PageFactory initialize elements with WebElement as SearchContext

541 views
Skip to first unread message

John Catlow

unread,
Dec 3, 2015, 10:02:02 PM12/3/15
to Selenium Users
Hi everyone,

I have a problem with initializing PageObject based on passed WebElement. The PageObject in question is a representation of a common element found on a website. I've tried numerous solutions but search context is always full web page not limited to the passed element.

The page contains several divs that share the same class "someClass" and have the the same child elements. The test always gets the element of the first div, even when the second div from the list is passed.

I can't show the real code and the page because it's company internal but here's the code that depicts the problem.

public class PageWithDivs extends PageObject {

 
@FindBys(@FindBy(xpath = "//div[@class='someClass'"))
 
private List<WebElement> divs;

 
public PageWithDivs(final WebDriver driver) {
     
super(browser);
 
}

 
public DivElement getSingleDiv(final int index) {
     
final WebElement element = divs.get(index);
     
return new DivElement(driver, element);
 
}
}

public class DivElement {
 
 
@FindBy(xpath = "//div[@class='iAmInsideDiv'")
 
private WebElement textBox;

 
public DivElement(final WebDriver driver, final WebElement element) {
     
PageFactory.initElements(new DefaultElementLocatorFactory(element), this);
 
}
 
 
public void enterText(final String text) {
      textBox
.sendKeys(text);
 
}
}

public class SampleTest extends Test {

 
private PageWithDivs pageWithDivs = openPage();
 
private DivElement divElement;
 
@Test
 
public void testSample() {
   
    divElement
= pageWithDivs.getSingleDiv(1);
    divElement
.enterText("test"); //Text is entered in the wrong div element
 
}
}

PeterJeffreyGale

unread,
Dec 4, 2015, 3:30:35 AM12/4/15
to Selenium Users
I would suspect that there's something in the code for page objects that means that it always returning the first element,

And, to me, it does look like rather convoluted way just to get the nth element in a list ... I presume it's difficult to debug if you can't find what's going wrong?

I've never found that predefining page elements works well when they aren't simple and statically defined.

Wouldn't it be easier just to just write a single method in your page class that takes an index and runs find elements by xpath to find the instance that you want?


PS. Isn't there a missing closing ']' in each of your xpaths?, e.g: 

  @FindBys(@FindBy(xpath = "//div[@class='someClass'"))

... could that be causing a problem? Or is it just a typo in the mocked up sample code?

John Catlow

unread,
Dec 4, 2015, 12:06:52 PM12/4/15
to Selenium Users
Thanks for your reply Peter. The missing ] is indeed a typo in the mocked code. I debugged the code earlier today and found that SearchContext is updated when initializing PageObject for the single element so it's still not resolved. For the time being I did exactly what you proposed but was hoping to find out what is happening that it does not work in this case (I passed the WebElement as a SearchContext before and it worked fine).
Reply all
Reply to author
Forward
0 new messages