将一个 angular 应用程序导航到另一个 angular 应用程序时量角器超时错误
Protractor timeout error while navigating one angular application to another angular application
我有两个 angular 申请
待登录
对于业务逻辑
我尝试使用量角器对这些应用程序进行自动化测试。但是在登录(第一个应用程序)后从第二个应用程序获取元素详细信息时遇到问题。
文件是
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 实现。所以我不想通过禁用 angular 来失去任何量角器功能。那么如何用量角器测试两个angular应用程序呢?
版本:
- 保护器:7.0.0
- Angular: 7.3.9
正如我在评论中提到的,您的问题是因为您的 angular 应用程序不断在后台轮询某些内容,即使在视觉上看起来页面已准备就绪。您可以在 protractors page and here 中阅读更多相关信息。不幸的是,我只做测试自动化,从来没有尝试解决应用程序方面的问题。然而,无论如何,我总是倾向于禁用量角器等待angular,所以它从来没有真正困扰我
我知道你已经在另一个post看到我的答案了,我只是想在这里背诵一些供大家参考
- 查看您的页面是否 Angular:在浏览器和 'console' 选项卡 运行 命令中打开开发控制台
getAllAngularTestabilities()
如果输出是getAllAngularTestabilities is not defined
,那么你的页面不是angular,转到步骤#3禁用内置等待
- 如果您的页面是 angular,现在庆祝还为时过早,因为 Protractor 可能仍然无法正常工作。 运行 控制台中的这些命令来检查它是否
getAllAngularTestabilities()[0]._ngZone.hasPendingMacrotasks
getAllAngularTestabilities()[0]._ngZone.hasPendingMicrotasks
如果其中任何一项 return true
(如果有微任务或宏任务待处理),则转到最后一步。如果都是false
,恭喜你可以使用内置量角器等待angular。但是,如果您像我一样不喜欢它,请阅读最后一步以了解如何禁用它
- 运行 上面提到的命令。但!它 return 是一个需要处理的承诺,最好使用
await
关键字
await browser.waitForAngularEnabled(false)
完整答案here
我发现根本原因是 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" alt="Random 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);
});
我有两个 angular 申请
待登录
对于业务逻辑
我尝试使用量角器对这些应用程序进行自动化测试。但是在登录(第一个应用程序)后从第二个应用程序获取元素详细信息时遇到问题。
文件是
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 实现。所以我不想通过禁用 angular 来失去任何量角器功能。那么如何用量角器测试两个angular应用程序呢?
版本:
- 保护器:7.0.0
- Angular: 7.3.9
正如我在评论中提到的,您的问题是因为您的 angular 应用程序不断在后台轮询某些内容,即使在视觉上看起来页面已准备就绪。您可以在 protractors page and here 中阅读更多相关信息。不幸的是,我只做测试自动化,从来没有尝试解决应用程序方面的问题。然而,无论如何,我总是倾向于禁用量角器等待angular,所以它从来没有真正困扰我
我知道你已经在另一个post看到我的答案了,我只是想在这里背诵一些供大家参考
- 查看您的页面是否 Angular:在浏览器和 'console' 选项卡 运行 命令中打开开发控制台
getAllAngularTestabilities()
如果输出是getAllAngularTestabilities is not defined
,那么你的页面不是angular,转到步骤#3禁用内置等待
- 如果您的页面是 angular,现在庆祝还为时过早,因为 Protractor 可能仍然无法正常工作。 运行 控制台中的这些命令来检查它是否
getAllAngularTestabilities()[0]._ngZone.hasPendingMacrotasks
getAllAngularTestabilities()[0]._ngZone.hasPendingMicrotasks
如果其中任何一项 return true
(如果有微任务或宏任务待处理),则转到最后一步。如果都是false
,恭喜你可以使用内置量角器等待angular。但是,如果您像我一样不喜欢它,请阅读最后一步以了解如何禁用它
- 运行 上面提到的命令。但!它 return 是一个需要处理的承诺,最好使用
await
关键字
await browser.waitForAngularEnabled(false)
完整答案here
我发现根本原因是 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" alt="Random 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);
});