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.
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:
- Firefox by default ignores all events sent to it when its window is not focused. The Selenium Webdriver does crazy things Show archive.org snapshot to overcome this.
- Magic solutions for parallel focus issues that don't require hardening of your test suites, but which we shied away from when we realized the work involved:
- Use a separate VNC session per test process (will require more work on geordi Show archive.org snapshot )
- Use a true headless browser like capybara-webkit Show archive.org snapshot (hasn't worked reliably in our tests)