TL;DR
It is time to get rid of those long XPath locators.
Our simple shop scenario had a flaw, as a page element locator, it used long Xpath. Let’s refactor using Watir enhanced locator methods. And there is a bonus. You will learn how to dynamically create page object element accessors. Very handy when you have a lot of elements that differ only in attribute values. Let’s examine this pull request.
features/step_definitions/cart.rb
Cart step definitions now use a new cart page object method for checking shirt item presence. The parameter is a shirt name that could be found on a page.
features/step_definitions/shirt.rb
Same with shirt page where we use a shirt page object for selecting a shirt using its name.
features/support/cart.rb
In the cart page object, we refactored paragraph HTML element locator and accessors. We now use class and text locators, where text value (shirt name) is a parameter. Watir locators could be combined in the case when elements share attribute values (in our case paragraph text). class value helps us to locate paragraph element on cart page. We changed the page object accessor from p to element, where the first parameter is the HTML element name. when_visible helper method waits for a default time of 5 seconds for paragraph element to become visible. Doing that, we do not need to use hardcoded sleep!
features/support/shirt.rb
In the shirt page object, we also use dynamic page element accessor elements, but Watir locator is a sibling method. We anchored to paragraph HTML element, and we search for Add to cart button using sibling method. Using Chrome elements inspector, it is clear that Add to cart button is the second sibling of paragraph element with shirt name. This anchoring is good heuristic because this locator would be broken only if the developer inserts a new HTML elements between the shirt name and Add to the cart button. But that would be immediately visible.
Run
cucumber features/shop.feature
and the scenario run result should be green.