如何调试等待异步Angular任务的超时?未能在角度页面上找到元素

S.H*_*ton 7 javascript jasmine protractor angular

编辑:请注意,我在@ ernst-zwingli的帮助下找到了我的问题的根源,所以如果你有同样的错误,他的一个明确的修复可能会帮助你.我的问题是Protractor本身的一个已知问题,如果您认为这可能是您,我已经扩展了我的步骤,以便在原始问题之后找出问题的根源.


我试图在使用angular-cli构建的Angular2(只是Angular)应用程序中使用Protractor.

我的问题:Angular应用页面上的元素在browser.waitForAngularEnabled默认设置时没有被找到true (如'我相信我在一个有角度的页面上,并希望Protractor做它的魔力').如果我设置它们,它们被发现就好browser.waitForAngularEnabledfalse (如'我不是在一个有角度的页面上并想自己处理它,坐下量角器').如何在我的Angular页面上找出导致这种情况的原因?

我有一个带有非Angular Auth0登录页面的产品,可以访问以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@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();
Run Code Online (Sandbox Code Playgroud)

如果我取消注释该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)
Run Code Online (Sandbox Code Playgroud)

我引用了常见问题:https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular 我让我的开发人员声明他们不使用$ timeout(他们使用(编辑:NOT $ interval)Observable Interval非常感谢你,他们不确定$ http.

我找到了关于调试量角器Angular sync问题的规范方法的解决方案:调试Protractor-Angular同步问题的规范方法 但是我不确定该解决方案是否无法修改dev代码以运行程序化跟踪器.(编辑:我从未弄清楚如何让这个工作)

我还发现这是关于你在每次测试之前添加的一个很长的超时,但是我认为这是不必要的开销,这会使你的整体测试执行时间超过应该没有理解问题的根本原因: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
Run Code Online (Sandbox Code Playgroud)

我认为isZoneStable就够了,但对于Protractor来说显然不是这样.然后看着Macrotasks是真的,我不得不查看Macrotask到底是什么:hasPendingMacrotasks和hasPendingMicrotasks检查了什么?.

macrotask可以是:

即setTimeout,setInterval,setImmediate

因此,@ ernst-zwingli关于区间引起区域问题的记录被记住了,最后点击了一些东西.
关于区域不稳定的第一个github问题

另一个github问题抱怨使用browser.driver与browser.waitForAngularEnabled一起完成工作的必要性.显然这是预期的行为,它导致我发出#3349

问题#3349 - 我的问题的实际根本原因.我的开发人员不会主动跳进和离开可观察区域.即使这些可观察者只有一个用户.由于他们此时生活在角度区域,他们是一个长期运行的"Macrotask",Protractor等待无限.

我不能用这些包装器重写代码,因为我目前还没有足够的Angular来安全地完成它,而且我们目前正在朝着11月的最后期限前进.我想我暂时不得不处理使用browser.driver的问题,希望以后我不能修复它.希望我的RCA对你有所帮助.

Ern*_*gli 7

在下文中,我列出了一组潜在的原因以及修复/解​​决它们的可能性.

AngularJS和Angular(2)如何工作/我可以在浏览器开发模式中检查什么

我不能在他的博客中解释它和安德烈阿吉巴洛夫,所以检查出来(也为开发人员).

基本上,您可以检查您的Chrome Dev中的Protractor所需的对象.

for AngularJS 检查对象window.angular是否已正确定义,即查找window.angular.version并尝试window.angular.getTestability使用Root元素

for Angular(2) 检查对象是否window.getAllAngularRootElements返回至少一个值.

根元素(AngularJS)

可能你的Angular App就像Body一样包裹在Body中<div ng-app="my-app">.在这种情况下,你必须调整你的rootElement: body内部config.ts.检查这个答案细节.

角(2)

如果你正在使用Angular(又名Angular2),那么就会引入ngZone.在这种情况下,您还config.js应该包含:

exports.config = {
    framework: 'jasmine',
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['spec.js'],
    useAllAngular2AppRoots: true,
    // rootElement: 'root-element'
};
Run Code Online (Sandbox Code Playgroud)

在浏览器中检查window.getAllAngularRootElementsconf.js中的附加行是关于此的.

如果可以,也许可以利用多个区域的优势.创建第二个区域,配置rootElement: 'root-element' 为仅关注一个区域,然后将一些异步任务移动到另一个区域,直到找到哪个(哪些)任务导致超时.将这些任务(如果可能)保留在单独的区域中,因此Protractor会忽略这些任务.

如果使用$interval其他持久的异步任务,则可能存在问题,因为区域.应该在区域外开始重复或持久的任务,然后将其移入区域,因为量角器可能会遇到超时.开发人员可以使用一种解决方法,以避免Protractor出现这些问题. 在这里阅读所有相关内容

browser.driver. - 旁边的评论

browser.driver.get()好像ignoreSynchronization = true,因为你直接分配浏览器驱动程序,你绕过了量角器的同步逻辑.在这里的答案中阅读更多相关信息.

希望我能给你更多的意见,你可以解决你的问题.请让我知道结果.


归档时间:

查看次数:

2286 次

最近记录:

8 年,1 月 前