Read more

How to solve Selenium focus issues

Henning Koch
November 23, 2012Software engineer at makandra GmbH

Most focus issues go away when testing with headless Chrome.

Selenium cannot reliably control a browser when its window is not in focus, or when you accidentally interact with the browser frame. This will result in flickering tests, which are "randomly" red and green. In fact, this behavior is not random at all and completely depends on whether or not the browser window had focus at the time.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

This card will give you a better understanding of Selenium focus issues, and what you can do to get your test suite stable again.

Preventing accidental interaction with the Selenium window

When Selenium windows steal your focus, you will sometimes accidentally focus/blur/type into a Selenium window. Obviously this impacts the outcome of your test. It also makes you very unproductive when you want to keep working while you wait for your tests to complete.

The solution is to run Selenium inside a VNC session so the Selenium-controlled browser doesn't pop up over your main work area.

Understanding issues with concurrent Selenium tests

When you run Selenium tests in parallel (which you want), other more subtle issues will infest your test suite. Even though you no longer accidentally interact with Selenium browsers, browsers from different test processes will pop up in your VNC session and steal each other's focus.

While this will not impact simple interactions such as clicking, it will impact focus or blur events in subtle ways. E.g. clicking on a text field will only trigger a focus event when that window is currently in focus. This impacts, for instance, the popular date picker from jQuery UI, which opens itself when you focus the bound text area.

All great solutions to concurrent focus issues require significantly more work (see Appendix below). What you can do right now is to harden your test suite so it is not sensitive to whether the browser window is focused or not. Such techniques are described below.

If you have trouble reproducing the problem, see How to provoke Selenium focus issues in parallel test processes.

Firefox: Dealing with lost focus/blur events

This is a problem when using Selenium with Firefox. We recommend using ChromeDriver for your Selenium tests.

When you want to focus or blur something, do not rely on the events happening as a side effect of something else (e.g. focus happening when clicking, or blur happening when something else is focused).

Instead you should explicitly trigger those events via Javascript. Examples for Capybara:

page.execute_script("$('#foo').focus()")
page.execute_script("$('#foo').blur()")

If this doesn't help, a workaround is to create a customevent and use it like this:

  $(function() {
    $('#element').on({
      blur: function() { $(this).trigger("customevent") },
      customevent: doStuff,
    });
  });

On how to use this in tests, see Testing focus/blur events with Cucumber.

Selecting elements with the :focus selector

jQuery gives you a :focus selector Show archive.org snapshot which you can use to select focused elements:

$('input:focus')

Unfortunately this selector only matches focused elements when the containing window has focus. This means that code relying on this selector can also break with multiple concurrent test processes.

That issue has probably ruined the life of Matthew O'Riordan, who has spent more time than you ever will in order to produce a fix. You should probably use this solution Show archive.org snapshot .

Note that I haven't tested Matthew's fix myself, it's just something I came across during my research.

Tag scenarios that should not run in parallel

parallel_tests lets you disable parallel run for tagged scenarios. Since this will slow down your test suite considerable, you should only this as a last resort and prefer to fix your tests instead.

Why you haven't encountered these issues before

You probably have this issue in your test suite right now, but never noticed. The issue only occurs when two focus-sensitive tests run at the same time. As your test suite accumulates a larger number of Selenium tests (required for today's increasingly Javascript-heavy interfaces), tests will start to flicker more.

Appendix

Things I hope you never need to know, which I wanted to write down for my own reference:

Posted by Henning Koch to makandra dev (2012-11-23 11:31)