Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mattheworiordan
Created August 23, 2011 22:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattheworiordan/1166816 to your computer and use it in GitHub Desktop.
Save mattheworiordan/1166816 to your computer and use it in GitHub Desktop.
:focus pseudo selector fix for Capybara-webkit and or Selenium with Cucumber
Feature: Capybara Webkit and Selenium :focus test
In order to show that Capybara Webkit and Selenium do not allow an element to maintain focus
I created this feature
Which anyone can try
@selenium
Scenario: Run demo page with Selenium
When I am on the capybara demo page
And I fill in "inpt" with "Test snapshot"
Then I should see a successful result
And the input field should have focus
@javascript
Scenario: Run demo page with Capybara Webkit
When I am on the capybara demo page
And I fill in "inpt" with "Test snapshot"
Then I should see a successful result
And the input field should have focus
<!DOCTYPE html>
<html>
<head>
<title>Capybara Webkit and Selenium :focus Test</title>
<!-- Jquery.focus.test-fix.js must be loaded before JQuery -->
<script src="/javascripts/jquery.focus.test-fix.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
<input type="text" id="inpt"/>
<p id="log" style="font-family: Arial; font-size: 13px;">Log:</p>
<script>
$(function() {
$('#inpt').focus();
console.log("This message was fired using console.log");
$('#log').append($('#inpt').is(':focus') ? 'focus success' : 'focus failure');
});
</script>
</body>
</html>
Then /I should see a successful result/ do
# pause to be extra sure we're not failing for stupid reasons
sleep 1
page.evaluate_script("$('#log').text();").should match(/success/)
end
Then /the input field should have focus/ do
page.evaluate_script("$('#inpt').is(':focus')").should be_true
page.evaluate_script("$(':focus')[0] === $('#inpt')[0]").should be_true
end
/**
* JQuery tries to use native CSS selectors instead of the Sizzle selector
* engine for performance reasons.
*
* This causes problems when trying to test intefaces using the
* :focus pseudo selector as unless the web page and browser window
* has the focus, all elements are considered to be without focus.
* Checking for :focus in Selenium or Capybara tests therefore fail if
* using JQuery or Sizzle.
*
* Sizzle will however return true for a :focus element even if the
* window itself has lost focus if we force it not use the native selector functions
* This script forces Sizzle to use its own engine over native selectors.
*
* This file MUST be included before JQuery or Sizzle is loaded
*
* Refer to https://github.com/mattheworiordan/jquery-focus-selenium-webkit-fix for more info
*
**/
/* replace the focus selector with our own version */
jQuery.find.selectors.filters.focus = function(elem) {
var doc = elem.ownerDocument;
return elem === doc.activeElement && !!(elem.type || elem.href);
}
# standard code before
when /the capybara demo page/
'/focus_test.html'
# standard code after
@mattheworiordan
Copy link
Author

This Gist is somewhat outdated, although I just updated jquery.focus.test-fix.js with the new code that will work on JQuery 1.8 as the old Gist only worked with JQuery 1.7.

Please refer to https://github.com/mattheworiordan/jquery-focus-selenium-webkit-fix for a more complete breakdown of the issue, and the fix for JQuery :focus selection in integration environments such as Selenium and Capybara-Webkit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment