While doing acceptance tests, we often run into scenarios where we need to click on elements which can’t be found or clicked on using simple expressions like – I follow “Login”. Let me give an example, on a page there is an anchor tag with specific id. The anchor tag has no text but an image inside it. In such cases, we are left no other choices than querying the dom. XPath could be a decent way to find the anchor tag here. Let’s assume that the anchor tag has the id – 14. So the xpath query should be – “//a[@id=’14’]”.
PS: We can use Firebug to test out XPath queries. There is a built in function – $x – on a firebug console, just pass xpath queries as string to this function and it will throw matching elements.
Here’s a step definition I wrote inside my FeaturedContext class. This method takes in a xpath query and clicks on the element:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/** * Click on the element with the provided xpath query * * @When /^I click on the element with xpath "([^"]*)"$/ */ public function iClickOnTheElementWithXPath($xpath) { $session = $this->getSession(); // get the mink session $element = $session->getPage()->find( 'xpath', $session->getSelectorsHandler()->selectorToXpath('xpath', $xpath) ); // runs the actual query and returns the element // errors must not pass silently if (null === $element) { throw new \InvalidArgumentException(sprintf('Could not evaluate XPath: "%s"', $xpath)); } // ok, let's click on it $element->click(); } |
And how do we use it inside a “feature” file?
1 |
Given I click on the element with xpath "//a[@id='14']" |
UPDATE:
Using a jQuery like CSS Selector is pretty easy. Looks like Mink also allows CSS Selectors by default. Here’s the same method with CSS Selector:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * Click on the element with the provided CSS Selector * * @When /^I click on the element with css selector "([^"]*)"$/ */ public function iClickOnTheElementWithCSSSelector($cssSelector) { $session = $this->getSession(); $element = $session->getPage()->find( 'xpath', $session->getSelectorsHandler()->selectorToXpath('css', $cssSelector) // just changed xpath to css ); if (null === $element) { throw new \InvalidArgumentException(sprintf('Could not evaluate CSS Selector: "%s"', $cssSelector)); } $element->click(); } |
And we use it in the feature file like:
1 |
Given I click on the element with css selector "a#14" |
The test should fail in case a matching element was not found. Let me know if you run into any issues or find even better or elegant ways to do this.
9 replies on “Behat and Mink: Finding and clicking with XPATH and jQuery like CSS Selector”
Just
find() has first argument by some reason:
$session->find('xpath', $xpathSelector);
$session->find('css', $cssSelector);
To get the title of your html page:
$title = $this->getSession()->getPage()->find('css', 'title')->getText();
FLIP101
It is actually getHtml() not getText(), I am getting empty string for getText() when trying to access the <title> tag in Mink
getText() works fine with Goutte driver but not with any other drivers. Correct if I’m wrong
Yes! Thankyou! Big help for me.
Thank you very much !!!!
Regards from Venezuela
Awesome… Thanks!
Nice example. Its solved my problem. Thanks!
invalid selector: The result of the xpath expression “//html//meta[@name =”description”]/@content” is: [object Attr]. It should be an element.