WebDriver is a new framework by Google for writing web automated tests. It is being merged with Selenium by OpenQA into Selenium 2.0, but as of Feb 19th, 2010, it is already available at http://code.google.com/p/selenium/ while the development is still in progress. Some of the advantages of WebDriver are a better and object-oriented API, use of browser-specific mechanisms to execute the tests and better support for advanced cases like drag and drop and dealing with pop-ups or multiple windows.
Using WebDriver is simple, there's no need to start any server or anything. All that it takes is to instantiate and use any of the WebDriver interface implementing classes. There's a driver for each of the supported browsers (the current drivers are Firefox, Internet Explorer, Chrome and HTMLUnit):
WebDriver driver = new FirefoxDriver(); driver.get("http://localhost:8080/mywebsite"); driver.findElement(By.id("username_field"));
Each driver uses a different approach to simulate the user's interactions with the browser, contrary to Selenium that always uses Javascript. This means that the tests run in the most native way in each browser, which guarantees better performance and flexibility, but as the API is still the same, writing tests that have to run in many different browsers becomes simple ![]()
Currently, as I am writing this, the Firefox driver is the most advanced one in terms of implementation. You can check the development road map here: http://code.google.com/p/selenium/wiki/RoadMap
The WebDriver object-oriented API makes the code naturally more maintainable. Plus, it also makes it easier to access the web elements, their children and their properties, reducing the need to use xpaths:
String username = "admin"; String password = "admin"; WebDriver driver = new FirefoxDriver(); driver.get("http://localhost:8080/mywebsite"); driver.findElement(By.id("os_username")).sendKeys(username); driver.findElement(By.id("os_password")).sendKeys(password); driver.findElement(By.id("loginButton")).click(); assertEquals("Dashboard", driver.getTitle()); WebElement recentTable = driver.findElement(By.id("recentlyUpdated")); List<WebElement> recentTableRows = recentTable.findElements(By.tagName("tr")); assertEquals(10, recentTableRows.size());
Notice how the findElements method searches for the elements children of the recentTable element.
It looks even better if used with the PageObjects pattern! ![]()
Talking about PageObjects, WebDrivers also offers a PageFactory class with auto binding for web elements, which makes it even more fun to use the pattern:
public class LoginPage { private WebDriver driver; @FindBy(id = "os_username") private WebElement usernameField; @FindBy(id = "os_password") private WebElement passwordField; // automatically binds by id using the field's name private WebElement loginButton; public LoginPage(WebDriver driver) { this.driver = driver; driver.get("http://localhost:1990/confluence"); } public Dashboard login(String username, String password) { usernameField.sendKeys(username); passwordField.sendKeys(password); loginButton.click(); return PageFactory.initElements(driver, Dashboard.class); } } public class Dashboard { private WebDriver driver; @FindBy(id = "recentlyUpdated") private WebElement recentTable; public Dashboard(WebDriver driver) { this.driver = driver; if (!"Dashboard".equals(driver.getTitle())) { throw new IllegalStateException("Dashboard page expected"); } } public int getRecentlyUpdatedRowsCount() { List<WebElement> recentTableRows = recentTable.findElements(By.tagName("tr")); return recentTableRows.size(); } }
And our test:
LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
Dashboard dashboard = loginPage.login(username, password);
assertEquals(10, dashboard.getRecentlyUpdatedRowsCount());
Isn't it cool? ![]()
Get to know more about WebDriver at http://google-opensource.blogspot.com/2009/05/introducing-webdriver.html and http://code.google.com/p/selenium/
A more complete manual decribing also some more advanced features can be found here: http://seleniumhq.org/docs/09_webdriver.html
Have fun!
Comments (7)
Feb 22, 2010
Aleksandr Zuikov says:
Pretty cool thing, however I see XPath as a strength, not a weaknessPretty cool thing, however I see XPath as a strength, not a weakness
Feb 22, 2010
Timur Strekalov says:
Me, too although I assume many would disagree, but we're geeky enough to love i...Me, too
although I assume many would disagree, but we're geeky enough to love it 
Feb 23, 2010
Luiz Ribeiro says:
I think that it is indeed cool and flexible and powerful. Somehow I forget it al...I think that it is indeed cool and flexible and powerful.
Somehow I forget it all and feel just a bit of a pain when I have to deal with somebody's else code with lots of xpath :P
Feb 23, 2010
Timur Strekalov says:
I dunno, I think understanding it is much easier than actually writing it and ma...I dunno, I think understanding it is much easier than actually writing it and making it work. If you don't really remember a lot of it, that is
Mar 04, 2010
Igor Malinin says:
It is only 4 axes you need to learn! Even if you forgot the language complet...It is only 4 axes you need to learn! Even if you forgot the language completely, take the spec. and learn it in 15 minutes! It simple like hell and expressions is very easy to understand comparing to any other tool for XML querying.
So, here is my +1 for XPath. Considering that I am strong supporter of type-safe languages and XPath is not one of them, I think my "+1" has really good weight :)
Apr 15
Anonymous says:
Let's be honest - XPath just sucks in functional user interface testing. Why? It...Let's be honest - XPath just sucks in functional user interface testing. Why? It makes your tests look really ugly and not readable (especially if some complex xpath expressions are needed or someone non-programmer has to read those tests). But then again, Java does the same thing
In one short sentence - type-safe languages (especially Java with all of it's unnecessary boilerplate code) are not the thing for writing tests for user interface. If you're thinking otherwise, then you're just being ignorant and don't even try to understand that you don't need this "safety" at all. Or do you? Please explain 
How to get rid of XPath? Just write normal html using id and name attributes so it's easy to access all your needed html elements. Can't do it? Well, then you're just being lazy.
Keep up the good (or not so good) work!
Apr 16
Luiz Ribeiro says:
I agree with you that XPath is not nice for tests readability. That's what I was...I agree with you that XPath is not nice for tests readability. That's what I was stressing also. It sure is powerful but not nice :D
And, yeap, WebDriver's development is much faster for the Java interfaces, but hey, there's always Groovy (and other JVM dynamic languages) that you can use too!
WebDriver + Spock = cool!