The task was to go to various woot web sites and to read the product name and price of the offer of the day.
I wrote a little bit of Selenium code and thought I'd post it here in case any of it is useful to anyone.
I got the job - so it can't be too bad.
First up I defined an interface to represent a woot page:
package uk.co.doogle;
import com.thoughtworks.selenium.Selenium;
/**
* This interface defines the methods we must implement for classes
* of type Woot. Woot web sites have one item for sale every 24 hours.
* @author Tony
*/
public interface Woot {
/**
* Defines the interface of the method we use to get the price
* of the item for sale on a Woot website
* @param selenium the selenium object we pass in which is used to interact
* with the browser/web page
* @return String representation of the price of the item for sale
*/
public String getPrice(Selenium selenium);
/**
* Defines the interface of the method we use to get the product name
* of the item for sale on a Woot website
* @param selenium the selenium object we pass in which is used to interact
* with the browser/web page
* @return String representation of the product name of the item for sale
*/
public String getProductName(Selenium selenium);
}
Then I implemented this interface a few times to represent the actual behaviour of the various woot pages - here for example if the winewoot page:
public class WineWoot extends BaseWoot {
/**
* Constructor
* @param url pass in the url of the web site
*/
public WineWoot(String url) {
super(url);
}
/**
* Implementation of the method to get the price of the object for sale on
* the Woot web site.
*/
public String getPrice(Selenium selenium) {
//if you need to update the xpath to the piece of text of interest - use xpather firefox plugin
String xPath = "//html/body/header/nav/ul/li[8]/section/div/a/div[3]/span";
selenium.waitForCondition("selenium.isElementPresent(\"xpath=" + xPath + "\");", "12000");
return selenium.getText(xPath) + " ";
}
/**
* Implementation of the method to get the product name of the item for sale
* on the Woot web site
*
*/
public String getProductName(Selenium selenium) {
//if you need to update the xpath to the piece of text of interest - use xpather firefox plugin
String xPath = "//html/body/header/nav/ul/li[8]/section/div/a/div[2]";
selenium.waitForCondition("selenium.isElementPresent(\"xpath=" + xPath + "\");", "12000");
return selenium.getText(xPath) + " ";
}
}
Note - back then I used the xPather plugin - this doesn't work for recent versions of firefox, so now I use firebug.
Then I wrote the actual 'test':
package uk.co.doogle;
import com.thoughtworks.selenium.*;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
/**
* This class is where we define tests of the Woot web sites
* @author Tony
*
*/
public class TestWoots extends SeleneseTestCase {
/**
* Outputstream for our results file
*/
private BufferedWriter out;
/**
* Our list of Woot web sites we want to test
*/
private List<BaseWoot> sites = new ArrayList<BaseWoot>();
/**
* This is where we do any set up needed before our test(s) run.
* Here we add the list of Woot web sites we want to test and we create an
* output stream ready to write results to file
*/
public void setUp() throws Exception {
sites.add(new BaseWoot("http://www.woot.com/"));
sites.add(new ShirtWoot("http://shirt.woot.com/"));
sites.add(new WineWoot("http://wine.woot.com/"));
try {
//let's append to our file...
FileWriter fstream = new FileWriter("out.csv", true);
out = new BufferedWriter(fstream);
out.write("Site, Product Name, Product Price");
out.newLine();
} catch (Exception e) {
System.err.println("Error creating a file to write our results to: " + e.getMessage());
}
}
/**
* Tests getting the item name and price for the item for sale on each Woot web site we test. We see the results of the test
* in std out in the form of a table and we also write the results to a csv file.
* If there are any errors getting the information, this is displayed instead.
*
* How to run me: open command prompt and from the directory where our selenium server is
* located type: java -jar selenium-server-standalone-2.0b3.jar (or equivalent) and wait for the server to start up.
* Then just run this unit test.
*/
public void testGetItemsAndPrices() throws Exception {
//for each Woot site in our list of sites we want to test
for (BaseWoot woot : sites) {
//let's put this in a try catch block as we want to try ALL the sites - some may be down or slow...
try {
selenium = new DefaultSelenium("localhost", 4444, "*firefox", woot.getUrl());
selenium.start();
selenium.open("/");
selenium.waitForPageToLoad("50000");
//add a new row for our table to std out
System.out.println();
//print out the information we need - the site, the title of the item for sale and the price
String siteUrl = woot.getUrl();
String productName = woot.getProductName(selenium);
String productPrice = woot.getPrice(selenium);
//sometimes there are commas which mess up our csv file - so
//we substitute with ;
productName = productName.replace(",", ";");
System.out.print("website: " + siteUrl + " ");
System.out.print("product name: " + productName);
System.out.print("price: " + productPrice);
out.write(siteUrl + ", " + productName + ", " + productPrice);
out.newLine();
} catch (Exception ex) {
//here may may see that the web site under test has changed and the xpath to the price or product name may need to
//be changed in the Woot class
System.out.print("problem getting the data for: " + woot.getUrl()+ " " + ex.getMessage() + " ");
} finally {
selenium.stop();
}
}
}
/**
* Any tear-down we need to do to cleanup after our test(s).
* Here we just stop selenium and close the output stream
*/
public void tearDown() throws Exception {
selenium.stop();
out.close();
}
}
I know this code worked for a couple of years, and I have made some minor changes to get it to work with the current woot.com web sites - all I had to do was get the latest selenium-server-standalone.jar for it to work with the latest firefox and also to update the xpaths to the price and product name information. That would be a good improvement to the code - to make it data driven - such that we could just update the xpaths in a config file rather than changing the hard-coded ones I have used here. That was the only feedback from the client actually.
Anyway - hope you find it useful - and if you need expert automation engineers get in touch with Doogle!
Interesting piece of code could you help me installing some html code in my blog? i could pay you..
ReplyDeleteLynda
Hi - glad you found it interesting! Get in touch via my web site with more details about what you need to do (www.doogleonline.co.uk) and I'll see if I can help, Cheers, Tony.
DeleteThis comment has been removed by the author.
ReplyDelete