禁用JavaScript的Selenium WebDriver测试

禁用JavaScript的Selenium WebDriver测试,javascript,firefox,testing,selenium-webdriver,protractor,Javascript,Firefox,Testing,Selenium Webdriver,Protractor,我们的一个内部应用程序(用angularjs编写)在浏览器中禁用javascript(使用)时会出现一个特殊的错误框,类似于stackoverflow上的错误框: 我正试图为它编写一个自动测试,但遇到了困难 我们使用的是量角器,但我很确定这与此无关。以下是量角器配置文件: 'use strict'; var helper = require('./helper.js'); exports.config = { seleniumAddress: 'http://localhost:4

我们的一个内部应用程序(用angularjs编写)在浏览器中禁用javascript(使用)时会出现一个特殊的错误框,类似于stackoverflow上的错误框:

我正试图为它编写一个自动测试,但遇到了困难

我们使用的是量角器,但我很确定这与此无关。以下是量角器配置文件:

'use strict';

var helper = require('./helper.js');

exports.config = {
    seleniumAddress: 'http://localhost:4444/wd/hub',
    baseUrl: 'http://localhost:9001',

    capabilities: helper.getFirefoxProfile(),

    framework: 'jasmine',
    allScriptsTimeout: 20000,

    jasmineNodeOpts: {
        showColors: true,
        isVerbose: true,
        includeStackTrace: true
    }
};
其中
helper.js
是:

var q = require('q');
var FirefoxProfile = require('firefox-profile');

exports.getFirefoxProfile = function() {
    var deferred = q.defer();

    var firefoxProfile = new FirefoxProfile();
    firefoxProfile.setPreference("javascript.enabled", false);
    firefoxProfile.encoded(function(encodedProfile) {
        var capabilities = {
            'browserName': 'firefox',
            'firefox_profile' : encodedProfile,
            'specs': [
                '*.spec.js'
            ]
        };
        deferred.resolve(capabilities);
    });

    return deferred.promise;
};
如您所见,我们正在将
javascript.enabled
firefox首选项设置为
false
,如果您在firefox中手动打开
about:config
,将其更改为
false
,您将看到
noscript
部分的内容

但是,当我运行测试时,我得到以下错误:

引发异常org.openqa.selenium.WebDriverException:正在等待 evaluate.js加载失败

这是你的电话号码

仅供参考,使用selenium
2.44.0
和firefox
33.1.1

据我所知(在提出的几点帮助下),禁用javascript会杀死javascript Web驱动程序本身。这是真的吗?如果是,我的选择或解决办法是什么


注:

  • 对于chrome,在过去可以通过禁用javascript,但是

  • 这导致了一个解决方案0-将chrome降级到支持命令行标志的旧版本-这将是一个未经测试的计划B

  • 设置
    javascript.enabled=false
    firefox首选项可用于python selenium绑定:


我愿意接受任何建议,并可以向您提供任何其他信息。

根据您的stacktrace,您似乎正在使用ff 33.1和selenium 2.43.1,因此它不支持。请将selenium版本升级到2.44,以便在ff-33上进行测试

据我所知(在这里提出的几点帮助下),禁用javascript正在扼杀javascript Web驱动程序本身。这是真的吗

对。请注意,WebDriver本身作为Firefox扩展运行,因此其代码不受禁用JavaScript的影响。但是,错误消息表示Selenium正试图在网页上下文中运行某些代码。为此,它将
标记注入网页,并将
evaluate.js
的内容放入其中。然后它等待脚本设置一个标志,表明它已经准备好了——这当然是永远不会发生的,因为脚本没有在该网页中运行

如果是,我的选择或解决办法是什么

重要的问题是Selenium试图在那里运行什么。您的回溯仅表明某些代码正在调用
executeScript()
executeAsyncScript()
。我在Selenium代码库中找不到任何对这两个方法的隐含调用(至少在与Firefox web驱动程序相关的任何文件中都找不到)。鉴于Selenium是开源的,您应该能够调试它并在
org.openqa.Selenium.remote.RemoteWebDriver.executeScript()
org.openqa.Selenium.remote.RemoteWebDriver.executeAsyncScript()
上添加一个断点,这样您将实际看到脚本在那里执行。或者,您也可以重新编译
RemoteWebDriver.java
,并使其产生调试输出

看看这些方法是如何实现的,可能还有另一种方法:告诉Selenium JavaScript被禁用。这应该通过以下功能实现:

'javascriptEnabled': false,

根据文档,这种能力只对HTMLUnitDriver起作用,但是Seleo会一直考虑它,从源代码中指定Firefox似乎是可能的。使用此功能,任何在网页上执行脚本的调用都将提前失败。

找到了替代解决方案/解决方法-

它对每个域禁用javascript,并且默认情况下,它对除白名单中列出的站点以外的所有站点都禁用javascript。这使得webdriver可以毫无问题地运行,打开一个网页,然后扩展就禁用了这个特定站点的javascript,我看到了
noscript
标记的内容

以下是量角器配置:

'use strict';

var helper = require('./disabledJavascript.helper.js');

exports.config = {
    seleniumAddress: 'http://localhost:4444/wd/hub',

    capabilities: helper.getFirefoxProfile(),
    chromeOnly: false,

    specs: [
        'disabledJavascript.spec.js'
    ],

    framework: 'jasmine',

    allScriptsTimeout: 20000,

    baseUrl: 'http://localhost:9001',

    jasmineNodeOpts: {
        showColors: true,
        isVerbose: true,
        includeStackTrace: true
    }
};
其中
disabledJavascript.helper.js
包含:

'use strict';

var q = require('q');
var FirefoxProfile = require('firefox-profile');

exports.getFirefoxProfile = function() {
    var deferred = q.defer();
    var firefoxProfile = new FirefoxProfile();

    firefoxProfile.addExtension('./test/e2e/disabledJavascript/noscript.xpi', function () {
        firefoxProfile.encoded(function(encodedProfile) {
            var capabilities = {
                'firefox_profile' : encodedProfile,
                'browserName': 'firefox'
            };
            deferred.resolve(capabilities);
        });
    });

    return deferred.promise;
};

其中
noscript.xpi
是下载的“noscript”扩展。

下面是实际发生的情况

事实证明,在探索了
量角器
和selenium js webdriver的源代码之后,关键问题不在于js webdriver或
量角器
,而在于我编写测试的方式

有一个名为的设置,默认情况下为
false

  /**
   * If true, Protractor will not attempt to synchronize with the page before
   * performing actions. This can be harmful because Protractor will not wait
   * until $timeouts and $http calls have been processed, which can cause
   * tests to become flaky. This should be used only when necessary, such as
   * when a page continuously polls an API using $timeout.
   *
   * @type {boolean}
   */
  this.ignoreSynchronization = false;
我没有将其设置为
true
,这使得
量角器
尝试与页面同步并执行客户端脚本,客户端脚本负责

解决方案非常简单,我无法想象-只需将
ignoreSynchronization
设置为
true
即可解决问题:

'use strict';

require('jasmine-expect');

describe('Disabled Javascript', function () {
    beforeEach(function () {
        browser.ignoreSynchronization = true;
        browser.get('index.html');
    });

    it('should show disabled js', function () {
        var element = browser.findElement(by.tagName('noscript'));
        expect(element.getText()).toEqual('Please enable Javascript and try again.');
    });
});

希望这会对将来的人有所帮助。

这可能是个问题,但已将selenium更新为
2.44.0
-问题仍然存在(更新了回溯)。谢谢。这个解决方案似乎否定了测试的意义,因为安装NoScript扩展与禁用JavaScript并不相同。行为上的差异确实相当显著。您没有回复我的建议,我猜
javascriptEnabled
功能不起作用?@WladimirPalant我同意禁用javascript的方式可能有所不同,你可能认为这是一个解决方案,而不是一个真正的解决方案——尽管没有其他选项起作用——我没有运气设置
javascriptEnabled
首选项,也没有使用
——禁用javascript
chrome选项和旧的chrome浏览器版本。谢谢。好吧,你仍然可以调试Selenium——这不是我能为你做的;)@我害怕瓦拉迪米尔帕兰特
'use strict';

require('jasmine-expect');

describe('Disabled Javascript', function () {
    beforeEach(function () {
        browser.ignoreSynchronization = true;
        browser.get('index.html');
    });

    it('should show disabled js', function () {
        var element = browser.findElement(by.tagName('noscript'));
        expect(element.getText()).toEqual('Please enable Javascript and try again.');
    });
});