Watir-Webdriver-Performance gem released

Today I added a simple watir-webdriver-performance gem whose purpose is to collect performance metrics specified for web applications to access timing information related to navigation and elements.

User latency is an important quality benchmark for Web Applications. While JavaScript-based mechanisms can provide comprehensive instrumentation for user latency measurements within an application, in many cases, they are unable to provide a complete end-to-end latency picture.

To address the need for complete information on user experience, this document introduces the PerformanceTiming interfaces. This interface allows JavaScript mechanisms to provide complete client-side latency measurements within applications. With the proposed interface, the previous example can be modified to measure a user’s perceived page load time.

Read More

Watirgrid Support for Watir-Webdriver

With the growing popularity of watir-webdriver I’ve decided to uplift watirgrid to support this newer approach. For installation instructions of Watir on top of WebDriver there is a good post on the topic by Željko Filipin. There’s also some musings on the ‘why’ of watir-webdriver at Alister Scott’s blog, WatirMelon.

If you want to get on with the business of parallel testing across a grid network with Watir or Watir-WebDriver then have a look at the following code:

Firstly, update your gem installation if it’s been a while ;)

gem update --system

Now install the prerelease version of Watirgrid

gem install watirgrid --prerelease

At this stage I haven’t updated my gemspec with dependencies, so you’ll also need uuid

gem install uuid

To test a simple 1 controller / 1 provider scenario using IE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
require 'rubygems'
require 'watirgrid'
 
# setup a controller on port 12351 for your new grid
controller = Controller.new(
        :ring_server_port => 12351,
  :loglevel => Logger::ERROR)
controller.start
 
# add a provider to your grid
# :browser_type => 'webdriver' if using webdriver or
# :browser_type => 'ie' if using watir...
provider = Provider.new(
        :ring_server_port => 12351,
  :loglevel => Logger::ERROR, :browser_type => 'webdriver')
provider.start
 
# connect to the grid and take all providers from it (this time only one)
grid = Watir::Grid.new(:ring_server_port => 12351,
    :ring_server_host => '127.0.0.1')
 
grid.start(:take_all => true)
 
# for each provider on the grid, launch a new thread to start multiple browsers
threads = []
grid.browsers.each do |browser|
        threads << Thread.new do
                p browser[:hostname]
                p browser[:architecture]
                p browser[:browser_type]
                # in this case we are starting a new IE browser
                b = browser[:object].new_browser(:ie)
                b.goto("http://www.google.com")
                b.text_field(:name, 'q').set("watirgrid")
                b.button(:name, "btnI").click
        end
end
threads.each {|thread| thread.join}

There’s some more examples of using watirgrid with watir-webdriver here.

Read More

Authenticating Proxy with Webdriver and Watir

A question came up on stack overflow about how to route Watir through an authenticating proxy within your script.

The problem here is that you cannot auto authenticate to a proxy server using Chrome –proxy-server=my.proxy.com:3128 or using Firefox.

Chrome will always prompt you for a user name and password on an authenticating proxy when it starts up (via Webdriver or manually). Firefox will not prompt (when launched via WebDriver) and will silently fail.

I *almost* got this to work by modifying headers on the fly with a Firefox add on (Modify Headers). Basic authentication is just base-64 encoded so you can force each request to authorize itself by modifying the Proxy-Authorization request header e.g.:
Proxy-Authorization Basic asHJksaKHs87akhkjah7

However whilst this works for manually launched instances of Firefox, Webdriver launched instances would complain that the add on is not compatible with FF3.6.3 and so once again would fail. The other problem with this approach is that I couldn’t find a similar plugin for Chrome.

Eventually I gave in and went with a slightly more complicated workaround. That is, chaining an authenticated proxy (with squid) running on localhost with a cache_peer relationship to the authenticated proxy running out there on the ‘tubes’. I had thought about using Webrick as a proxy (as per previous posts) but lack of SSL support is a gotcha for me. Squid seemed most appropriate in this case:

To install squid from source:
cd /opt/src
sudo curl -O http://www.squid-cache.org/Versions/v2/2.7/squid-2.7.STABLE9.tar.gz
sudo tar xjf squid-2.7.STABLE9.tar.gz
cd squid-2.7.STABLE9
# I wanted SSL support for this
./configure --enable-ssl
make
sudo make install

Edit the squid.conf (location is normally /etc/squid/squid.conf on linux):
sudo vim /usr/local/squid/etc/squid.conf

# Don't want to run squid as root
# TAG: cache_effective_user
cache_effective_user nobody
# TAG: cache_effective_group
cache_effective_group wheel
# Point this proxy to a peer cache, and provide the logon credentials
# TAG: cache_peer
cache_peer proxy.altentee.com parent 3128 0 default no-query login=username:mypassword
never_direct allow all
# Allow access from my local private network
# TAG: cache_peer
acl localnet src 10.0.0.0/0

Save changes and change ownership as appropriate:
sudo chown -R nobody:wheel /usr/local/squid

Initialize the cache and startup squid:
sudo /usr/local/squid/sbin/squid -z
sudo /usr/local/squid/sbin/squid -D

Now you can configure firefox (using -ProfileManager) or chrome (using –proxy-server=127.0.0.1) to point to your local proxy server. This proxy will then authenticate on your behalf and peer all requests via the original parent.

A little long winded but achieves the outcome. Added side benefit is you’ve now got a local proxy (with access logs) that you can start doing interesting things with in your automation / performance tests like modifying headers and so forth.

Hope this helps!

Read More