8

I'm rewriting some Selenium tests according to the page object design pattern taking advantage of Seleniums' annotations. My problem is that I have some html select elements whose option elements are loaded dynamically. These are not available at the same time the selects are.

The original code looks like:

public void fillinForm() {
 // Fill-in some fields ...
 // Select dynamic loaded option
 String optionXpath = "//*[@id='field']/option[text()='Software engineering']";
 waitForElement(driver, By.xpath(optionXpath), SHORT_TIMEOUT_S);
 driver.findElement(By.xpath(optionXpath)).click();
 // Fill-in more fields, etc ...
}
// Selenium wait
public static void waitForElement(WebDriver driver, By by, int timeout) {
 // implementation
}

The new code turns into something like:

public void setUp() {
 page = PageFactory.initElements(driver, Page.class);
}
public void fillinForm() {
 page.setField("Software engineering");
}
public class Page {
 private webElement field;
 public Page setField(String byText) {
 field.click();
 String optionXpath = String.format("./option[text()='%s']", byText);
 field.findElement(By.xpath(optionXpath)).click();
 return this;
 }
}

If I want to implement the wait in the new code, I have to use an xpath for the option that includes the xpath for the select, thus losing the advantage of using annotations to simplify the code:

public void fillinForm() {
 page.setField("Software engineering");
}
public class Page {
 private webElement field;
 public Page setField(String byText) {
 field.click();
 // Note that I'm now explicitly writing "field", exactly what I wanted
 // to save using annotations and the PageFactory
 String optionXpath = String.format("//select[@id='%s']/option[text()='%s']",
 "field", byText);
 field.findElement(By.xpath(optionXpath)).click();
 return this;
 }
}

Is there any annotation I can use to wait until the options are loaded, or am I using this wrong?

asked Jul 26, 2011 at 14:48

1 Answer 1

4

After spending some more time with WebDriverWait, I came out with something nicer:

Client code:

/** Page Object. */
public class Page {
 private WebElement mySelect;
 public Page setMySelect(String optionText) {
 String optXpath = String.format("./option[text()='%s']", optionText);
 mySelect.click();
 waitForOption(driver,mySelect, By.xpath(optXpath), 10)
 .click();
 }
}

Utility library:

public class Util {
 /**
 * Waits until the option targeted by <tt>byOption</tt> is available.
 *
 * @param select parent element of the option to wait for
 * @param byOption selector (relative to the <tt>select</tt>). It will be
 * searched calling <tt>select.findElement(byOption)</tt>
 * @return option element
 */
 public static WebElement waitForOption(
 WebDriver driver, WebElement select, By byOption, int seconds) {
 Wait<WebDriver> wait = new WebDriverWait(driver, seconds);
 return wait.until(new OptionAvailable(select, byOption));
 }
 public static class OptionAvailable
 implements ExpectedCondition<WebElement> {
 private WebElement select;
 private By byOption;
 public OptionAvailable(WebElement select, By byOption) {
 this.select = select;
 this.byOption = byOption;
 }
 @Override
 public WebElement apply(WebDriver input) {
 return select.findElement(byOption);
 }
 }
}

Note that with this approach (a By for the option), we can support the option as text or as value.

answered Jul 27, 2011 at 17:02
2
  • I'm testing it now, and it seems that it doesn't work :-( The two consecutive clicks (in select and in option) are failing somehow, and unfortunately it is not easy to debug, as the debugger interferes with the normal flow. Commented Jul 27, 2011 at 17:47
  • Indeed, it works removing the mySelect.click(). I'm a bit confused now, as I was "double"-clicking due to Selenium's issue 2112. I have to check if without this "double" click it still works in my SUSE Linux Enterprise Server 11 box with Firefox 3.6.18 Commented Jul 27, 2011 at 18:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.