I’m So Dizzy, Spinners Are Spinnin’

6 Apr

I write a lot of Selenium automation for a very dynamic and Ajax-y application.

Lucky me!

Pages load with some areas populating more quickly than others as endpoints are accessed in the background and the page must wait for the data to load. While this is happening, the areas in progress display ‘spinners’, swirling animated icons to visually indicate to the end user that we’re working as hard as we can to get the data they’re looking for.  

This is a fine and very helpful thing, but a fair pain in the butt to encounter when doing browser automation.  While writing a method to wait for these things to come and go is pretty straightforward, there can be complications.  In our product, we have large spinners and small, each with different class names, which can lead to some fugly coding to cope with them all.

With the olde and oft-maligned XPATH locators, there is an easier way!

I’m not going to get into the logic of how best to implement a wait strategy for these things.  There are many ways, but most will rely on the basic idea of 

1. Wait for spinner(s) to appear (in case the spinner itself takes a while to load)
2. Wait for the spinner(s) to disappear

What I did was to write a single method to wait for any and all spinners of any size or naming convention on a given page to stop.  The kewl thing is, no matter how many varieties there are, with XPATH, we can handle them all with a single locator as follows:

public final static By by_roundSpinnerIcon = By.xpath(

"//*[@class='fa-circle-o-notch fa-2x fa-spin'] | "
+ "//*[@class='spinner_container'] | "
+ "//*[@class='fa-spin fa-spin-fast'] | "
+ "//*[@class='spinny'] | "
+ "//*[@class='fa fa-circle-o-notch fa-4x fa-spin'] |" // many kinds of spinners

A personal quirk of my automation visible here is a fondness for using By objects to store locators, be they CSS, XPATH, link text or whatever. This makes it much easer to create helper methods to deal with dynamic content, like dependableClick(By), waitForElementExists(By) and so on. There are other and probably better ways to do this, but this is my current approach.

In any case, what’s great about this sort of xpath locator, is the ability to use an OR operator ‘|’ to consolidate different xpath locator strings into 1 single entity. Now, without any programming logic whatsoever, I can wait for and interact with an element that matches any 1 of those xpath strings.

Just today I ran into some tests that were failing suddenly, and I noticed that they were no longer heeding the waitForSpinner() method like they used to, and were trying to interact with elements of a page that was not fully loaded. Once I spotted this, I did a bit of investigation and found a new class name had been added to one of the spinners, which I was quickly able to create an xpath string for: "//*[@class='loading_spinner spin']".

I then added this 1 string to the others on the by_roundSpinnerIcon locator, which resulted in fixing 4 broken tests in one fell swoop! Here’s the new xpath locator:

public final static By by_roundSpinnerIcon = By.xpath(
"//*[@class='fa-circle-o-notch fa-2x fa-spin'] | "
+ "//*[@class='spinner_container'] | "
+ "//*[@class='fa-spin fa-spin-fast'] | "
+ "//*[@class='spinny'] | "
+ "//*[@class='fa fa-circle-o-notch fa-4x fa-spin'] |"
+ "//*[@class='loading_spinner spin']"); // many kinds of spinners

Of note, troubleshooting a spinner icon is not always easy, as they tend to fly by quickly before you can inspect them. Here’s one low tech way to do this without having to get into javascript, break points and so on:

1. Open your application to the area with the spinner and dynamic content in the Chrome browser
2. Open the Development Console and click to ‘Customize and control DevTools’ on the right
3. Go down to the ‘More tools’ menu and choose ‘Network conditions’
4. Throttle the network down to something low enough for your application to load, and then when the spinner itself loads, throttle down even further.
5. With the spinner available, right-click-Inspect it, and hopefully you’ll have enough time to at least grab a screen shot you can look at more closely afterwards!

Like I said, ‘lo tech’! It worked for me though and can be handy in a pinch to catch a fleeting element that you want to inspect.

Some (More) Simple Selenium Helper Methods

28 Mar

Are there parts of Selenium automation that scare you?  No? Well there are parts that scare me, and one of them is Advanced User Actions.  It’s very powerful and useful, but I never feel comfortable implementing User Actions without lots of Googling first to make sure I’m doing it right.

So I cheat, and look it up once and then put that dreadful code into a helper method so I never (?) have to look it up again!  If I later find a better way to do it, I can just update the helper method itself, and then all that newfound brilliance will trickle down to the test cases that use that method. I call it (drum roll please) moveToElementAndClickCss():

public void moveToElementAndClickCss(String cssString) {
	new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(cssString)));
	new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector(cssString)));
	Actions builder = new Actions(driver);
	Action moveAndClick = builder.moveToElement(driver.findElement(By.cssSelector(cssString)))


