How to Simulate Slow Connections
With Selenium you have the luxury of cross browser testing. But what happens when you also need to test how your application behaves on a slow connection?
With the help of a proxy server like BrowserMob Proxy we can simulate bandwidth limitations and run our tests to see if they fall down. In order to do this we'll also need to adjust our Selenium's default timeout.
A Brief Primer on BrowserMob Proxy
BrowserMob Proxy is a server which sits between your browser and the application you're testing. You connect to it by configuring a browser profile to pass through it. As listed on the BrowserMob Proxy GitHub page, here are some of the benefits it offers:
- blacklisting and whitelisting certain URL patterns
- simulating various bandwidth and latency
- remapping DNS lookups
- flushing DNS caching
- controlling DNS and request timeouts
- automatic BASIC authorization
NOTE: You can also capture HTTP status codes with it as well. See tip 17 for details on how to do that.
Let's continue with an example.
First we'll need to download BrowserMob Proxy from here.
Then we can wire up our test script to pull in our requisite libraries (e.g.,
selenium-webdriver to drive the browser,
rspec/expectations and it's matchers for our assertion, and
browsermob/proxy to control the proxy server).
# filename: bandwidth_limit.rb
Now let's configure the proxy server and bind it to a Selenium browser profile.
server = BrowserMob::Proxy::Server.new('./browsermob-proxy-2.1.0-beta-3/bin/browsermob-proxy')
@proxy = server.create_proxy
profile = Selenium::WebDriver::Firefox::Profile.new
profile.proxy = @proxy.selenium_proxy
Now we can create
run methods to handle our test configuration.
@driver = Selenium::WebDriver.for :firefox, profile: configure_proxy
@driver.manage.timeouts.page_load = 300 # seconds
@proxy.limit(upstream_kbps: 20, downstream_kbps: 30)
setup we set the default timeout for Selenium to 5 minutes (e.g.
300 seconds) and specify an upload limit of
20 kilobits per second and a download limit of
30 kilobits per second (which is similar to a dial-up connection).
Now let's write our test. A simple page load and copy assertion will suffice (to make sure the page actually loaded).
expect(@driver.find_element(class: 'heading').text).to eql('Welcome to the Internet')
If you save this file and run it (e.g.,
ruby bandwidth_limit.rb from the command-line) here is what will happen:
- Proxy server starts
- Proxy server session created
- Browser opens (connecting to the proxy server session with a large default timeout)
- Proxy bandwidth constraints applied
- Visit the page (which loads slowly)
- Page eventually loads
- Grab the text from the page heading
- Perform an assertion against the text to make sure it loaded
- Browser closes
- Proxy session closes
It may not be clear in
browsermob-proxy-rb what options and functionality are available since the library is light on documentation. But the code is easy to read and has good comments. It's worth looking at the client class to see what's available.
Alternatively, you can BrowserMob Proxy through it's Rest API. You can find out more about that on the BrowserMob Proxy GitHub page.
About The Author
Dave Haeffner is the original writer of Elemental Selenium -- a free, once weekly Selenium tip newsletter that's read by thousands of testing professionals. He also created and maintains the-internet (an open-source web app that's perfect for writing automated tests against).
Dave has helped numerous companies successfully implement automated acceptance testing; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is also an active member of the Selenium project and has spoken at numerous conferences and meetups around the world about automated acceptance testing.