angularjs - 如何使用 Protractor 捕获 AngularJS 错误

标签 angularjs protractor angularjs-e2e

我在 E2E 使用 Protractor 测试 AngularJS 应用程序时遇到了一些问题。总结一下:我有以下规范,第一步总是因 btstrpd 错误而失败。 (页面是自动引导的,我们使用 AngularJS v1.3.0 和 Protractor v2.1.0。)

describe('Protractor Demo App', function() {

    it('should have a title', function() {
        browser.get('http://myapp.abc.de/ext/#/login');
        expect(browser.getTitle()).toEqual('My App');
    });

    it('should do other stuff', function() {
        // ...
    });

});

错误:
1) Protractor Demo App should have a title
 Message:
 UnknownError: unknown error: [ng:btstrpd] http://errors.angularjs.org/1.3.15/ng/btstrpd?p0=document
  (Session info: chrome=43.0.2357.132)
  (Driver info: chromedriver=2.15.322448 (52179c1b310fec1797c81ea9a20326839860b7d3),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 9 milliseconds

(Full description here)

Since I don't seem to find a solution to prevent this error and the remaining test steps run without any problems, my approach would be to simply ignore the error. However I don't want the test case to fail due to it. This brings me to my question: How can I catch this error so that the test won't fail? A plain try-catch around the two statements in the step does not the trick and since I don't have any promises here I also cannot do the typical promise error handling as one would manually handle e.g. a NoSuchElementError.

Edit - Error in webdriver console:

12:06:18.975 INFO - Executing: [new session: Capabilities [{count=1, browserName
=chrome}]])
12:06:18.995 INFO - Creating a new session for Capabilities [{count=1, browserNa
me=chrome}]
Starting ChromeDriver 2.15.322448 (52179c1b310fec1797c81ea9a20326839860b7d3) on
port 23267
Only local connections are allowed.
12:06:21.248 INFO - Done: [new session: Capabilities [{count=1, browserName=chro
me}]]
12:06:21.271 INFO - Executing: [set script timeoutt: 11000])
12:06:21.281 INFO - Done: [set script timeoutt: 11000]
12:06:21.390 INFO - Executing: [get: data:text/html,<html></html>])
12:06:21.405 INFO - Done: [get: data:text/html,<html></html>]
12:06:21.425 INFO - Executing: [execute script: window.name = "NG_DEFER_BOOTSTRA
P!" + window.name;window.location.replace("http://myapp.abc.de/ext/#/login");, [
]])
12:06:23.440 INFO - Done: [execute script: window.name = "NG_DEFER_BOOTSTRAP!" +
 window.name;window.location.replace("http://myapp.abc.de/ext/#/login");, []]
12:06:23.458 INFO - Executing: [execute script: return window.location.href;, []
])
12:06:23.468 INFO - Done: [execute script: return window.location.href;, []]
12:06:23.489 INFO - Executing: [execute async script: try { return (function (at
tempts, asyncCallback) {
  var callback = function(args) {
    setTimeout(function() {
      asyncCallback(args);
    }, 0);
  };
  var check = function(n) {
    try {
      if (window.angular && window.angular.resumeBootstrap) {
        callback([true, null]);
      } else if (n < 1) {
        if (window.angular) {
          callback([false, 'angular never provided resumeBootstrap']);
        } else {
          callback([false, 'retries looking for angular exceeded']);
        }
      } else {
        window.setTimeout(function() {check(n - 1);}, 1000);
      }
    } catch (e) {
      callback([false, e]);
    }
  };
  check(attempts);
}).apply(this, arguments); }
catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [10]])
12:06:25.603 INFO - Done: [execute async script: try { return (function (attempt
s, asyncCallback) {
  var callback = function(args) {
    setTimeout(function() {
      asyncCallback(args);
    }, 0);
  };
  var check = function(n) {
    try {
      if (window.angular && window.angular.resumeBootstrap) {
        callback([true, null]);
      } else if (n < 1) {
        if (window.angular) {
          callback([false, 'angular never provided resumeBootstrap']);
        } else {
          callback([false, 'retries looking for angular exceeded']);
        }
      } else {
        window.setTimeout(function() {check(n - 1);}, 1000);
      }
    } catch (e) {
      callback([false, e]);
    }
  };
  check(attempts);
}).apply(this, arguments); }
catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [10]]
12:06:25.633 INFO - Executing: [execute script: return (function () {
    angular.module('protractorBaseModule_', []).
        config(['$compileProvider', function($compileProvider) {
          if ($compileProvider.debugInfoEnabled) {
            $compileProvider.debugInfoEnabled(true);
          }
        }]);
  }).apply(null, arguments);, []])
12:06:25.643 INFO - Done: [execute script: return (function () {
    angular.module('protractorBaseModule_', []).
        config(['$compileProvider', function($compileProvider) {
          if ($compileProvider.debugInfoEnabled) {
            $compileProvider.debugInfoEnabled(true);
          }
        }]);
  }).apply(null, arguments);, []]
