将一个角度应用程序导航到另一个角度应用程序时量角器超时错误

Posted

技术标签:

【中文标题】将一个角度应用程序导航到另一个角度应用程序时量角器超时错误【英文标题】:Protractor timeout error while navigating one angular application to another angular application 【发布时间】:2021-05-29 13:37:02 【问题描述】:

我有两个角度应用程序

    用于登录

    业务逻辑

我尝试使用量角器开始对这些应用程序进行自动化测试。但是在登录后(第一个应用程序)从第二个应用程序获取元素详细信息时面临问题。

文件是

specs: [
        'login.js',// 1st application 
        'navigatetoRegisterReport.js',// page loaded by menu navigation from 1st application
        'requestCreation.js',// 2nd application page loaded by `browser.get(2nd app Url)`
        'navigateToDcOtherInvoice.js'// navigation to another screen in my 2nd application 
    ],

我已经通过以下方式完成了登录逻辑,并且运行良好

async first() 
        await browser.driver.get(browser.baseUrl).then(async () => 
            await browser.wait(ExpectedConditions.elementToBeClickable(element(by.linkText("Other User"))), 30000);
            await element(by.linkText("Other User")).click().then(() => 
                browser.wait(ExpectedConditions.elementToBeClickable(element(by.css('#username'))), 30000);
                element(by.css('#username')).sendKeys('XXXXX').then(() => 
                    browser.wait(ExpectedConditions.elementToBeClickable(element(by.id("password-field"))), 30000);
                    element(by.id("password-field")).sendKeys('XXXXX').then(() => 
                        browser.wait(ExpectedConditions.elementToBeClickable(element(by.id('login-submit'))), 30000);
                        element(by.id('login-submit')).click().then(async () => 
                            const dashboardImage = await element(by.css("app-dashboard .dashboard-image"));
                            browser.wait(ExpectedConditions.elementToBeClickable(dashboardImage), 30000);
                            dashboardImage.isDisplayed().then((value) => 
                                if (value == true) 
                                    console.log('dashborad image is displayed')
                                 else 
                                    console.log('dashborad image is not identified')
                                
                            ).catch(error => console.error('caught error while login', error));;
                        ).catch(error => console.error('caught error 7', error));;
                    ).catch(error => console.error('caught error on password', error));;
                ).catch(error => console.error('caught error on user name', error));;
            ).catch(error => console.error('caught error tab click', error));;
        ).catch(error => console.error('caught error on load', error));
    

但是在从第二个应用程序获取元素值时,我遇到了错误

async requestCreation(date: string, report: string) 

        await browser.get('https://2ndapplication/xxx/xxxx').then(async () => 
            var selectDate = element(by.xpath("//input[@id='icon-right']"));
            var reportType = element(by.xpath("//input[@placeholder='Report Type']"));
            browser.wait(ExpectedConditions.elementToBeClickable(selectDate), 30000);
            selectDate.clear();
            selectDate.sendKeys(date)
            browser.wait(ExpectedConditions.elementToBeClickable(reportType), 30000);
            reportType.click();
            reportType.clear();
            reportType.sendKeys(report)
        ).catch(error => console.error('caught error on requestCreation', error));
    

错误:

