Reputation: 60709
I'm doing some web app testing using Selenium IDE, and would like to like to introduce some randomness to spread out our tests. I'm currently using Selenium's storeAttributeValue
, where you give it a XPath expression, and it stores the first element that matches it (sorta). However I don't want to store the first match, I'd like for it to randomly select a child node.
e.g.
//table[@id='mytable']//tr
selects all the tr childs of this table.
//table[@id='mytable']//tr[0]
selects the first tr (assuming now nested tables)
//table[@id='mytable']//tr[3]
selects the third tr, etc.
Is there some way (entirely in xpath) I can say "Give me a random tr", i.e. //table[@id='mytable']//tr[SOMETHINGHERE]
which everytime I 'evalulate'/'run' it will 'return' one tr node that is in the set of //table[@id='mytable']//tr
.
Upvotes: 7
Views: 9716
Reputation:
If you are using bash commandline, you can get a pseudorandom number from the $RANDOM variable like such:
/table[@id='mytable']/tbody/tr[floor('"${RANDOM}"' mod count(../tr)+1)]
This was the only way I could get a random number in while using xmllint to try and get a random child node. Here is the command using xmllint and some FILENAME.xml:
xmllint --format --recover --xpath '/table[@id='mytable']/tbody/tr[floor('"${RANDOM}"' mod count(../tr)+1)]' FILENAME.xml
Upvotes: 3
Reputation: 243479
Construct dynamically the XPath expression and then evaluate it:
/table[@id='mytable']/tbody/tr[position() = {yourRandom}]
where
{yourRandom}
must be substituted in the "skeleton" of the XPath expression with a random number obtained in the PL hosting XPath.
For example in C# one would use the string.Format()
method to construct the XPath expression.
If you are using XSLT, the code that invokes the transformation may provide as an external parameter a sequence of random numbers encoded in an XML fragment. Then the XSLT code would use each consecutive random number for each XPath expression.
Upvotes: 1
Reputation:
If the XPath expression isn't going to change from one invocation to another, and the input source is also going to be the same, then you will need to provide the variance by parameterization, otherwise the same function with the same input will always output the same result (that's why I've make the comment on declarative paradigm).
Something like:
/table[@id='mytable']/tbody/tr[$pseudoRandom mod count(../tr) + 1]
If there is going to be one evaluation per input source, the most simple pseudo randomness in XPath would be
/table[@id='mytable']/tbody/tr[count(//node()|//@*) mod count(../tr) + 1]
In other words, making some pseudo randomness calculation with some property of the whole input source as seed.
Upvotes: 6