Archive | April, 2013

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.

-Kent

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) {
		contentMenuHover(driver);
		String css = "html.js body.html div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2121 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void addContentButtonClick(WebDriver driver) {
		// THIS FAILS I DON'T KNOW WHY
		// ** troubleshoot later **
		//contentMenuHover(driver);
		//String css = "html.js body.html div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122";
		//driver.findElement(By.cssSelector(css)).click();
		// ** in the meantime, just get the url **
		driver.get(driver.getCurrentUrl().replace("/content-dashboard", "") + "/node/add");
	}
	
	public void addArticleButtonClick(WebDriver driver) {
		contentMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2124 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void addBlogButtonClick(WebDriver driver) {
		contentMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2125 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void addFilmButtonClick(WebDriver driver) {
		contentMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2126 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void addInfographicButtonClick(WebDriver driver) {
		contentMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2127 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void addPollButtonClick(WebDriver driver) {
		contentMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2128 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void addSpecialFeatureButtonClick(WebDriver driver) {
		contentMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2122 ul li.menu-2129 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void carouselControlButtonClick(WebDriver driver) {
		String css="li.menu-2130 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	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";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void addAuthorButtonClick(WebDriver driver) {
		tagMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2133 a";
		driver.findElement(By.cssSelector(css)).click();
	}

	public void addTagButtonClick(WebDriver driver) {
		tagMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2135 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void viewAuthorsButtonClick(WebDriver driver) {
		tagMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2134 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	public void viewTagsButtonClick(WebDriver driver) {
		tagMenuHover(driver);
		String css = "div#admin-toolbar ul#nice-menu-main.nice-menu li.menu-2136 a";
		driver.findElement(By.cssSelector(css)).click();
	}
	
	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();
        do{
            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.

	@Test
	public void testMenuNavigation() {
		loginAsEditor();
		assertThat(driver.getTitle(), is("Editor Dashboard | US English"));
		
		System.out.println("addContentButton");
		navBar.addContentButtonClick(driver);
		assertThat(driver.getTitle(), is("Add content | US English"));
		
		System.out.println("dashboardButton");
		navBar.contentDashboardButtonClick(driver);
		assertThat(driver.getTitle(), is("Editor Dashboard | US English"));
		
		System.out.println("addArticleButton");
		navBar.addArticleButtonClick(driver);
		assertThat(driver.getTitle(), is("Create Article | US English"));
		
		System.out.println("addBlogButton");
		navBar.addBlogButtonClick(driver);
		assertThat(driver.getTitle(), is("Create Blog | US English"));
		
		System.out.println("addFilmButton");
		navBar.addFilmButtonClick(driver);
		assertThat(driver.getTitle(), is("Create Film | US English"));
		
		System.out.println("addGraphicsButton");
		navBar.addInfographicButtonClick(driver);
		assertThat(driver.getTitle(), is("Create Infographic | US English"));
		
		System.out.println("addPollButton");
		navBar.addPollButtonClick(driver);
		assertThat(driver.getTitle(), is("Create Poll | US English"));
		
		System.out.println("addFeatureButton");
		navBar.addSpecialFeatureButtonClick(driver);
		assertThat(driver.getTitle(), is("Create Special Features | US English"));
		
		System.out.println("carouselControlButton");
		navBar.carouselControlButtonClick(driver);
		assertThat(driver.getTitle(), is(not("Carousel Control | US English"))); // fail when fixed?
		
		System.out.println("gridControlButton");
		navBar.gridControlButtonClick(driver);
		assertThat(driver.getTitle(), is("Grid Manager | US English"));
		
		System.out.println("tagsAndAuthorsButton");
		navBar.tagsAndAuthorsButtonClick(driver);
		assertThat(driver.getTitle(), is("Taxonomy | US English"));
		
		System.out.println("addAuthorButton");
		navBar.addAuthorButtonClick(driver);
		assertThat(driver.getTitle(), is("Tags & Authors | US English"));
		
		System.out.println("addTagButton");
		navBar.addTagButtonClick(driver);
		assertThat(driver.getTitle(), is("Tags & Authors | US English"));
		
		System.out.println("addViewAuthorsButton");
		navBar.viewAuthorsButtonClick(driver);
		assertThat(driver.getTitle(), is("View Authors | US English"));
		
		System.out.println("addViewTagsButton");
		navBar.viewTagsButtonClick(driver);
		assertThat(driver.getTitle(), is("View Tags | US English"));
		
		System.out.println("logoutButton");
		navBar.logoutButtonClick(driver);
		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:

navBar.viewTagsButtonClick(driver);

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.

Advertisements
19 Apr

One of the most satisfying aspects of the Selenium Webdriver course I’ve been taking on Udemy has been communicating with it’s creator, Alan Richardson. Alan’s delivery on his videos is upbeat, professional and well produced, and his enthusiasm for testing with Selenium is infections. Alan is also great about responding to questions via email and always has a generous and thoughtful answer to even the most mundane of questions.

What a happy surprise it was to find out a while back that he had referenced a comment of mine in one of his blog postings! I was having trouble getting the proper focus when exercising a simple test using the Webdriver user interactions and did a bit of research which led to a simple and unexpected workaround.

You can see Alan’s post here. What a thrill to be officially recognized by the Best Dressed Zombie Tester around!

Thanks, Alan!

; )