dsidler
dsidler

Reputation: 499

Using WebElements from PageFactory POMs in my test class

Basically, I would like to make an assertion (from my test class) that a WebElement contains text(). Since all of my WebElements are defined in my page.class, I think I have to make them public to do this.

I am running into a few problems with the webdriver and elements, and I think it may be because multiple test classes are accessing WebElements from the page class simultaneously. My question is: Is there a reason the WebElements must be private?

Code example:

All PageFactory tutorials I have seen say to make your WebElements private, like

    @FindBy(xpath = "//*[@id='searchStringMain']")
    private WebElement searchField;

But to assert that an element contains text (from another class), I have to define them like this:

    @FindBy(xpath = "(//*[contains (text(),'Hrs')])[2]")
    public static WebElement yourLoggedTime;

Upvotes: 0

Views: 1771

Answers (2)

user861594
user861594

Reputation: 5908

You can keep your class filed public but as a standard practice it is advised to have getter method for class filed rather than direct filed access.
Problem is static keyword you are using with public. When you are using @FindBy annotation with filed (webelement), it initialize at the time when class initialize (or depending on your implementation where initElements() called). So it is fine to have webelement public but not static. For instance:

In your page class:

@FindBy(xpath = "(//*[contains (text(),'Hrs')])[2]")
public WebElement yourLoggedTime;

In test:

String yourLoggedTime = pageObj.yourLoggedTime.getText(); //pageObj is object of your page class

Upvotes: 0

MikeJRamsey56
MikeJRamsey56

Reputation: 2819

Consider this example:

package org.openqa.selenium.example;

import org.openqa.selenium.By;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.WebElement;

public class GoogleSearchPage {
    // The element is now looked up using the name attribute
    @FindBy(how = How.NAME, using = "q")
    private WebElement searchBox;


    public void searchFor(String text) {
        // We continue using the element just as before
        searchBox.sendKeys(text);
        searchBox.submit();
    }
}

searchbox is private but the method searchFor is public. The test would use searchFor but never searchBox.

I usually put the page factory initElements call in the last line of the page constructor. This makes all the public functions available to the tests. So

package org.openqa.selenium.example;

import org.openqa.selenium.By;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.WebElement;

public class GoogleSearchPage {
    public WebDriver driver;
    // The element is now looked up using the name attribute
    @FindBy(how = How.NAME, using = "q")
    private WebElement searchBox;

    public GoogleSearchPage(WebDriver driver) {
        this.driver = driver
        PageFactory.initElements(driver, this);
    }


    public void searchFor(String text) {
        // We continue using the element just as before
        searchBox.sendKeys(text);
        searchBox.submit();
    }
}

In your test you can do something like:

new GoogleSearchPage(webDriver).searchFor("Foo");

Upvotes: 1

Related Questions