I'd like to suppress the initialization of TinyMCE inside my tests and can do this easily if the Javascript can detect that I'm running inside a Selenium-automated page.
So, is there some JS code that I can use to detect the Selenium driver? Alternatively, how can I extend the userAgent string to include a pattern that I can detect from JS?
If it really matters, I'm running this through cucumber and capybara on Mac OS X.
As far as I know there is no cross-browser method that Selenium provides to detect that it is driving the browser. In FF, webdriver sets the webdriver
attribute on the html
element but apparently not in other browsers. Maybe some day this will be the way to detect that the browser is being driven by Selenium but not for now. I've just tested it with FF and Chrome: the attribute was present in FF but not Chrome. So that's that...
A Method for Any Browser, Any OS, Any Test Runner
Sometimes I need to do something like what you are trying to achieve. I run large test suites with Selenium. These suites run on multiple versions Chrome, Firefox and IE, on Linux, Windows and OS X, with some of the tests being run remotely on Sauce Labs.
The methods I've used rely on executeScript
. (I'm linking to the Java doc but this method exists for all platform that Selenium is available for.) I use it to run code on the browser side before running a test. The two ways I've used this method:
Set a variable browser-side on window
that my browser code checks. So I could for instance set window.running_test_suite_for_foobar = true
and then have code check that. There's a risk of a clash but if the variable name is used carefully the risk is minimal.
Another method I've used is to design my code so that it has configuration options or undocumented methods that can be called to set it up properly for a test environment or to disable it completely. For instance I have an onbeforeunload
module that prevents users from moving away from a page with unsaved modifications. In testing, it is not useful to have this generally turned on. Selenium could handle the popup but when you run tests remotely every bit of interaction has a significant cost. Then multiple by dozens of tests and then you have a test suite that can easily take a few more minutes to run. So I have a method that I call to turn it off.
The Problems with Changing the User Agent
The methods to do it differ from browser to browser. Your code has to check which browser you want to run and then perform the right action depending on the browser.
The methods shown for FF and Chrome in other answers here completely replace the user agent string (contrarily to what some have said). To append to it, you'd have to know what the unmodified string would be. This changes from browser to browser and version to version. I guess you could have a table of stock user agent strings to modify. This is not something I'd want to have to maintain. Or you could start the browser twice: once to query the stock user agent and once to run the test with the modified user agent.
And you can't be lazy about using the right user agent string. While it is true that browser code should do feature detection rather than browser detection, there remain some cases where the only reasonable way to know that the code has to handle a special case is by knowing which version of the browser it is running in. When the problem is a bug in the browser, there is no feature to check for. Checking that the bug is happening may be too costly or impossible to do reliably. So the code has to check the user agent string. Your code may not have to do this but third party code may. (For instance, I've run into an issue that happens with getBoundingClientRect
where the coordinates would be incorrect generally in IE but only in one version of Chrome. It is too costly to check for the bug at run-time and I can't be sure that a change of fonts or display settings would not yield false negatives.)
Since the question mentions Capybara, here's the equivalent code in Ruby:
profile = Selenium::WebDriver::Firefox::Profile.new
profile['general.useragent.override'] = "my ua string"
driver = Selenium::WebDriver.for :firefox, :profile => profile
Since webbriver automates normal browsers (just like iMacros), your website can not detect it directly.
You can easily append a string to the useragent:
This is easy with the Firefox Driver:
FirefoxProfile profile = new FirefoxProfile();
profile.addAdditionalPreference("general.useragent.override", "some UA string");
WebDriver driver = new FirefoxDriver(profile);
Here's how to do it with Capybara and Chromedriver:
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome,
args: ['--user-agent="Chrome under Selenium for Capybara"'] )
end
Yes you can do it if someone is using firefox driver for selenium automation, for detection of selenium driver you have to put following code at your client side:-
$(document).ready(function() {
try{
if(window.document.documentElement.getAttribute("webdriver"))
alert("Caught in 1st case :- Selenium Webdriver is banned!!!");
}
catch(Exception){}
try{
if(navigator.webdriver)
alert("Caught in 2nd case :- Selenium Webdriver is banned!!!");
}
catch(Exception){}
});
For Chrome and IE specific selenium browser it is not working.