ScriptTimeoutError: script timeout
  (Session info: chrome=88.0.4324.190)
  (Driver info: chromedriver=88.0.4324.96 (68dba2d8a0b149a1d3afac56fa74648032bcf46b-refs/branch-heads/4324@#1784),platform=Windows NT 10.0.18363 x86_64)
    at Object.checkLegacyResponse (E:\updatedCode\backup\node_modules\selenium-webdriver\lib\error.js:546:15)
    at parseHttpResponse (E:\updatedCode\backup\node_modules\selenium-webdriver\lib\http.js:509:13)
    at doSend.then.response (E:\updatedCode\backup\node_modules\selenium-webdriver\lib\http.js:441:30)
    at process._tickCallback (internal/process/next_tick.js:68:7)
From: Task: Protractor.waitForAngular() **- Locator: By(xpath, //input[@id='icon-right'])

我可以在浏览器中看到该元素并且它是可见的。但是量角器抛出错误,因为它不存在。我知道如果我为 WaitForAngularDisabled(false) 提供 false 就会解决。但是这两个应用程序都仅由 Angular 实现。所以我不想通过禁用角度来失去任何量角器功能。那么如何通过量角器测试两个角度应用呢?

版本:

保护器:7.0.0 角度:7.3.9

【问题讨论】:

你为什么要用这么多的链接把你的代码弄得这么乱!!!!你不能直接使用等待而不是链接。有了这样的承诺链,代码真的是一个令人头疼的维护问题 ***.com/a/66072132/6793637 @PDHide 感谢您的回复。实际上它适用于我的第一个应用程序,问题是我的第二个应用程序抛出无法找到元素错误。 它肯定会起作用,但问题是当某些东西中断并且您必须调试时,更改链接并使其等待 并非所有角度应用程序都可以使用默认的 waitForAngularEnabled(true) 量角器进行测试。在这里查看如何检查您的应用程序是否可以运行***.com/a/66111219/9150146 让我知道您的每个页面上的 getAllAngularTestabilities 返回什么 【参考方案1】:

正如我在 cmets 中提到的,您的问题是因为您的 Angular 应用程序不断地在后台轮询某些内容,即使在视觉上看起来页面已经准备好。您可以在protractors page 和here 中了解更多信息。不幸的是,我只做测试自动化,从未尝试在应用程序端解决问题。但是,无论如何,我总是倾向于禁用量角器的等待角度,所以它从来没有真正困扰过我


我知道你已经在另一篇文章中看到了我的答案,我只是想在这里背诵一些以供大家参考

    确定您的页面是否为 Angular:在浏览器中打开开发控制台并在“控制台”选项卡中运行命令
getAllAngularTestabilities()

如果输出是getAllAngularTestabilities is not defined,那么你的页面不是有角度的,去第3步禁用内置等待

    如果您的页面有棱角,现在庆祝还为时过早,因为 Protractor 可能仍然无法在本地运行。在控制台中运行这些命令以检查是否正常
getAllAngularTestabilities()[0]._ngZone.hasPendingMacrotasks
getAllAngularTestabilities()[0]._ngZone.hasPendingMicrotasks

如果其中任何一个返回true(如果有微任务或宏任务待处理),则转到最后一步。如果都是false,恭喜,你可以使用内置量角器的等待角。但是,如果您不喜欢它,我不喜欢它,请阅读最后一步以了解如何禁用它

    运行上述命令。但!它返回一个promise,需要处理,最好使用await关键字
await browser.waitForAngularEnabled(false)

完整答案here

【讨论】:

我在应用程序端发现了问题,我们在所有组件中调用了一个通用包。在公共服务内部,我们已经在全局范围内定义了三个 BehaviorSubject 属性,所以每当我在组件构造函数中调用公共服务类时,都会出现错误。如果我从构造函数中删除了该公共服务,它将正常工作。现在我的问题是如何在 Angular 之外编写 BehaviorSubject 属性声明? 太关键了 :( 找到根本原因: 应用洞察是铜矿。删除应用程序洞察宏任务中的加载事件后为假。但是如何在实际应用中处理而不是删除呢?有什么想法吗?【参考方案2】:

我发现根本原因是Application insight is a culprit,所以我将代码移到了 angular 之外。现在量角器工作得很好。

this.ngZone.runOutsideAngular(() => 
      this.appInsightSvc.onPageLoad();
    );

而ngb-carousel 也抛出了同样的错误,所以我也修复了同样的错误

在轮播控件中添加[interval]='0'

<ngb-carousel *ngIf="images" [interval]='0' style="position: fixed;" [showNavigationArrows]="showNavigationArrows"
     [showNavigationIndicators]="showNavigationIndicators">
     <ng-template ngbSlide *ngFor="let image of images">
          <img [src]="image" class="img-slide" >
     </ng-template>
</ngb-carousel>

在 componenet.ts 中添加此代码

import  NgbCarousel  from '@ng-bootstrap/ng-bootstrap';

 @ViewChild(NgbCarousel)
 private carousel: NgbCarousel;

在构造函数中定义 NgZone

private ngZone: NgZone

在 ngOninit 钩子中添加以下行

this.ngZone.runOutsideAngular(() => 
            setInterval(() => 
                this.ngZone.run(() => 
                    this.carousel.next();
                );
            , 3000);
        );

【讨论】:

以上是关于将一个角度应用程序导航到另一个角度应用程序时量角器超时错误的主要内容,如果未能解决你的问题,请参考以下文章

角度路由更改后量角器找不到元素

在没有导航或路由的角度 2 类型脚本中,将数据一个组件传递到另一个组件的所有可能性是啥?

量角器:失败:超时等待异步角度任务在11秒后完成

如何不忘记再次将量角器转换为角度同步?

量角器:从标准角度GRID中获取数据,在向左或向右滚动时重绘

需要专业建议,关于非角度应用的量角器中的显式等待