Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for invisibility of an element through PageFactory using Selenium and Java

Is there a way to wait for an element not present in Selenium using PageFactory annotations?

When using:

@FindBy(css= '#loading-content')
WebElement pleaseWait;

to locate the element, and then:

wait.until(ExpectedConditions.invisibilityOfElementLocated(pleaseWait));

I would get:

org.opeqa.selenium.WebElement cannot be converted to org.openqa.selenium.By

I am able to do what I need by using:

wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector('loading-content')));

However, I would like to be able to use the PageFactory annotations in order to keep the framework consistent. Is there a way to do this?

like image 873
Mate Mrše Avatar asked Feb 13 '19 11:02

Mate Mrše


People also ask

How do you wait for invisibility of element in Selenium?

Wait for invisibility of element with Text Below is the syntax which is used for checking that an element with text is either invisible or not present on the DOM. WebDriverWait wait = new WebDriverWait(driver, waitTime); wait. until(ExpectedConditions. invisibilityOfElementWithText(by, strText));

How do you use explicit wait on PageFactory?

I would suggest that you use the PageFactory as intended and have a constructor for your class where you would like to use the explicit wait. Having a separation between the script and the page objects makes it much easier to work with in the future. Then in your test case use code to perform your test.

What are the best practices for Page factory in selenium?

One of the Selenium best practices with Page Factory is to create all the web element variables at the beginning of the class and initialize those variables when the page is loaded. The initialization of web elements can be done through the use of initElements methods of the PageFactory class.

How do I check if an element is invisible using pagefactory?

When using PageFactory in PageObjectModel if you expect the element to be invisible, you can use the Explicit Wait support with a normal locator factory and use either of the following solutions: invisibilityOfElementLocated () is the implementation for an expectation for checking that an element is either invisible or not present on the DOM.

What is @findby annotation in selenium Page factory?

When using Page Factory in Selenium, automation testers can use the @FindBy annotation for locating the web elements. These web elements are defined in web page classes (or Page Objects). The major benefit of the @FindBy annotation is that it lets you initialize page elements without using the FindElement (or FindElements) in Selenium.

Why does selenium wait for an element to be visible?

That may happen for several reasons, but a common one is simply trying to interact with an element before it exists or before it’s visible and ready to be used. In this post, you’ve seen how to code around that problem, ensuring that Selenium waits until the element is visible.


2 Answers

When using PageFactory in PageObjectModel if you expect the element to be invisible, you can use the Explicit Wait support with a normal locator factory and use either of the following solutions:


invisibilityOfElementLocated()

invisibilityOfElementLocated() is the implementation for an expectation for checking that an element is either invisible or not present on the DOM. It is defined as follows:

public static ExpectedCondition<java.lang.Boolean> invisibilityOfElementLocated(By locator)
An expectation for checking that an element is either invisible or not present on the DOM.

Parameters:
    locator - used to find the element

Returns:
    true if the element is not displayed or the element doesn't exist or stale element
  • Code Block:

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.FindBy;
    import org.openqa.selenium.support.PageFactory;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    public class fooPage {
    
        WebDriver driver;
        public fooPage(WebDriver driver)
        {
            PageFactory.initElements(driver, this);
        }
    
        //you don't need this
        //@FindBy(css= '#loading-content')
        //WebElement pleaseWait;
    
        public void foo()
        {
            Boolean bool = new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector('#loading-content')));
            //other lines of code
        }
    }
    

As an alternative you can also use the invisibilityOf() method as follows:

invisibilityOf()

invisibilityOf() is the implementation for an expectation for checking the element to be invisible. It is defined as follows:

public static ExpectedCondition<java.lang.Boolean> invisibilityOf(WebElement element)
An expectation for checking the element to be invisible

Parameters:
    element - used to check its invisibility

Returns:
    Boolean true when elements is not visible anymore
  • Code Block:

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.FindBy;
    import org.openqa.selenium.support.PageFactory;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    public class fooPage {
    
        WebDriver driver;
        public fooPage(WebDriver driver)
        {
            PageFactory.initElements(driver, this);
        }
    
    
        @FindBy(css= '#loading-content')
        WebElement pleaseWait;
    
        public void foo()
        {
            Boolean bool = new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOf(fooPage.getWebElement()));
            //other lines of code
        }
    
        public WebElement getWebElement()
        {
            return pleaseWait;
        }
    }
    

You can find a detailed discussion in How to use explicit waits with PageFactory fields and the PageObject pattern

like image 68
undetected Selenium Avatar answered Sep 29 '22 20:09

undetected Selenium


invisibilityOfElementLocated is expecting a locator but you are sending a web-element and that is why it is throwing an error. You can perform the operation by checking the webelement list by using:

wait.until(ExpectedConditions.invisibilityOfAllElements(Arrays.asList(pleaseWait)));

Updated Answer:
If you want to check that the element is not present on the page then you can check its list size is equal to 0 or not, as its list size will be 0 when its not displayed on the UI.

You can get the list of the element by using:

@FindBy(css='#loading-content')
List<WebElement> pleaseWait;

And you can check the list size equals to 0 by using:

if(pleaseWait.size()==0){
     System.out.println("Element is not visible on the page");
     // Add the further code here
}

And this would not give NoSuchElement exception as well.

like image 33
Sameer Arora Avatar answered Sep 29 '22 20:09

Sameer Arora