开发者

Is there a way to detect that I'm in a Selenium Webdriver page from JavaScript?

开发者_JAVA百科

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 JavaScript code that I can use to detect the Selenium driver? Alternatively, how can I extend the user agent string to include a pattern that I can detect from JavaScript?

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 Firefox, 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 Firefox and Chrome: the attribute was present in Firefox, 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 Internet Explorer, 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 documentation, but this method exists for all platforms 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:

  1. 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.

  2. 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

  1. 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.

  2. The methods shown for Firefox 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 Internet Explorer, 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


Yes, you can do it if someone is using the Firefox driver for Selenium automation, for detection of Selenium driver you have to put in the following code at your client side:

$(document).ready(function() {
    try{
        if(window.document.documentElement.getAttribute("webdriver"))
            alert("Caught in the first case: Selenium Webdriver is banned!!!");
    }
    catch(Exception)
    {
    }

    try{
       if(navigator.webdriver)
           alert("Caught in the second case: Selenium Webdriver is banned!!!");
    }
    catch(Exception)
    {
    }
});

For Chrome and Internet Explorer specific, the Selenium browser it is not working.


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


You can try this answer to disable the navigator.webdriver variable, but notice that it's no longer from ChromeDriver 79.0.3945.16 and above.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