Why do I prefer Selenium (Ruby) over Watir?
I develop/maintain raw Selenium WebDriver tests with better efficiency.
A week ago, a reader sent me a question “what were your reasons for stopping using Watir in 2010?”
I started real UI test automation with Watir in 2006 (see My Test Automation Journey), and liked it a lot. I even wrote an ebook on Watir. Check out this article for my successful test automation in Watir that enabled real DevOps back in 2009 (when the term not existed yet). I still don’t mind using Watir now if necessary.
Since the release of Selenium 2, (a.k.a, Selenium WebDriver) in 2011, I have been using Watir and raw Selenium at the same time (Watir for Project 1, Selenium for Project 2). Gradually, I found myself using less and less Watir. I like Selenium WebDriver, the raw Selenium WebDriver better: more intuitive and consistent syntax, faster, more reliable, better supported, and easier to learn.
Table of Contents:
∘ 1. Raw selenium syntax is actually more natural.
∘ 2. Watir became a syntax layer on top of Selenium, anyway
∘ 3. Watir shows signs of fading
∘ 4. I implemented ‘Attaching existing Window’, the only missing feature in the original Watir, in TestWise
∘ 5. It is easier to convince a project to adopt Selenium than Watir.
1. Raw selenium syntax is actually more natural.
When I write a test step for the element, the syntax is more consistent with Selenium. For example, I copied the element ID or name (by inspection in Chrome).
driver.find_element(:name, "user_name")...
Here all I needed to focus on was to paste the Name attribute. In Watir, I had to remember the tag name too, such as browser.text(:name, ...)
and brower.button(...)
(the standard syntax based on the Watir doc).
I know that I could use
browser.element(:name, ...)
. But it would be two syntaxes for the same statement which is “not recommended” .“
while this works: browser.element(tag_name: 'div')
” — Watir Doc
it is highly recommended to leverage this locator by using the element's associated method: browser.div
I prefer there is only one consistant syntax, like raw Selenium WebDriver.
The argument might be that Watir's syntax is more concise and easy to type. That’s true. But I can overcome that with the TestWise snippet feature.
For the above example, I just need to type dfen
(driver find element by name) followed by the tab key, then paste the copied ID. Done.
2. Watir became a syntax layer on top of Selenium, anyway
I have used Watir, Watir-WebDriver, Watir-classic (old Watir with OLE), and now Watir (really is Watir-WebDriver).
Yes, Watir works. But I like to go directly to the foundation layer, given that it offers the same productivity. Why? an extra layer introduces performance overhead and possible defects. If I can achieve the same or higher productivity with raw Selenium, why not?
3. Watir shows signs of fading
‘r’ in Watir is Ruby. I am grateful to the Watir creators for using the best test automation scripting language. However, as you know, Ruby’s popularity has unfortunately been decreasing (starting with the failed Angular.js) in app development, which affects the choice for testing too.
Another objective proof is the declining sales of my book: Watir Recipes.
Personally, I knew several Watir testers ‘betrayed’ Watir and worked on jobs using Protractor, Cypress, or Playwright. To my knowledge, their test automation attempts all failed when using these JavaScript frameworks. But you can’t blame them because they want better pay or more job opportunities 😔.
I would not call JS test automation a dark side. After all, the measurement of test automation success is objective (check out the Definition of End-to-End Test Automation Success). The result is binary, based on the objective assessment, regardless of personal preferences. To my knowledge, every single JS test automation attempt failed (acknowledged or not-acknowledged, I judged based on the success definition). As a test automation coach, I have seen several of my mentees who have seen real test automation (using raw Selenium + Ruby, working on a team with daily automated regression testing), jumped on JS ship. Check out this story “A Former Mentee Failed Test Automation with Protractor”.
4. I implemented ‘Attaching existing Window’, the only missing feature in the original Watir, in TestWise
In the original Watir (deprecated as ‘watir-classic’, as Internet Explorer is now dead, so is ‘watir-classic’), there was an important feature: Watir Attaches an existing IE window. It was so essential that I used it many times a day. However, this feature no longer works on watir-webdriver
, because Selenium WebDriver does not have this feature.
Therefore, I came up with my own solution to attach the existing Chrome browser window using the TestWise v4 tool with one global variable (in Ruby). That’s why my early test scripts started as below:
@driver = $driver = Selenium::WebDriver.for(:browser)
With the help of TestWise, I develop/debug raw Selenium Tests with the same or better efficiency as Watir ones.
I re-implemented the ‘attaching to existing browser window’ feature in TestWise 6, and the global variable is no longer required.
5. It is easier to convince a project to adopt Selenium than Watir.
Selenium WebDriver is the W3C standard. Most software companies have tried Selenium at some stage despite low success rates (due to the capability, not the framework. I found Selenium was often in approved tech stacks. However, when I mentioned Watir, a large percentage of staff were not aware of it.
From my experience, seeing so many test automation failed (WebDriverIO, Protractor, TestCafe, Cypress, Playwright, and numerous so-called self-created frameworks, see why?), the only successful ones used WebDriver, a W3C Standard. Of course, there are many failed Selenium test automation too, but due to lacking the capablity (need to seek professional help from test automation coach), on the right track though.
Besides, I could find Selenium success stories to support my proposal using raw Selenium WebDriver.
However, there is an issue with choosing Selenium, which does not exist with Watir. If a software company selects Watir, the scripting language will be set, Ruby. Selenium has five official language bindings: Ruby, Python, Java, C#, and JS. Convincing a Java project team to use Selenium Ruby, from my experience, turned out to be very difficult despite the fact that the team members knew that the automated end-to-end test scripts had nothing to do with the code. Human issue!
FAQ
You may be biased because your TestWise tool supports it.
Wrong. TestWise supports Watir from v1 (2006).
I am 100% objective here. W3C won’t pay me a cent for promoting Selenium WebDriver. I share my opinion only based on my experience of authoring/maintaining test scripts and training/coaching testers. Check out my other article: Why Selenium WebDriver is So Easy to Learn? and my daughter’s article: Set up, Develop Automated UI tests and Run them in a CT server on your First day at work.
2. Watir syntax is more concise and readable than Selenium from the maintenance perspective. Is it surely a better option?
Not really. I agree that Watir's syntax is more concise and may be slightly more readable. However, in my opinion, it offers few benefits compared to Selenium. Let me illustrate this with an example.
Below is a Selenium test script, I purposely chose long Selenium statements there. Watir testers can immediately picture a more clean and concise version of Watir.
it "One-way trip" do
driver.find_element(:id, "username").send_keys("agileway")
driver.find_element(:id, "password").send_keys("testwise")
driver.find_element(:xpath,"//input[@value='Sign in']").click
driver.find_element(:xpath, "//input[@name='tripType' and @value='oneway']").click
Selenium::WebDriver::Support::Select.new(driver.find_element(:name, "fromPort")).select_by(:text, "Sydney")
Selenium::WebDriver::Support::Select.new(driver.find_element(:name, "toPort")).select_by(:text, "New York") Selenium::WebDriver::Support::Select.new(driver.find_element(:id, "departDay")).select_by(:text, "02") Selenium::WebDriver::Support::Select.new(driver.find_element(:id, "departMonth")).select_by(:text, "May 2016")
driver.find_element(:xpath,"//input[@value='Continue']").click expect(page_text).to include("2016-05-02 Sydney to New York")
end
But this is not my final test script. After verifying the script working, I immediately performed functional test refactorings based on Maintainable Automated Test Design to this:
it "[2] One-way trip" do
login("agileway", "testwise") # helper function
flight_page = FlightPage.new(driver) # POM
flight_page.select_trip_type("oneway")
flight_page.select_depart_from("Sydney")
flight_page.select_arrive_at("New York")
flight_page.select_depart_day("02")
flight_page.select_depart_month("May 2016")
flight_page.click_continue
expect(page_text).to include("2016-05-02 Sydney to New York")
end
This version is more readable, concise, and more importantly, much easier to maintain. The individual raw test steps are extracted into the functions in page classes, which are much easier to manage. By using TestWise’s refactoring support, I achieved that quickly, about 30 seconds for this test script.
By the way, Watir testers, you too can use the snippet and test refactoring in TestWise for your Watir test scripts.
Related reading: