1

I have created one element using page factory class.

@Findby(how=How.ID,using="userName")
private WebElement userName;

//Adding explicit wait here

WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.visibilityOf(userName)); // It is taking long time to wait even though the web element presents in the DOM

If I use, below statement the web driver responds immediately when webelement presents in DOM.

wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("userName")));

Same issue with other explicit wait methods also.

This is my observation. Any idea to resolve this would help me. Thanks!

GPT14
  • 769
  • 5
  • 12
  • I think you need to write `(ExpectedConditions.visibilityOf(By.id(userName)));` – Rajagopalan May 26 '18 at 05:27
  • Do you have an implicit wait on the driver also? – Grasshopper May 26 '18 at 05:28
  • 1
    @Rajagopalan There is no such method visibiltyOf(By by) only visibilityOf(WebElement element). Or are you referring to visibilityOfElementLocated(By locator)? https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html#visibilityOf-org.openqa.selenium.WebElement- – Grasshopper May 26 '18 at 05:32

3 Answers3

0

So confused about the stage you are trying to locate the element (before or after DOM loaded). ExpectedConditions.visibilityOf(element) should only be used when we are used that element is present in the DOM, and to wait for it's visibility.

You need to use ExpectedConditions.visibilityOfElementLocated - it ensures that:

  • Element is present in DOM

  • Element is visible

When you use ExpectedConditions.visibilityOf it doesn't check that element is present in DOM.

I have a question, did you initialize your POM? If not you need to initialize it as bellow:

// To initialize elements. 
MyPage myPage = PageFactory.initElements(driver, MyPage.class);

OR in the constructor:

public MyPage(WebDriver driver) { 
this.driver = driver; 
PageFactory.initElements(driver, this);
}
Nael Marwan
  • 940
  • 1
  • 9
  • 27
0

This explanation You provided is not clear, but I'will try to explain

// in top of class, enter code with annotations for init. webElementa
@FindBy(xpath = "//button[@id='...']")
private WebElement buttonBack;() 

... n elements ... 

// in constructor initElements() takes all elements and tries to find it and assign to variables above

public Page(WebDriver driver) {
    super(driver);
    PageFactory.initElements(driver, this);
    waitForScriptsToLoad(driver); // this will wait 30s to get 

}

and try to wait for Your page to load with this method (bellow):

public static void waitForScriptsToLoad(WebDriver driver) {
    new org.openqa.selenium.support.ui.WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
            ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}

This method waits unitl complete DOM is ready to continue working. If You like please check this link: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

Explicit wait You put in places inside methods, or in constructor if You're certain that wait will be always need.

And more info about wait types here: 1. Types of Explicit Wait in Selenium webdriver (Java)? 2. Replace implicit wait with explicit wait (selenium webdriver & java)

Kovacic
  • 1,427
  • 4
  • 21
0

The solution to eleminate the delay will be to use the PageFactory as intended and have the constructor for your class, where you would like to initialize the Explicit Wait as well as follows :

public class My_Page_Class {

    WebDriver driver;
    WebDriverWait wait; 

    //class constructor
    public Your_Page_Class(WebDriver driver)
    {
        this.driver = driver; 
        wait = new WebDriverWait(driver,10);
    }

    @Findby(how=How.ID,using="userName")
    private WebElement userName;

    // page class functions
    public void foo()
    {
        wait.until(ExpectedConditions.visibilityOf(userName));
        //other code works
    } 
}

Now from your @Test annotated class you can initialize the class as follows:

@Test (priority=0)
public void checkValidUser()
{
    //Created Page Object using Page Factory
    My_Page_Class my_page_class = PageFactory.initElements(driver, My_Page_Class.class);

    //Call the method
    my_page_class.foo();

}

You will find a related discussion in Using PageObjects, Page Factory and WebDriverWait in Selenium WebDriver using Java

DebanjanB
  • 118,661
  • 30
  • 168
  • 217