Just a quickie: Sitting on the periphery of the Selenium project is an “add on” for Java called Fluent Selenium.

It adds a fluent API (link to Martin on such things) to Selenium 2.0’s WebDriver. As we push into a increasingly JavaScript reality for web applications, and less and less Sever Side templating, there are often timing intricacies when testing applications, and FluentSelenium attempts to give such problems elegant solutions.

Examples for Fluent Selenium

See https://github.com/paul-hammant/fluent-selenium-examples.

I have two examples described below, but here is a 50 second video of the two running in series:

Etsy.com

The first for Etsy.com is for an app that mostly uses Server-Side templating.

See BuyAHatTest.java and the “page objects” that make for more reusable code.

Hipmunk.com

The second is for Hipmunk’s very-Javascripty flight search + booking app. BookAFlightTest.java and associated page objects show how I did it. There is more ‘wait for’ going on in this example because of the dynamic nature of the DOM, and interstitial effects. Indeed in one case, whole nodes become invalidated in the DOM, and the dreaded StaleElementReferenceException is handled with a retry strategy (which sadly makes the code a little ugly).

The Hipmunk solution is a little flawed, as the actual booking opens another tab in the browser, and I’m not closing that on exit. I could do some more work towards fixing that (as per this StackOverflow article), but I’m not trying to actually finish this test, and am only using Hipmunk because it is an impressive Web 2.0 application.

In both of these example I’m using ‘double-brace initialization’ - C2Wiki on that. It allows for a faked builder style for Java, albeit forcing us to instantiate something to leverage it. Each of (HipMunk) SearchResults, Home, BookingOverlay contain reusable methods that don’t in themselves do assertions, but do encode the fluent interfaces for navigating the DOM, while taking into account timing flakiness.

Tricks for Web 2.0 applications.

In an Web 2.0 application, the DOM mutates as events happen. That is not new news. Nor is that the mutation can sometimes happen slowly. How to push through that without intimate knowledge of the implementation (I have not worked at Hipmunk) can be hard.

Here is the line in the Hipmunk example that waits for an overlay to appear that will allow interaction to complete a booking. It is not a new page, it is a JQuery overlay on top of the search results. There could be a bigger booking pages elsewhere, but this is the one I found during experimentation. The code:

within(secs(8)).div(className("booking-info-container"));

How did I discover that secret?

That div, with its ‘booking-info-container’ class is one of thousands in the page. How did I find it? …

OK, In Regular Firefox (not under WebDriver control), with the MAFF plugin installed, I saved the DOM back to HTML for the returns flights list before I click “select leg”, and after I click “select leg”. That gave me two MAFF files in my downloads folder: hipmunk1.maff and hipmunk2.maff. I unzipped them both (they are just zips). In WebStorm I reformatted the index.html in each to be tidy/pretty - Ctrl+Alt+L - then used ‘compare to clipboard’ (some other guy’s video on that). Any visual diff tool could be used, but we just used WebStory for the reformat.

Comparing the two allows me to see all the DOM differences for the before and after states. After a couple of minutes I was able to determine that the div I mentioned (with a class name of ‘booking-info-container’) was present in the ‘after click’ transition, and it seemed reasonable to wait for it to appear before trying to click ‘book’ and other interactions.

Alternatives to Fluent Selenium

Fluent Lenium Geb (uses Groovy)



Published

May 19th, 2013
Reads:

Tags

Categories