We pass a css element path as the argument and let the method code take care of moving to that element and clicking it.

I of course have another one called moveToElementAndClickXpath(), which you should be able to infer from the css version.  These methods are very simple, but again help to speed up test case design and make the resulting tests more maintainable and easier to read.

Some Simple Selenium Helper Methods

28 Mar

I just wanted to pass along some Selenium/WebDriver helper methods that I used a great deal in a recent project. This first series are my ‘tryBy’ helpers, which simply return a boolean value depending on whether or not the specified element exists. It’s handy for when you want to do some quick content checks using XPATH or CSS, but don’t want to have everything grind to a halt if the element in question is not found. These methods use a simple try/catch loop to bypass the exception and simply return a FALSE if the element is not there.

Here’s the code for tryByXpath():

	 * This method lets you test for the existence of an element.
	 * @param xpath = xpath selector text
	 * @return TRUE if xpath element isDisplayed, false with no error if not
	public boolean tryByXpath(String xpath) {
		try {
			new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.xpath(xpath)));
			new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath)));
			return true;
		} catch (TimeoutException e) {
			report.report("Xpath element not found: " + xpath);
			return false;

And here’s the same idea for CSS, aptly named tryByCss():

	 * This method lets you test for the existence of an element.
	 * @param css = css selector text
	 * @return TRUE if css element isDisplayed, false with no error if not
	public boolean tryByCss(String css) {
		try {
			new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(css)));
			new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(css)));
			return true;
		} catch (TimeoutException e) {
			report.report("Xpath element not found: " + css);
			return false;

And lastly, tryByLinkText:

	 * This method lets you test for the existence of an element.
	 * @param text = link text selector text
	 * @return TRUE if link text element isDisplayed, false with no error if not
	public boolean tryByLinkText(String text) {
		try {
			return driver.findElement(By.linkText(text)).isDisplayed();
		} catch (NoSuchElementException e) {
			report.report("Xpath element not found: " + text);
			return false;

The pattern is simple and there’s nothing tricky going on here, but creating helpers like these can really help save you a lot of time when writing your tests, and also helps to make your test code much easier to read.

For a small test suite, you can put these helpers in the test class itself. In a larger suite with multiple test classes, put them in a parent or abstract class which will then make them available to all child classes in which you write your tests.

In use, typical scenarios will look a lot like this:

boolean closeButton = tryByXpath("//*[text()='close']");
if (!closeButton) { report.report("problem with closeButton"); }

In that example we’re just checking to see if the Close Button exists, using XPATH. If it’s not there, we report the problem and move on. If it’s there, we move on and can use the information at the end of the test by stringing all the booleans together:

return closeButton && assetIcon && (etc. etc.)

The method calling this test method could then fail the test case if any of the content is missing, or pass it if all the content is there. You could also use it directly as a part of a JUnit assertion or any other way you like.

Equality NOW!

6 Feb

Equality NOW!

When is one item definitely NOT equal to another, even though they are both exactly the same?

When you’re programming in JAVA of course!

I’ve run into this many times, but for some reason today I stared at and wrestled with this problem for an hour straight before the “Oh YEAH!” clicked in, so I’m writing this post to help drive the point home for myself.

And you too, hopefully!

It seemed so simple:

return (elementText == "An email has been sent!");

If they’re equal, return TRUE, if not, FALSE. No biggie. But this is all I saw on every run:

junit.framework.AssertionFailedError: Fail report was submitted

Eh? Whazzat? The ensuing stack trace didn’t even mention the class the code was actually running from, so I looked in all the dustiest, darkest corners of my code (and the surrounding project) trying to find what strange, esoteric programming conundrum or race condition was causing this error.

It was staring me in the face the whole time, and I literally had to do that…STARE…at it for while before it hit me! This is probably the most common Java programming error of all time, and I’m ashamed to say it slapped me a good one this morning. Here’s what that code should look like:

return (elementText.contentEquals(
            "An email has been sent!"));

Nothing strange, nothing esoteric, nothing I haven’t encountered before. We use “==” for numbers and “.contentEquals()” for text. Easy! Grrrrr.

My only excuse is that with the intensity of this current project and deadlines looming, I immediately assumed that the problem was something dreadful I hadn’t encountered before. I was in the habit of seeing the offending method in the stack trace and this time there was nothing and, well, I PANICKED!

There it is, my confession. Kids don’t try this at home and end up a clown like me. I am now going to the (white?) board to write, “Not all equivalencies are ==” 100 times.

My Simple Java Logger

16 May

Captain's log...

While working on a recent project using parameterized tests against 1000+ lines of test data, it quickly became clear that some sort of logging was in order to get all the errors in one place in one file. I knew there were solutions such as log4j readily available, but I felt that the setup for that might be a bit too complex and would slow down an effort that was otherwise going quite smoothly.

So I searched the web to get an idea of the best approach for simply writing data to a file. I was able to put that together fairly quickly but then ran into the issue of how best to implement it, either as a method within the test class itself or as a separate class which would then be called by the test class (and any other future test classes which might want to use it). The first option was clearly the easiest and the second was clearly the most sensible.

So I went for both, of course!

While implementing the basic logging as method in my test class, I ran into questions as to how best to initialize the output file, how to append new data to the old without trouncing the file each time, adding a nice separator between each test case and so on. I finally got it sorted out to my liking after which I made the move to putting it into a class of it’s own. Fully acknowledging plenty of help from ‘anonymous donors’ on the Web, here are the results:

import java.io.*;

public class Logger {
    public static String logFileName;

    public Logger (String filename) throws IOException {
        this.logFileName = filename;

    public void initLog(String fileName) throws IOException {
        // initialize log file and delete existing
        File logFile = new File(fileName);

    public void logThis(String message) {

        BufferedWriter bw = null;

        try {
            bw = new BufferedWriter(new FileWriter(this.logFileName, true));
        } catch (IOException ioe) {
        } finally {                       // always close the file
            if (bw != null) try {
            } catch (IOException ioe2) {
                // just ignore it
        } // end try/catch/finally

    } // end method()

    public void logSeparator() {
        String separator = "------------------------------\n";


To implement the code from another file, you first need to instantiate an object and (if you like) define a variable to hold the log file name:

public static Logger logger;
public static String logFileName = "ExampleLoginsParameterizedTest.log";

Then, in my JUnit @BeforeClass method, I fully instantiate and initialize the logger:

public static void startLogger() throws IOException {
    // instantiate logger
    logger = new Logger(logFileName);
    // initialize new log

The first line hits the Logger constructor with the logFileName text variable, while the second calls the ‘initLog’ method with the same variable name to clobber the old log if it exists. The old log is clobbered in a way that would make Rube Goldberg beam with pride. The Logger class creates a file with the desired name and then deletes it. If a file with the same name exists, then that file ends up deleted. If it doesn’t, then a file is quickly created and deleted, no harm no foul. There’s probably a much better way to do this, but that’s what I came up with on short notice.

The actual act of logging looks like this:

// log test info and separator to log.txt file AND log to console
message = "Testing: (" + this.UserType + ") " + this.Username
        + "/" + this.Password + ", " + this.SchoolID + "\n";

That code appears in my JUnit @Before method, which runs before each test. In this case it puts a separator and then writes some basic info about the test in question.

In another area of the test class, I use the logger to record pertinent details if a try/catch loop fails:

try {
        wait.until(ExpectedConditions.presenceOfElementLocated(By.linkText("Log out")));
    catch (TimeoutException timeout) {
        // log error to log.txt file AND log to console
        message = ">>>ERROR:  Login for " + this.Username + "/" + this.Password
                + " appears to be unsuccessful, 'Log out' link never appeared.\n"
                + "Error text: \n" + timeout + "\n";

That’s it. A poor man’s logger that does what I need and very little more!

Parametrized Testing With WebDriver and JUnit

12 May

Parametrized testing, with WebDriver and JUnit (4 in this case) is not all that hard, provided you have a few magical incantations, tremendous computing horsepower and endless coffers of disposable funds.

No, really, it’s not that hard! If I can do it, anyone can. The incantations are all you really need (although ample funding, a sturdy laptop and plenty of tasty snacks is always nice).

The first one is this:


This magical JUnit directive goes above the initial class declaration in your code.

The next one is this:

public LoginsParameterizedTest(String uname, String pword, String schoolID, String userType) {
        this.Username = uname;
        this.Password = pword;
        this.SchoolID = schoolID;
        this.UserType = userType;

That’s a constructor for my particular class file. Yours will be different. Just make sure to replace ‘LoginsParameterizedTest’ with whatever the name of your class is, and pass along whatever parameters will be important for your testing. All this constructor does is assign the passed in variables to the actual class variables (each of which should be declared as private beforehand outside of the constructor method).

Now we get to the fun part, the data we’ll be passing to each iteration of the test.

    public static Collection data() {
        return Arrays.asList(
                new Object[][]{
                        { "username1", "password1", "demo", "Instructor" },
                        { "username2", "password2", "demo", "Student" },
                        { "username3", "password3", "demo", "Student" },
                        { "username4", "password4", "demo", "Student" }

You can copy/paste the framework of the code and then tailor your data to match your own test. Just 4 lines here, but there could be as many as you wish. Each element of a given array should map directly to the parameters passed to the constructor. Easy, no?

Finally, for the actual @Test’s, go on as usual, but replace specific parameter data with the parameter variable names you defined earlier in the class, prefixed with ‘this.’ like so:


Those are not the most robust assertions of course, but that’s pretty much all there is to it for the basic approach. For each line of data passed to the constructor, you’ll get a fresh junit test result as output. This can really revolutionize your tests and save you from writing mountains of fragile code. Try taking a simple project you already have under way and parametrizing it.

Next up will be parametrizing values from a spreadsheet or file, instead of from within the code itself.

Huge thanks to Alan Richardson and his absolutely beyond superb WebDriver course on Udemy. Check him out, sign up and let the learning really begin!

Nailing (finally) the Navigation Page Object

24 Apr

READERS TAKE NOTE: I wrote this a while back and then found a LOT of mistakes and better ways of doing things, but never came back to update the post. Oh the things I learned from this NavBar class! The basic idea here still applies, but take the details with a grain (or four) of salt.


I’ll add details later, but I wanted to share a page object class I wrote to allow for easy navigation for a suite of Selenium tests we’re working on.

The class is simply called ‘NavBar’ and looks like this:

package com.Vericode;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy;

public class NavBar {
	static String contentMenuCSS = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122";
	static String tagMenuCSS = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2132";

	public void contentDashboardButtonClick(WebDriver driver) {
		String css = "html.js body.html div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2121 a";
	public void addContentButtonClick(WebDriver driver) {
		// ** troubleshoot later **
		//String css = "html.js body.html div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122";
		// ** in the meantime, just get the url **
		driver.get(driver.getCurrentUrl().replace("/content-dashboard", "") + "/node/add");
	public void addArticleButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2124 a";
	public void addBlogButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2125 a";
	public void addFilmButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2126 a";
	public void addInfographicButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2127 a";
	public void addPollButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2128 a";
	public void addSpecialFeatureButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2129 a";
	public void carouselControlButtonClick(WebDriver driver) {
		String css="li.menu-2130 a";
	public void gridControlButtonClick(WebDriver driver) {
		driver.findElement(By.cssSelector("li.menu-2131 a")).click();
	public void tagsAndAuthorsButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2132 a";
	public void addAuthorButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2133 a";

	public void addTagButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2135 a";
	public void viewAuthorsButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2134 a";
	public void viewTagsButtonClick(WebDriver driver) {
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2136 a";
	public void logoutButtonClick(WebDriver driver) {
		driver.findElement(By.cssSelector("li.menu-2123 a")).click();
	// Some helper methods for this class
	public static void contentMenuHover(WebDriver driver) {
		WebElement menuHoverLink = driver.findElement(By.cssSelector(contentMenuCSS));
		new Actions(driver).moveToElement(menuHoverLink).perform();
		waiting(1);  // pathetic, I know
	public static void tagMenuHover(WebDriver driver) {
		WebElement menuHoverLink = driver.findElement(By.cssSelector(tagMenuCSS));
		new Actions(driver).moveToElement(menuHoverLink).perform();
		waiting(1);  // pathetic, I know
	public static void waiting (int n){
        long t0, t1;
        t0 =  System.currentTimeMillis();
            t1 = System.currentTimeMillis();
        while ((t1 - t0) < (n * 1000));

You’ll see near the beginning there where there was one case in which a simple click wasn’t doing the job. I pulled some hair on that one to no avail, so have decided to brute force it with a simple ‘get’ and a bit of base URL massaging. We’ll be using this class across multiple sites for which the URL’s will each be a little bit different depending on locality, so I’m hoping that this won’t break in those cases (testing this soon!)

And then here’s the test from the test driver class I wrote to test it out. All’s green that ends green! The print statements were for troubleshooting early on and will be removed for clarity. This test just navigates to a page using the NavBar page object, and then verifies the correct title.

	public void testMenuNavigation() {
		assertThat(driver.getTitle(), is("Editor Dashboard | US English"));
		assertThat(driver.getTitle(), is("Add content | US English"));
		assertThat(driver.getTitle(), is("Editor Dashboard | US English"));
		assertThat(driver.getTitle(), is("Create Article | US English"));
		assertThat(driver.getTitle(), is("Create Blog | US English"));
		assertThat(driver.getTitle(), is("Create Film | US English"));
		assertThat(driver.getTitle(), is("Create Infographic | US English"));
		assertThat(driver.getTitle(), is("Create Poll | US English"));
		assertThat(driver.getTitle(), is("Create Special Features | US English"));
		assertThat(driver.getTitle(), is(not("Carousel Control | US English"))); // fail when fixed?
		assertThat(driver.getTitle(), is("Grid Manager | US English"));
		assertThat(driver.getTitle(), is("Taxonomy | US English"));
		assertThat(driver.getTitle(), is("Tags & Authors | US English"));
		assertThat(driver.getTitle(), is("Tags & Authors | US English"));
		assertThat(driver.getTitle(), is("View Authors | US English"));
		assertThat(driver.getTitle(), is("View Tags | US English"));
		assertThat(driver.getTitle(), is("User Account | US English"));	

This should help us a great deal in writing our tests, as some of the navigation items are wrapped in javascript and hidden. Now that complexity is hidden away in the NavBar class, which will be much easier to change and troubleshoot if there are changes to the application code down the road.

All we need to do is instantiate a NavBar object once in our code:

static NavBar navBar = new NavBar();

…and then we can traverse the menu with simple, easy-to-read one-line statements any time we need:


Also nice is the fact that in the IntelliJ or Eclipse IDE’s, the context help menu’s will show all of these navigation options in a nice list without our having to memorize them.