Using Selenium WebDriver to select JSF/PrimeFaces selectOneMenu options
I'm using JBehave with Selenium WebDriver to test my PrimeFaces (JSF2) application. Selecting an option from a SelectOne option list isn't standard though because of the HTML markup generated by the JSF component.
The facelets code to place the selectOneMenu uses the ID 'state':
This generates HTML div blocks with id's prefixed with this components id:
To select an option, I use a method which manipulates the appropriate divs - this can be used as illustrated below:
To reuse this type of utility method, I put it in a base Page Object class:
The facelets code to place the selectOneMenu uses the ID 'state':
This generates HTML div blocks with id's prefixed with this components id:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="myForm:state" class="ui-selectonemenu ui-widget ui-state-default ui-corner-all ui-helper-clearfix" style="width: 147px;"> | |
<div class="ui-helper-hidden"> | |
<select id="myForm:state_input" name="myForm:state_input"> | |
<option value="">- Select One -</option> | |
<option value="Enabled">Enabled</option> | |
<option value="Disabled">Disabled</option> | |
</select> | |
</div> | |
<div class="ui-helper-hidden-accessible"> | |
<input id="myForm:state_focus" name="myForm:state_focus" type="text"> | |
</div> | |
<label id="myForm:state_label" class="ui-selectonemenu-label ui-inputfield ui-corner-all" style="width: 137px;">- Select One -</label> | |
<div class="ui-selectonemenu-trigger ui-state-default ui-corner-right"> | |
<span class="ui-icon ui-icon-triangle-1-s"></span> | |
</div> | |
</div> |
To select an option, I use a method which manipulates the appropriate divs - this can be used as illustrated below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
The facelets code uses the id "state" | |
<p:selectOneMenu id="state" value="#{myBean.state}"> | |
... | |
</p:selectOneMenu> | |
*/ | |
// sample invocation to select element | |
selectOne("myForm:state", "Disabled"); | |
// select given option | |
public void selectOne(String idPrefix, String value) { | |
if (StringUtils.isNotBlank(value)) { | |
getDriver().findElement(By.id(idPrefix + "_label")).click(); | |
getDriver().findElement(By.xpath("//div[@id='" + idPrefix + "_panel']/div/ul/li[text()='" + value + "']")).click(); | |
} | |
} |
To reuse this type of utility method, I put it in a base Page Object class:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import net.thucydides.core.pages.PageObject; | |
import org.apache.commons.lang3.StringUtils; | |
import org.openqa.selenium.By; | |
import org.openqa.selenium.WebDriver; | |
public abstract class AbstractPage extends PageObject { | |
public AbstractPage(WebDriver driver) { | |
super(driver); | |
} | |
public void waitForAjax() { | |
waitForRenderedElements(By.className("ajaxLoadingImg")); | |
waitForRenderedElementsToDisappear(By.className("ajaxLoadingImg")); | |
} | |
public void clickLinkWithText(String linkText) { | |
getDriver().findElement(By.linkText(linkText)).click(); | |
} | |
public void selectOne(String idPrefix, String value) { | |
if (StringUtils.isNotBlank(value)) { | |
getDriver().findElement(By.id(idPrefix + "_label")).click(); | |
getDriver().findElement(By.xpath("//div[@id='" + idPrefix + "_panel']/div/ul/li[text()='" + value + "']")).click(); | |
} | |
} | |
} |