Reputation: 383
I have radio buttons that when either radio button is selected, it gets a checked
attribute.
This is how the HTML looks:
My implementation of getting the descendant that has a checked
attribute:
public TestObject getCheckedTestObjectFromParent(String parentID){
WebDriver driver = DriverFactory.getWebDriver()
WebElement parentWebElement = driver.findElement(By.id(parentID))
List<WebElement> children = parentWebElement.findElements(By.xpath(".//*"))
println(children.size())
for(int i = 0; i < children.size(); i++){
TestObject childTestObject = getTestObjectFromWebElement(children[i])
if(WebUI.verifyElementHasAttribute(childTestObject, 'checked', 10, FailureHandling.OPTIONAL)){
return childTestObject
}
}
}
This is the helper method that I use for converting a WebElement
to a TestObject
:
public TestObject getTestObjectFromWebElement(WebElement element) {
TestObject object = new TestObject()
object.addProperty("xpath", ConditionType.CONTAINS, getXPathFromElement(element))
return object
}
Helper for getting xpath
from WebElement
:
protected String getXPathFromElement(WebElement element) {
String elementDescription = element.toString();
return elementDescription.substring(elementDescription.lastIndexOf("-> xpath: ") + 10, elementDescription.lastIndexOf("]"));
}
Am I missing something here or is there something wrong with the WebElement
-> TestObject
conversion? Also is this possible using only TestObject or only WebElement? If I could get child TestObjects
containing certain attributes from a parent TestObject
then I wouldn't need to make a mess using WebElements
.
Edit
Another image of the HTML, this time with the first radio button checked. As you can see the second radio button no longer has the 'checked' attribute.
Upvotes: 0
Views: 929
Reputation: 383
I was able to fix this by changing (".//*")
to (".//*[@checked='checked']")
parentWebElement.findElement(By.xpath(".//*[@checked='checked']")
will find the element that has the attribute checked = 'checked'
Notice that a list is no longer needed as there can only be 1 checked radio button at a time.
Implementation
public TestObject getCheckedTestObjectFromParent(String parentID){
WebDriver driver = DriverFactory.getWebDriver()
WebElement parentWebElement = driver.findElement(By.id(parentID))
//there is only 1 checked child at a time, so there is no need for a list
WebElement checkedChild = parentWebElement.findElement(By.xpath(".//*[@checked='checked']"))
//convert the WebElement to a TestObject and return
return getTestObjectFromWebElement(checkedChild)
}
Upvotes: 1
Reputation: 193308
To retrieve the WebElement that is currently checked
you can use either of the following Locator Strategies:
cssSelector:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.a-toggle.a-toggle--anycase#config-src-laserunits div[id^='config-src-laserunits-']>input.a-toggle__radio[checked]")));
xpath:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='a-toggle a-toggle--anycase' and @id='config-src-laserunits']//div[starts-with(@id, 'config-src-laserunits-')]/input[@class='a-toggle__radio' and @checked]")));
Upvotes: 1
Reputation: 33384
Try this Xpath
"//input[@id='config-src-laserunits-wavnmradio' and @checked='checked']"
Example:
List<WebElement> children = driver.findElements(By.xpath("//input[@id='config-src-laserunits-wavnmradio' and @checked='checked']"))
It should return size 1
EDIT
List<WebElement> children = driver.findElements(By.xpath("//input[@id='config-src-laserunits-wavnmradio']"));
for (int i=0;i<children.size();i++)
{
if(children.get(i).getAttribute("checked")!=null)
{
System.out.println("radio button is checked");
}
}
Upvotes: 0