Reputation: 2662
I have a XPath that will select a specific radio button item of my HTML. I would like to enhance my locator to be more dynamic by using a stored variable to represent the text for which my XPath is using to lock on.
This is my current setup
Command: Click
Target:
//*[contains(@for,'Page149.Question48.TypeChoiceOneAnswerRadioButton.holder_ctl02')
and text()="Below 70 – May be too low"]
I would like to replace the literal text "Below 70 – May be too low" with a variable. My proposed Target is failing to evaluate. I hope I just have the syntax incorrect.
Can I do this? Can I use stored variables with XPath locators?
Proposed Target:
//*[contains(@for,'Page149.Question48.TypeChoiceOneAnswerRadioButton.holder_ctl02')
and text()=${radioText}]
EDIT: Adding code. I made a simple example of my HTML radio button list and isolated my Selenium commands. I am using the Selenium IDE in the Firefox. My commands example has comments.
Sample HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Page</title>
</head>
<body>
<table border="0" class="srvy_radiobuttonlist" id="ctl00_cphSurveyControls_surveyCategoryPage_Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02">
<tbody>
<tr>
<td>
<input type="radio" checked="checked" value="Page51.Question5.Answer580" name="ctl00$cphSurveyControls$surveyCategoryPage$Page51.Question5.TypeChoiceOneAnswerRadioButton.holder$ctl02"
id="ctl00_cphSurveyControls_surveyCategoryPage_Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02_0"><label
for="ctl00_cphSurveyControls_surveyCategoryPage_Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02_0">Male</label>
</td>
<td>
<input type="radio" value="Page51.Question5.Answer581" name="ctl00$cphSurveyControls$surveyCategoryPage$Page51.Question5.TypeChoiceOneAnswerRadioButton.holder$ctl02"
id="ctl00_cphSurveyControls_surveyCategoryPage_Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02_1"><label
for="ctl00_cphSurveyControls_surveyCategoryPage_Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02_1">Female</label>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Mocked up Selenium IDE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://localhost" />
<title>LocatorTest</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">LocatorTest</td></tr>
</thead><tbody>
<!--Select Male-->
<tr>
<td>click</td>
<td>//*[contains(@id,'Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02_0')]</td>
<td></td>
</tr>
<tr>
<td>store</td>
<td>Female</td>
<td>Gender</td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>${Gender}</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>javascript{ storedVars['Gender']}</td>
<td></td>
</tr>
<!--FYI, locates first item in radio collection-->
<tr>
<td>click</td>
<td>//*[contains(@for,'Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02')]</td>
<td></td>
</tr>
<!--Works to select female-->
<tr>
<td>click</td>
<td>//*[contains(@for,'Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02') and text()='Female']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//*[contains(@for,'Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02') and contains(text(),'Female')]</td>
<td></td>
</tr>
<!---- not found -->
<tr>
<td>click</td>
<td>//*[contains(@for,'Page51.Question5.TypeChoiceOneAnswerRadioButton.holder_ctl02') and contains(text(),${Gender})]</td>
<td></td>
</tr>
<!--Works to select female-->
<tr>
<td>click</td>
<td>//*[contains(text(),'Female')]</td>
<td></td>
</tr>
<!---- not found -->
<tr>
<td>click</td>
<td>//*[contains(text(),${Gender})]</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
Upvotes: 4
Views: 9583
Reputation: 5889
You need quotation marks around the variable.
//*[contains(text(),'${Gender}')]
And yes, I have successfully used an XPath locator with stored variables, though it was not with 'click' but with 'waitForXpathCount'. At first it didn't work and I had to resort to printf-debugging to get to the cause. The reason it didn't work is irrelevant here(I didn't set the target appropriately), but I think a list of relevant files will be of interest to those having trouble with Selenium IDE.
Location of the files on a Mac:
~/Library/Application Support/Firefox/Profiles/[your profile]/extensions/{a6fd85ed-e919-4a43-a5af-8da18bda539f}/chrome/content/selenium-core/scripts/
Important files:
Selenium.prototype.doClick
doClick
handler above calls BrowserBot.prototype.findElement
, for instance.selenium.preprocessParameter(command.target)
. selenium.preprocessParameter
can be found in selenium-api.js
.XPathEvaluator
How to print to the IDE log:
LOG.error("Useful debugging information");
You need to restart Firefox each time you make a change to Selenium IDE's internals (I couldn't find a way to reload it on the fly).
Additionally, you can test your XPath expression like $x("xpath/expr/with/stored/variables/replaced/accordingly")
on a normal Firefox JS console.
Upvotes: 4
Reputation: 9570
Yes, that should work just fine. The documentation shows a simple example:
type | textElement | Full name is: ${fullname}
The obvious question would be "Where did you get the value of radioText from?", followed closely by "Are you sure there is no other text in it?" (because you coded "text()='xxx'
", not "contains(text(), '...')
". Or perhaps you really did leave out the quotes in the code, not just in your example (i.e., "text()=xxx
", not "text()='xxx'
")?
Upvotes: 0
Reputation: 869
What is the HTML element you are selecting? Can you provide the HTML? Yes, this is possible. What binding are you using? ie. Python, Ruby, Java???
You can do something like this:
var = selenium.get_eval(locator)
Upvotes: 0