目前我正在编写一个小的测试项目,我使用了页面对象模型和 Playwright。我的页面带有返回页面本身或另一个页面的方法。这使我更容易编写测试。然而,当我使用异步方法时,我得到了很多等待。
var homePage = new HomePage(page);
await (await (await (await homePage.goto())
.DoSomething())
.NavigateToNextPage())
.ValidateResult();
我想知道是否有办法避免排队等候。或者我不应该默认使用异步,因为我的测试本质上是连续的。
我找到了 Promise.all() 但是在这种情况下似乎不起作用,因为我正在链接这些方法。
我会从 API 中删除链接并将调用分成多行:
const homePage = new HomePage(page);
await homePage.goto();
await homePage.doSomething();
await homePage.navigateToNextPage();
await homePage.validateResult();
做一个 Playwright 定位器式的链只有当你有一系列的调用被惰性评估并以某种动作结束时才有效。使用 Playwright 文档中的示例:
await page
.getByRole('listitem')
.filter({ hasText: /Product 2/ })
.getByRole('button', { name: 'Add to cart' })
.click();
在这里,唯一的动作是
click()
。其他一切都可以链接在它之前,因为它正在选择和过滤以准备点击。 Playwight 可以返回可同步链接的对象,直到最后的 click()
返回一个评估链并不允许进一步链接的承诺。
但在您的情况下,每一行似乎都是一个应该能够自行执行的操作,并且不涉及任何可选的准备步骤。剧作家不支持动作链接,比如
await page.goto().click().waitForNavigation().click();
虽然可能,但实现一个收益可疑的异步链 API 需要大量工程工作。
如果我在此答案顶部显示的模式看起来太“无聊”,请考虑 Puppeteer 的 API(以及大部分 Playwright,定位器除外)基本上 100% 这种风格。读、写、用都是正常的,不足为奇。避免耍小聪明就好了。可以说 Playwright 的惰性定位器比 Puppeteer 的非链式 API 更聪明,因此更难推理。
请注意,我使用的是
camelCase
而不是 PascalCase
和 const
而不是 var
.
如果你真的想要这样做,最简单的方法是选择一个函数作为动作:
class HomePage {
constructor() {
this.actions = [];
}
doSomething() {
this.actions.push(page.doSomething());
return this;
}
navigateToNextPage() {
this.actions.push(page.navigateToNextPage());
return this;
}
validateResult() {
this.actions.push(page.validateResult());
return this;
}
async run() {
for (const action of this.actions) {
await action;
}
this.actions = [];
}
}
const homePage = new HomePage();
await homePage
.doSomething()
.navigateToNextPage()
.validateResult()
.exec();
或者您可以让
validateResult
兑现承诺而不是 exec
,具体取决于您的用例。