Videos now online for ‘Advanced Test Automation with Firefox’

Posted: November 19th, 2010 | Author: Dave | Filed under: Events | Tags: , , , , , | No Comments »

The videos from the third London Selenium users event are now available on the London Selenium YouTube channel: http://www.youtube.com/user/londonselenium/


Meetup.com Attendance Lists

Posted: November 8th, 2010 | Author: Dave | Filed under: Examples | Tags: , , , , | No Comments »

For the recent London Selenium Users Meetup Event I was asked if I could provide the attendance list in a suitable format for creating labels for the guests when they arrive. Given the short timeframe I did this simply by highlighting the names on meetup.com, copying them, and pasting them into a simple text editor. I then quickly cleaned this up before sending the list on. Within a short while the list was out of date due to some members dropping out.

It did occur to me at the time that I could write a simple Selenium script, but I didn’t want to delay providing the list. Well I’ve now had some time to revisit this, and hopefully for the next meetup event I’ll be more prepared. The following script should work on both upcoming and past events. It doesn’t support waiting lists, and may have problems if meetup.com truncates lists after a certain number. I may revisit these items once I’ve scheduled the next event.

Meetup.java

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
 
import java.util.ArrayList;
import java.util.List;
 
public class Meetup {
 
    HtmlUnitDriver driver;
 
    String meetup = "seleniumlondon"; //meetup name from URL
    String event = "14712022"; //event ID from URL
 
    @BeforeTest
    public void startDriver() {
        driver = new HtmlUnitDriver();
    }
 
    @AfterTest
    public void stopDriver() {
        driver.close();
    }
 
    @Test
    public void listResponses() {
 
        //open the event page
        driver.get("http://www.meetup.com/" + meetup + "/calendar/" + event + "/");
 
        if (driver.findElement(By.xpath("id('C_document')/descendant::dl[@class='stats'][2]/dt")).getText().equals("Who’s coming?")) {
            //this event has not yet occurred
            listMembers("id('C_document')//li[div[@class='D_attendeeHeader D_yes']]//li[starts-with(@id, 'member_')]", "Yes");
            listMembers("id('C_document')//li[div[@class='D_attendeeHeader D_maybe']]//li[starts-with(@id, 'member_')]", "Maybe");
            listMembers("id('C_document')//li[div[@class='D_attendeeHeader D_no']]//li[starts-with(@id, 'member_')]", "No");
        } else {
            //this event is in the past
            listMembers("id('C_document')//li[starts-with(@id, 'member_')]", "Attended");
        }
    }
 
    public void listMembers(String xpath, String label) {
 
        //get a list of all members that have responded or attended
        List<WebElement> memberElements = driver.findElements(By.xpath(xpath));
 
        int guestTotal = 0; //set guest total to zero
        List<Member> members = new ArrayList<Member>(); //create a list to store our members
        for (WebElement member : memberElements) {
            String name = member.findElement(By.className("D_name")).getText(); //member name
 
            int guests = 0; //set member's guests to zero
 
            //get the number of guests for this member
            try {
                //upcoming events use a different class for the guest count as past events
                String guestsTemp = member.findElement(By.className("guests")).getText();
                guests = new Integer(guestsTemp.substring(guestsTemp.indexOf("+")+1, guestsTemp.indexOf(" ")));
            } catch (NoSuchElementException e) { }
 
            try {
                String guestsTemp = member.findElement(By.className("D_guests")).getText();
                //past events use a different format for the guest count
                guests = new Integer(guestsTemp.substring(guestsTemp.indexOf("+")+1, guestsTemp.indexOf(")")));
            } catch (NoSuchElementException e) { }
 
            guestTotal = guestTotal + guests; //update the total number of guests for this event
            members.add(new Member(name, guests)); //add the current member to our list
        }
 
        //output a label for this list including total member and guest counts
        System.out.println("\n" + members.size() + " " + label + getGuestSuffix(guestTotal));
 
        for (int i=0; i<members.size(); i++) {
            //output details for each member
            System.out.println(i+1 + ". " + members.get(i).name + getGuestSuffix(members.get(i).guests));
        }
    }
 
    public String getGuestSuffix(int guests) {
        //return a suffix to indicate the number of guests
        if (guests > 0) {
            return " (+" + guests + " guest" + (guests > 1 ? "s" : "") + ")";
        } else {
            return "";
        }
    }
 
    //inner class for members
    public class Member {
 
        String name;
        int guests;
 
        public Member(String name, int guests) {
            this.name = name;
            this.guests = guests;
        }
 
    }
 
}

Cheesecake

Posted: November 7th, 2010 | Author: Dave | Filed under: Examples | Tags: , , , , | 2 Comments »

Here’s another one of my odd Selenium examples! Last month I finally got to eat at a ‘Cheesecake Factory’ restaurant, after first hearing about them a few years back from an American friend. There’s an overwhelming choice of 30+ cheesecakes to choose from, and I’m really not good at making decisions when there’s so much choice. I decided to go with ‘The Original’, and that every subsequent visit to the chain I would work my way down the menu, knowing I’d probably never get through all of them in my lifetime!

