编辑:请注意,在 @ernst-zwingli 的帮助下,我找到了问题的根源,因此,如果您遇到相同的错误,他指出的修复之一可能会帮助您。我的问题是量角器本身的一个已知问题,如果您认为这可能是您,我已经扩展了我的步骤,以在我最初的问题之后查明问题的根源。
我正在尝试在使用 angular-cli 构建的 Angular2(只是 Angular)应用程序中使用量角器。
我的问题:在以下情况下找不到 Angular 应用程序页面上的元素browser.waitForAngularEnabled
是它的默认设置true
(如“我相信我在一个有角度的页面上并且希望量角器发挥它的魔力”)。如果我设置的话,他们会被发现很好browser.waitForAngularEnabled
to false
(如“我不在有角度的页面上,想自己处理这个问题,请坐下量角器”)。如何在我的绝对 Angular 页面上找出导致此问题的原因?
我有一个带有非 Angular Auth0 登录页面的产品,该页面可以访问该产品的其余部分is用 Angular 编写(准确地说是 Angular 4.3.2)。我已经成功遍历非Angular登录页面登录。我翻转了waitForAngularEnabled
切换到false
以方便非 Angular 登录。我把它转回true
在单击提交按钮后,我期望加载初始登陆页面(Angular)。代码如下:
browser.waitForAngularEnabled(false);
browser.driver.get('https://dashboard.net/projects');
browser.driver.sleep(10000);
browser.driver.findElement(By.css("[type='email']"));
browser.driver.findElement(By.css("[type='email']")).sendKeys("[email protected] /cdn-cgi/l/email-protection");
browser.driver.findElement(By.css(".auth0-label-submit")).click();
browser.driver.findElement(By.id("passwordInput")).sendKeys("password");
browser.driver.findElement(By.id("submitButton")).click();
browser.driver.sleep(5000); // needed if not waiting for Angular
//browser.waitForAngularEnabled(true); // Back to Protractor land we go
let elementToFind = element(by.className("header-text"));
elementToFind.isDisplayed().then(function() {grabTheDarnLocalStorage()});
expect(elementToFind.isDisplayed()).toBeTruthy();
如果我取消注释browser.waitForAngularEnabled(true);
行来表明我回到了 Angular 代码中,我得到的错误跟踪如下:
Failed: Timed out waiting for asynchronous Angular tasks to finish after 30 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
While waiting for element with locator - Locator: By(css selector, .header-text)
ScriptTimeoutError: asynchronous script timeout: result was not received in 30 seconds
(Session info: chrome=61.0.3163.100)
(Driver info: chromedriver=2.32.498550 (9dec58e66c31bcc53a9ce3c7226f0c1c5810906a),platform=Windows NT 10.0.14393 x86_64)
at WebDriverError (C:\Users\c-shouston\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:27:5)
at ScriptTimeoutError (C:\Users\c-shouston\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:203:5)
at Object.checkLegacyResponse (C:\Users\c-shouston\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:505:15)
at parseHttpResponse (C:\Users\c-shouston\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\http.js:509:13)
at doSend.then.response (C:\Users\c-shouston\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\http.js:440:13)
at process._tickCallback (internal/process/next_tick.js:109:7)
From: Task: Protractor.waitForAngular() - Locator: By(css selector, .header-text)
我参考了常见问题解答:https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular我让我的开发人员声明他们不使用 $timeout (他们使用(编辑:不是 $interval)可观察间隔,非常感谢)并且他们不确定 $http。
我找到了关于调试量角器角度同步问题的规范方法的解决方案:调试量角器到角度同步问题的规范方法 https://stackoverflow.com/questions/42865376/canonical-way-to-debug-protractor-to-angular-sync-issues但我不确定该解决方案在无法修改开发代码以运行编程跟踪器的情况下是否有效。(编辑:我从来没有弄清楚如何让它发挥作用)
我还发现您在每次测试之前添加了很长的超时,但我认为这是不必要的开销,使您的整体测试执行时间比应有的时间长,而不了解问题的根本原因:https://stackoverflow.com/a/37217167/2718402 https://stackoverflow.com/a/37217167/2718402 (编辑:是的,这是一个坏主意,会给您的测试增加不必要的时间,请不要这样做)
令人沮丧的是,这似乎是一种常见现象,而且似乎没有关于如何处理它的简化文档。使用非 Angular 页面登录只是为了转换到 Angular 页面。量角器无法正确拾取有角度的页面。我在网上找到的所有示例都是一些代码,我没有参考它们应该在我的整体测试框架中的位置。我会想要一个完整的例子,说明有人测试非 Angular 登录,转换到完全 Angular 网站,并带有设置配置和真实世界的测试用例。(编辑:这仍然是事实,但我无法自己制作一个,因为我的应用程序处于糟糕的灰色区域,请注意下面我的 RCA 以了解更多详细信息。)
我只希望能够登录,然后成功转换到我的 Angular 页面,并能够依靠 Protractor 来处理我的 Angular 页面。我需要知道要寻找什么,这可能是一个长时间运行的异步进程(我具体可以在 Chrome 开发工具中检查什么?)。我很想了解 Protractor 需要什么作为默认值才能成功地使用我的应用程序/网站的 Angular 部分(除了存在之外还有什么东西吗?<app-root _nghost-c0="" ng-version="4.3.2">
在 HTML 中?)。在这份工作之前,我从事 Java 工作,所以所有这些异步性和 Angular 对我来说都是新的,所以我知道我错过了经验丰富的 Javascript 开发人员所知道的已知事物。
我的解决方案/根本原因分析
从@ernst-zwingli 建议的列表开始:
for Angular(2) 检查对象 window.getAllAngularRootElements 是否至少返回一个值。
它至少返回一个值,所以我继续前进。
useAllAngular2AppRoots:true,
我尝试了这个,但仍然遇到异步超时。
如果使用 $interval 或其他持久的异步任务,由于区域的原因,可能会出现问题
之前 @ernst-zwingli 也提到过查看可测试性方法,只不过这是旧方法。通过研究和测试我发现window
对象还有一个getAllAngularTestabilities
方法。这导致了一个有趣的兔子洞。 Chrome 控制台的输出示例(将window.getAllAngularTestabilities()
在Chrome控制台窗口中,查看结果列表)如下:
t:
_callbacks:...,
_didWork:true,
_isZoneStable: true (this looks promising, but why isn't Protractor working then?!?)
_ngZone:
hasPendingMacrotasks: true,
hasPendingMicrotasks: false,
isStable: true
我认为 isZoneStable 就足够了,但对于 Protractor 来说显然不是这样。然后看看 Macrotasks 是否正确,我必须查一下 Macrotask 到底是什么:hasPendingMacrotasks 和 hasPendingMicrotasks 检查什么? https://stackoverflow.com/questions/43480595/what-does-haspendingmacrotasks-and-haspendingmicrotasks-check-for.
宏任务可以是:
即setTimeout、setInterval、setImmediate
因此,@ernst-zwingli 关于间隔在区域中引起问题的注释被记住,并且最终得到了解决。
第一个 github 问题,关于区域不稳定 https://github.com/angular/angular/issues/12372
另一个 github 问题 https://github.com/angular/protractor/issues/3611抱怨必须使用 browser.driver 和 browser.waitForAngularEnabled 来完成任务。显然这是预期的行为,它导致我发出问题#3349
问题#3349 https://github.com/angular/protractor/issues/3349- 我的问题的实际根本原因。我的开发人员不会主动跳入或跳出可观察值周围的区域。尽管这些可观察量只有一个订阅者。由于此时它们位于角区域,因此它们是 Protractor 无限等待的长时间运行的“宏任务”。
我无法使用这些包装器重写代码,因为我目前对 Angular 还不够熟悉,无法安全地完成此操作,而且我们目前正朝着 11 月份的截止日期赶去。我想我暂时必须处理使用 browser.driver 的问题,并希望以后不能修复它。希望我的 RCA 对您有帮助。