12:06:25.663 INFO - Executing: [execute script: angular.resumeBootstrap(argument
s[0]);, [[protractorBaseModule_]]])
12:06:26.093 WARN - Exception thrown
org.openqa.selenium.WebDriverException: unknown error: [ng:btstrpd] http://error
s.angularjs.org/1.3.15/ng/btstrpd?p0=document
  (Session info: chrome=43.0.2357.134)
  (Driver info: chromedriver=2.15.322448 (52179c1b310fec1797c81ea9a20326839860b7
d3),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any
 stacktrace information)
Command duration or timeout: 10 milliseconds
Build info: version: '2.45.0', revision: '5017cb8', time: '2015-02-26 23:59:50'
System info: host: 'xxxxx', ip: 'xxx.xxx.xx.x', os.name: 'Windows 7', os.arch: '
amd64', os.version: '6.1', java.version: '1.8.0_45'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEn
abled=false, chrome={userDataDir=C:\Users\abcdefg\AppData\Local\Temp\scoped_dir1
1436_18156}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true,
version=43.0.2357.134, platform=XP, browserConnectionEnabled=false, nativeEvents
=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true,
 browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsE
nabled=true}]
Session ID: 0c39849d960cccef7ec7036b8414c9fb
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou
rce)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.
java:204)
        at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHa
ndler.java:156)
        at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.ja
va:599)
        at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDri
ver.java:508)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.openqa.selenium.support.events.EventFiringWebDriver$2.invoke(Even
tFiringWebDriver.java:101)
        at com.sun.proxy.$Proxy1.executeScript(Unknown Source)
        at org.openqa.selenium.support.events.EventFiringWebDriver.executeScript
(EventFiringWebDriver.java:213)
        at org.openqa.selenium.remote.server.handler.ExecuteScript.call(ExecuteS
cript.java:53)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at org.openqa.selenium.remote.server.DefaultSession$1.run(DefaultSession
.java:168)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
12:06:26.103 WARN - Exception: unknown error: [ng:btstrpd] http://errors.angular
js.org/1.3.15/ng/btstrpd?p0=document
  (Session info: chrome=43.0.2357.134)
  (Driver info: chromedriver=2.15.322448 (52179c1b310fec1797c81ea9a20326839860b7
d3),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any
 stacktrace information)
Command duration or timeout: 10 milliseconds
Build info: version: '2.45.0', revision: '5017cb8', time: '2015-02-26 23:59:50'
System info: host: 'xxxx', ip: 'xxx.xxx.xx.x', os.name: 'Windows 7', os.arch: '
amd64', os.version: '6.1', java.version: '1.8.0_45'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEn
abled=false, chrome={userDataDir=C:\Users\abcdefg\AppData\Local\Temp\scoped_dir1
1436_18156}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true,
version=43.0.2357.134, platform=XP, browserConnectionEnabled=false, nativeEvents
=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true,
 browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsE
nabled=true}]
Session ID: 0c39849d960cccef7ec7036b8414c9fb
12:06:26.203 INFO - Executing: [delete session: f947352d-3b40-4b1b-a46a-9d4ffe32
8b76])
12:06:27.417 INFO - Done: [delete session: f947352d-3b40-4b1b-a46a-9d4ffe328b76]

最佳答案

在您的代码中,我会放置一个 WaitforAngular() 以确保同步附加到 Angular & Protractor。请参阅下文以供引用:

it('should have a title', function() {
    browser.get('http://myapp.abc.de/ext/#/login');
    browser.waitForAngular();
    expect(browser.getTitle()).toEqual('My App');
});

然后如果它不起作用,我会使用 browser.pause();命令。这将中断您使用命令的 Protractor 的执行。从那里您可以打开 Chrome 调试控制台以查看究竟发生了什么。

您还可以使用 REPL Debug模式,这是一种非常方便的方式来检查您的元素是否出现在页面上以及您是否使用了正确的选择器。

有关使用 Protractor 调试的更多信息,请参阅以下链接:https://angular.github.io/protractor/#/debugging

关于angularjs - 如何使用 Protractor 捕获 AngularJS 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31537684/

相关文章:

node.js - 将 Protractor E2E 测试与 Node 重放连接起来

javascript - 如何在 angular.js 中调用 ng-title 属性上的作用域函数

angularjs - 如何在 angular.js 中使用嵌套的 ng-repeat 动态打印表行中的数组对象?

javascript - 无法使用 AngularJS 在编号 "appState"上创建属性 "200"

javascript - 如何在带有 Chrome 的 MAC 上使用 Protractor 进行复制和粘贴?

javascript - 使用 Protractor 检查复选框

selenium-webdriver - 从 Protractor 读取浏览器日志在第二次调用后没有产生任何结果

javascript - 是否可以将函数结果与 angularJS 绑定(bind)?

javascript - Protractor (3.0.0)/Webdriver (2.53.0) 切换选项卡错误

javascript - 在 Protractor 中断言数组列表中值的部分关键字