Automating the “10 Fast Fingers” Typing Test with Watir

For UI automation as a hobby, I tend to use Ruby and Watir. Today I’m going to walk through a script that automates an online typing test, using that toolset.

I won’t be digging into details much about really small details, like figuring out how to locate an element–I’m just going to put the locator in there, with minimal explanation, because I know you’re smart people and can learn more by just grabbing the code and fooling with it, than any amount of talking I do.

Plus it saves my fingers some wear-and-tear, and instead of typing here, I can type on a typing test. Or automate it.

Let’s get started!

Manual First, Then Automate

First let’s head over to the site itself, http://10fastfingers.com/, and click the “Start a Typing Test” button at the bottom.

Then just start using it. Every time you type a word, and hit the space bar, the next word will highlight.

When you have finished a test, start up another one and let’s take a look at the guts of what’s going on with this page.

Checking out the DOM

There’s a structure to this page that will need to be known before automating. We first need to know how to tell what word to have the script type.

Right-click on the first highlighted word and click “Inspect Element” in Chrome or Firefox.

You’ll see something like this:

<div id="words" class="row" style="opacity: 1;">
<div id="row1" style="top: 1px;"> 
<span wordnr="0" class="highlight">look</span> 
<span wordnr="1" class="">word</span> 
<span wordnr="2" class="">being</span> 
<span wordnr="3" class="">after</span> 
<span wordnr="4" class="">does</span> 
<span wordnr="5" class="">word</span> 
<span wordnr="6" class="">try</span> 
 ...

So a locator for these words can be found by searching for the following XPath:

//div[@id='words']/div/span

That particular XPath will give you multiple hits, which is fine, because Ruby allows you to iterate through a list of items and act on each one. Sounds perfect for a loop later.

Next, we need to find out where to actually type the word. So do the same Inspect Element operation on the text field below, and see what can be identified about it:

<input type="text" class="form-control" id="inputfield" value="" dir="ltr" placeholder="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">

Well that’s pretty straightforward. The XPath for this would be:

//input[@id='inputfield']

The Code

Ok let’s start putting this together. From here down, put all the code sections into the same script, in the order they’re presented.

First we need to tell the script which Ruby gems to use:

require "rubygems"
require "watir-webdriver"

Next we need a function that opens up a browser window and hooks the Watir session to it. Below is just some boiler plate code that I’ve been using for years. If you want to dig in and figure out how it works, be my guest, but it’s kind of out of scope of this article:

def setup
 client = Selenium::WebDriver::Remote::Http::Default.new
 client.timeout = 600
 # set up the $b component with the info here. 
 # $b = Watir::Browser.new :ff, :http_client => client
 $b = Watir::Browser.new :chrome, :http_client => client
 $timeout_length = 30
end

Once we open a browser, we need a place to go. We need a thread spun up to actually load the link we want to go to, and to shut down the thread when done:

def go_to_url(url)
 load_link($timeout_length){ $b.goto url }
end
def load_link(waittime)
 begin
  Timeout::timeout(waittime) do
  yield
 end
 rescue Timeout::Error => e
  log("Page load timed out: #{e}")
  retry
 end
end

We’ll also need a function to close out the browser when the script is done, otherwise you’ll have a browser window open every time you run the script:

def teardown
 $b.close 
end

Then once we have all this support code set up, we can write the script:

# setup the browser instance
setup

# go straight to the english typing test, saves time.
go_to_url "http://10fastfingers.com/typing-test/english"

# wait for the words to actually show up on the screen before doing anything else
$b.element(:xpath => "//div[@id='words']/div/span").wait_until_present

# when the input field is visible, click it so that you can start typing into it
$b.text_field(:xpath => "//input[@id='inputfield']").when_present.click

# iterate through each available word. for each word, 
# type in the text of the word followed by a space.
# this is how the site tells when you enter a word. 
$b.elements(:xpath => "//div[@id='words']/div/span").each do |word|
 # type the word followed by a space, so the site picks up that you typed a word
 $b.send_keys("#{word.text}")
 $b.send_keys(" ")
end

# all done! finish up and close out the browser instance
teardown

Performance Enhancing!

How can you make this go faster? What about using different browser? How high a rate can you get?

Hiding the Ugly (aka Refactoring)

How would you refactor this? It’s likely that opening a browser, going to a url are going to be common across all kinds of web UI scripts.

Refactoring is a great way to learn more about the structure of a script, and understand how it works. The more you do it, the more you’ll be comfortable with any code, so feel free to grab this and start moving things around.

Have fun! And don’t forget to share!

If this is your first foray into UI automation, welcome to the fold! It’s a fun way to test, and there are lots of things beyond just testing that benefit you by making a computer do the heavy lifting for you.

And, if you have interesting snippets that you’d like to share, go right ahead.

Advertisements

One thought on “Automating the “10 Fast Fingers” Typing Test with Watir

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s