So as I’m in California right now, I remembered my experience, and decided to check out the full menu from the restaurant so that I could add it to Evernote and keep track of my progress. Unfortunately I wasn’t able to do a nice copy+paste from the site, so – as usual – I wrote a Selenium script to list all the cheesecakes. For a change this script uses the HtmlUnitDriver, however you can easily swap in one of the other browser drivers.

CheesecakeFactory.java

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
 
import java.util.List;
 
public class CheesecakeFactory {
 
    HtmlUnitDriver driver;
 
    @BeforeTest
    public void startDriver() {
        driver = new HtmlUnitDriver();
    }
 
    @AfterTest
    public void stopDriver() {
        driver.close();
    }
 
    @Test
    public void listCheesecakes() {
        driver.get("http://www.thecheesecakefactory.com/");
        driver.findElement(By.linkText("Menu")).click();
        driver.findElement(By.linkText("Cheesecake")).click();
        List<WebElement> cheesecakes = driver.findElements(By.xpath("id('leftNav_levelTwo')//li"));
 
        System.out.println(cheesecakes.size() + " cheesecakes:");
        for (int i=0; i<cheesecakes.size(); i++) {
            System.out.println(i+1 + ". " + cheesecakes.get(i).getText());
        }
    }
 
}

Output

34 cheesecakes:
1. The Original
2. Fresh Strawberry
3. Reeses Peanut Butter Chocolate Cake Cheesecake
4. 30th Anniversary Chocolate Cake Cheesecake
5. White Chocolate Raspberry Truffle®
6. Ultimate Red Velvet Cake Cheesecake™
7. Godiva® Chocolate Cheesecake
8. Fresh Banana Cream Cheesecake
9. Adam's Peanut Butter Cup Fudge Ripple
10. White Chocolate Caramel Macadamia Nut Cheesecake
11. Lemon Raspberry Cream Cheesecake
12. Dulce de Leche Caramel Cheesecake
13. Chocolate Coconut Cream Cheesecake
14. Tiramisu Cheesecake
15. Chocolate Mousse Cheesecake
16. Vanilla Bean Cheesecake
17. Chocolate Tuxedo Cream™ Cheesecake
18. Kahlua® Cocoa Coffee Cheesecake
19. Pineapple Upside-Down Cheesecake
20. Chocolate Raspberry Truffle®
21. Dutch Apple Caramel Struesel
22. Chocolate Chip Cookie - Dough Cheesecake
23. Wild Blueberry White Chocolate Cheesecake™
24. Low Carb Cheesecake
25. Low Carb Cheesecake with Strawberries
26. Key Lime Cheesecake
27. Caramel Pecan Turtle Cheesecake
28. Brownie Sundae Cheesecake
29. Snickers® Bar Chunks and Cheesecake
30. Craig's Crazy Carrot Cake Cheesecake
31. Oreo® Cheesecake
32. Cherry Cheesecake
33. Pumpkin Cheesecake
34. Pumpkin Pecan Cheesecake

Hmmm… Maybe I should get the Caltrain into San Francisco and make it 2 down, 32 to go!


London Selenium Meetup Event #3

Posted: November 5th, 2010 | Author: Dave | Filed under: Events | Tags: , , , , , , | No Comments »

This week saw the third London Selenium Users Meetup event, with presentations from Mozilla and an update from Simon Stewart on the progress of Selenium 2. You can read my full write-up of the event on my personal blog.


New London Users Event: Advanced Test Automation with Firefox

Posted: September 24th, 2010 | Author: Dave | Filed under: Events | Tags: , , , , , | No Comments »

Although it’s been scheduled for a while, the next London Selenium Users meetup event has now been officially announced. As before, Google will be generously hosting the event, which this time is Firefox flavoured! There will be four presentations, mostly by folks from Mozilla, but also an update from Simon Stewart on the progress of Selenium 2. Head over to the event page on meetup.com for all the latest details.


Checking Wedding Gifts with Selenium

Posted: August 23rd, 2010 | Author: Dave | Filed under: Examples | Tags: , , , , | No Comments »

Admittedly this one is unlikely to be useful to many, but it could still serve as a useful example for Selenium 2. Also, I haven’t posted an example since alpha 5 was released.

I’m getting married in a few short weeks, and our gift list has now opened for any guests that would like to buy us something for the occasion. We debated over having a list in the first place, but in the end decided that it was probably for the best. One of our hesitations was that we didn’t want to know what people had bought for us before the day, and having an online gift list makes it possible to ‘spoil’ the surprise.

With the list only having been open a couple of days, the temptation was already pretty difficult to resist and we decided that it was okay to see what has been bought just so long as we don’t find out who’s bought what. Unfortunately this isn’t easy on the site as they’re listed together, so I was sneakily able to construct an XPath that extracted the necessary information. I’ve now combined into a Selenium 2 example using Java, which can be found below.

GiftList.java

package giftlist;
 
import java.util.List;
import java.util.concurrent.TimeUnit;
 
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
 
public class GiftList {
 
	private static WebDriver driver;
	private static final String GIFT_LIST_NUMBER = "123546";
	private static final String GIFT_LIST_PASSWORD = "password";
 
	public static void main(String [ ] args) {
		//open browser
		driver = new FirefoxDriver();
 
		//set implicit wait
		driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
 
		//login
		driver.get("https://www.johnlewisgiftlist.com/");
		driver.findElement(By.linkText("Manage your list")).click();
		driver.findElement(By.name("giftListNumber")).sendKeys(GIFT_LIST_NUMBER);
		driver.findElement(By.name("listPassword")).sendKeys(GIFT_LIST_PASSWORD);
		driver.findElement(By.linkText("Display List")).click();
 
		//get purchased items
		driver.findElement(By.linkText("Gifts purchased")).click();
		driver.findElement(By.xpath("//h1[text()='Gifts purchased by guests']"));
		List<WebElement> purchasedItems = driver.findElements(By.xpath("//tr[td[2] and @class='item']"));
 
		//output purchased items
		for (WebElement item : purchasedItems) {
			System.out.println(item.findElement(By.xpath("/td[1]")).getText());
		}
 
		//log out
		driver.findElement(By.linkText("Log out")).click();
 
		//close browser
		driver.close();
	}
 
}

Selenium 2 in .NET framework

Posted: July 7th, 2010 | Author: zacc | Filed under: Examples | Tags: , , , , , , | 18 Comments »

I’m not Dave but you might have met me at one of the London Selenium meets. My name is Zac and I have several years of automated testing experience with Selenium RC in Java and C# and am now intending to be one of the early adopters of Selenium 2 using the .NET version.

Selenium 2 and .NET are up to alpha4 already but thorough examples of code on the internet are a bit thin on the ground so far compared to the Java equivalent. In my time using Selenium RC and now Selenium 2 I have built up a framework to support it.

I consider it to be an intermediate-level framework for using Selenium 2, NUnit and the Page Object model together so some advanced users might find it a bit basic. You may have even seen some of these concepts as snippets on testing blogs around the place. But overall it offers a framework from which to develop an easily maintainable suite of tests using the Page Object model (which is now considered to be the best practice for Selenium 2). If you already have a suite of Selenium tests in flat files that is spiralling in size and you are looking to make it more durable and more efficient then this could suit you.

With this blog post I intend to step through and get you started with this framework.

Read the rest of this entry »


Get a new iPhone with help from Selenium

Posted: June 30th, 2010 | Author: Dave | Filed under: Examples | Tags: , , , , , , | No Comments »

I’ve been looking forward to the iPhone 4 ever since the 3GS was released, as I was in contract at the time and decided to wait another year for whatever Apple decided to release next. Due to unexpected (but very cool) circumstances, I was out of the country on the day Apple released the iPhone 4 and so was unable to queue up for one of the devices, and now due to the demand it’s very difficult to get hold of one. Since getting back to the UK I have been visiting my two nearest O2 stores to check if they have had a delivery, and today they pointed me towards their online stock checker…

So rather than check this manually, I decided to write a couple of small Selenium 2 scripts to check the stock levels at my ‘local’ stores, and to find out all stores that do have the devices. These examples use Java with TestNG (for dataproviders), and Selenium 2.

Read the rest of this entry »


Play Pacman with Selenium 2

Posted: May 25th, 2010 | Author: Dave | Filed under: Challenges, Examples | Tags: , , , , | 29 Comments »

When I saw Google’s recent interactive Pacman doodle to celebrate the game’s 30th anniversary, my first thought was ‘Wouldn’t it be cool to automate playing Pacman using Selenium’. I know – I’m a geek!

Google's Pacman Doodle

Anyway, below is my quick proof of concept using Selenium 2 alpha 4 – the latest version of Selenium 2 is available for download here.

Read the rest of this entry »


Survey Results from London Selenium Users

Posted: April 22nd, 2010 | Author: Dave | Filed under: Events | Tags: , , , , | No Comments »

Before holding the second London Selenium Users meetup we asked several questions of the Selenium users in London:

  1. What is your level of experience with Selenium?
  2. What do you want to know about Selenium 2?
  3. What language would you like to see Selenium 2 demos in?

Below are the slides that I didn’t get time to show at the event.

View more presentations from davehunt82.

In case you can’t see the slides above, the results are repeated below:

What is your level of experience with Selenium?

  1. Beginner: 44%
  2. Intermediate: 46%
  3. Advanced: 10%

What do you want to know about Selenium 2?

  1. New Features: 50%
  2. Migration: 20%
  3. Everything: 20%
  4. Grid: 10%

What language would you like to see Selenium 2 demos in?

  1. Java: 55%
  2. .NET: 26%
  3. Python: 10%
  4. Ruby: 3%
  5. JavaScript: 3%
  6. PHP: 3%