有没有办法通过 Javascript 检测我是否在 Selenium Webdriver 页面中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3614472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 01:44:19  来源:igfitidea点击:

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

javascriptseleniumcucumberwebdrivercapybara

提问by Lee Iverson

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.

我想在我的测试中抑制 TinyMCE 的初始化,如果 Javascript 可以检测到我在 Selenium 自动化页面内运行,那么可以轻松地做到这一点。

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?

那么,是否有一些 JS 代码可以用来检测 Selenium 驱动程序?或者,如何扩展 userAgent 字符串以包含我可以从 JS 检测到的模式?

If it really matters, I'm running this through cucumber and capybara on Mac OS X.

如果真的很重要,我会在 Mac OS X 上通过黄瓜和水豚运行它。

回答by Louis

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 webdriverattribute on the htmlelement but apparently not in other browsers. Maybe some day this will be theway 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...

据我所知,Selenium 没有提供跨浏览器的方法来检测它是否正在驱动浏览器。在 FF 中,webdriverwebdriverhtml元素上设置属性,但在其他浏览器中显然没有。也许有一天,这将是方式来检测浏览器是由硒驱动,但不是现在。我刚刚用 FF 和 Chrome 对其进行了测试:该属性存在于 FF 中,但不存在于 Chrome 中。所以就是这样...

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.

有时我需要做一些类似于你想要实现的事情。我使用 Selenium 运行大型测试套件。这些套件在多个版本的 Chrome、Firefox 和 IE 上运行,在 Linux、Windows 和 OS X 上运行,其中一些测试在 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 beforerunning a test. The two ways I've used this method:

我使用的方法依赖于executeScript. (我正在链接到 Java 文档,但此方法适用于 Selenium 可用的所有平台。)我使用它运行测试之前在浏览器端运行代码。我使用这种方法的两种方式:

  1. Set a variable browser-side on windowthat my browser code checks. So I could for instance set window.running_test_suite_for_foobar = trueand 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 onbeforeunloadmodule 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 couldhandle 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 minutesto run. So I have a method that I call to turn it off.

  1. window我的浏览器代码检查上设置一个变量浏览器端。所以我可以例如设置window.running_test_suite_for_foobar = true然后让代码检查。存在冲突的风险,但如果谨慎使用变量名称,则风险很小。

  2. 我使用的另一种方法是设计我的代码,使其具有配置选项或未记录的方法,可以调用这些方法为测试环境正确设置它或完全禁用它。例如,我有一个onbeforeunload模块可以防止用户离开带有未保存修改的页面。在测试中,通常将其打开是没有用的。Selenium可以处理弹出窗口,但是当您远程运行测试时,每一点交互都会产生巨大的成本。然后通过数十个测试进行多次测试,然后您就有了一个测试套件,它可以轻松地多花几分钟来运行。所以我有一个方法可以调用来关闭它。

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 FF and Chrome in other answers here completelyreplace the user agent string (contrarily to what some have said). To appendto 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 detectionrather than browser detection, there remain some caseswhere the only reasonable way to know that the code has to handle a special case is by knowing which versionof the browser it is running in. When the problem is a bugin the browser, there is no featureto 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 getBoundingClientRectwhere 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.)

  1. 执行此操作的方法因浏览器而异。您的代码必须检查要运行的浏览器,然后根据浏览器执行正确的操作。

  2. 此处其他答案中为 FF 和 Chrome 显示的方法完全替换了用户代理字符串(与某些人所说的相反)。要附加到它,您必须知道未修改的字符串是什么。这会因浏览器和版本而异。我猜你可以有一个库存用户代理字符串表来修改。这不是我想要维护的东西。或者您可以启动浏览器两次:一次查询库存用户代理,一次使用修改后的用户代理运行测试。

    并且您不能偷懒使用正确的用户代理字符串。虽然浏览器代码确实应该进行特征检测而不是浏览器检测,但在某些情况下,知道代码必须处理特殊情况的唯一合理方法是了解它正在运行的浏览器版本。问题是浏览器中的错误,没有要检查的功能。检查错误是否发生可能成本太高或不可能可靠地完成。所以代码必须检查用户代理字符串。您的代码可能不必这样做,但第三方代码可以。(例如,我遇到了一个问题getBoundingClientRect坐标通常在 IE 中不正确,但仅在一个版本的 Chrome 中。在运行时检查错误成本太高,我不能确定字体或显示设置的更改不会产生误报。)

回答by jarib

Since the question mentions Capybara, here's the equivalent code in Ruby:

由于问题提到了 Capybara,这里是 Ruby 中的等效代码:

profile = Selenium::WebDriver::Firefox::Profile.new
profile['general.useragent.override'] = "my ua string"

driver = Selenium::WebDriver.for :firefox, :profile => profile

回答by Onkar_M18

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:-

是的,如果有人使用 firefox 驱动程序进行 selenium 自动化,您可以这样做,为了检测 selenium 驱动程序,您必须在客户端放置以下代码:-

$(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.

对于 Chrome 和 IE 特定的 selenium 浏览器,它不起作用。

回答by Rhett Sutphin

Here's how to do it with Capybara and Chromedriver:

以下是使用 Capybara 和 Chromedriver 执行此操作的方法:

Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, browser: :chrome,
    args: ['--user-agent="Chrome under Selenium for Capybara"'] )
end

回答by Quinn Wynn

You can try this answerto disable the navigator.webdrivervariable, but notice that it's no longer from ChromeDriver 79.0.3945.16 and above.

您可以尝试使用此答案来禁用该navigator.webdriver变量,但请注意它不再来自 ChromeDriver 79.0.3945.16 及更高版本。