编辑:请注意,我在@ernst-zwingli 的帮助下找到了问题的根源,因此如果您遇到相同的错误,他的一个修复程序可能会对您有所帮助。我的问题是量角器本身的一个已知问题,如果您认为这可能是您,我已经扩展了我的步骤以在我最初提出问题后查明问题的根源。
我正在尝试在使用 angular-cli 构建的 Angular2(只是 Angular)应用程序中使用 Protractor。
我的问题:在 Angular 应用程序页面上的元素browser.waitForAngularEnabled
处于默认设置时无法找到true
(如“我相信我在一个 Angular 页面上并且希望 Protractor 能够发挥它的魔力”)。如果我设置browser.waitForAngularEnabled
为false
(如“我不在一个有角度的页面上并且想自己处理这个问题,请坐 Protractor”),它们会被发现很好。我如何在我的绝对 Angular 页面上追踪导致这种情况的原因?
我有一个带有非 Angular Auth0 登录页面的产品,该页面可以访问用 Angular 编写的产品的其余部分(准确地说是Angular 4.3.2)。我已经成功遍历了非 Angular 登录页面的登录。我翻转了waitForAngularEnabled
switch 以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@example.com");
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 我的开发人员说他们不使用 $timeout(他们使用(编辑:NOT $interval)Observable Interval 非常感谢您)而且他们不确定 $http。
我找到了有关调试量角器角度同步问题的规范方法的解决方案:调试量角器到角度同步问题的规范方法, 但我不确定该解决方案是否可以在无法修改开发代码以运行编程跟踪器的情况下工作。(编辑:我从来没有想过如何让它工作)
我还发现这是关于您在每次测试之前添加的长时间超时,但我觉得这是不必要的开销,它使您的整体测试执行时间比不了解问题的根本原因要长: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 建议的列表开始:
对于 Angular(2) 检查对象 window.getAllAngularRootElements 是否至少返回一个值。
它至少返回了一个值,所以我继续前进。
useAllAngular2AppRoots: 真,
我试过了,但仍然遇到了异步超时。
如果使用 $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 就足够了,但对于量角器显然不是这样。然后看着 Macrotasks 是真的,我不得不查一下 Macrotask 到底是什么:hasPendingMacrotasks 和 hasPendingMicrotasks 检查什么?.
宏任务可以是:
即 setTimeout, setInterval, setImmediate
因此,@ernst-zwingli 关于间隔在区域中引起问题的注释被记住了,并且最终点击了一些东西。
第一个 github 问题,关于区域不稳定
另一个 github 问题抱怨使用 browser.driver 与 browser.waitForAngularEnabled 一起完成工作的必要性。显然这是预期的行为,它导致我发出 #3349
问题 #3349 - 我的问题的实际根本原因。我的开发人员不会主动进出可观察对象的区域。即使这些 observables 只有一个订阅者。由于此时它们处于角度区域,因此它们是 Protractor 无限等待的长时间运行的“宏任务”。
我无法用这些包装器重写代码,因为我目前对 Angular 还不够精通,无法安全地做到这一点,而且我们目前正朝着 11 月的最后期限迈进。我想我暂时不得不处理使用 browser.driver 并希望我以后不能修复它。希望我的 RCA 对您有所帮助。