【问题标题】:Angular Protractor: Execute Scripts in Browser ContextAngular Protractor:在浏览器上下文中执行脚本
【发布时间】:2016-05-13 22:26:33
【问题描述】:

在我的 index.html 中,我明确地说:

window.myAppInstance = new MyApp.myAppConstructor();

在我的 todo-spec.js 中,我有以下设置:

describe('my web page', function() {
  it('should have a "myAppInstance" object on the window', function() {
    browser.get('https://my.web.page.com');

    function myTest() {
      return Object.keys(window.myAppInstance).sort();
    };

    var p = browser.driver.executeScript(myTest);
     p.then(function(ret) {
        console.log("yay");
        console.log(ret);
     }, function() {
        console.log("error");
        console.log(arguments);
     });
  });
});

但是量角器没有找到我的应用程序。相反,它会找到 null 或 undefined:

error
{ '0':
   { [WebDriverError: unknown error: Cannot convert undefined or null to object
 (Session info: chrome=50.0.2661.102)
... and more garbage

但是从 Chrome 的控制台,我可以运行

window.myAppInstance

很好,它可以正确打印出对象。

如何从量角器测试中访问此窗口对象?

编辑 1:更明确地了解构造函数。

编辑 2:在我的应用程序中,我使用 angular 的 manual bootstrapping。经过进一步调查,我可以将此行添加到我的测试中:

<snip>
  browser.get('https://my.web.page.com');
  **browser.pause()**
<snip>

我现在的步骤: 1) 按 F12 调出 Chrome 的开发者工具 2)查看控制台。注意一个错误。我的应用程序崩溃了。 3)手动点击浏览器上的刷新按钮。 4)注意应用程序如何刷新并且一切都加载得很漂亮。不解地挠挠我的头。得出的结论是,它可能是以某种方式以编程方式启动页面

browser.get('https://my.web.page.com'); 

与打开浏览器并输入该 URL 来破坏它有很大不同。

我现在想知道,使用量角器运行测试会导致我的应用失败怎么办?

【问题讨论】:

    标签: javascript angularjs selenium selenium-webdriver protractor


    【解决方案1】:

    可能存在时间问题 - 该值尚不可用,您可能需要等待:

    function waitForKey() {
      return browser.executeScript("return window.myAppXXXXXXXXXXXXX");
    }
    
    browser.wait(waitForKey, 5000);
    var p = browser.executeScript(myTest);
    // ...
    

    【讨论】:

    • 感谢您的回答!听起来很有希望。等我回到电脑前我会试试看。
    • 有趣的是你应该使用动词'promise'。
    【解决方案2】:

    您的对象myAppXXXXXXXXXXXXX 在执行myTest 时可能尚未实例化。如果是这种情况,那么一种解决方案是调用executeAsyncScript,而不是在对象存在时返回对象的键:

    function myTest(callback){
      if (window.myAppXXXXXXXXXXXXX) {
        callback(Object.keys(window.myAppXXXXXXXXXXXXX).sort());
      } else {
        setTimeout(myTest, 30);  // try again in 30ms
      }
    }
    
    browser.driver.executeAsyncScript(myTest)
      .then(function(ret) {
        console.log("yay");
        console.log(ret);
      }, function() {
        console.log("error");
        console.log(arguments);
      });
    

    【讨论】:

    • 感谢您的回答!听起来很有希望。等我回到电脑前我会试试看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多