Playwright.js 找不到元素错误处理

Playwright.js element not found error handling

我正在将一系列测试从 Selenium + Jest 转换为 Playwright + Jest,其中一个区别是对于元素查找,如果找不到元素,await page.$(".whatever") 不会拒绝.

我正在做很多元素查找,因为我们已经为很多组件构建了页面对象模型。

我的问题是,我需要手动添加一些错误处理,还是我遗漏了什么? Jest 会告诉我哪个测试失败了,但是没有堆栈跟踪,所以很难找出哪里出了问题。另外,这是个好方法吗?

// some-test.js
it("should display the event title", async () => {
  let eventTitle = await this.bookingPage.getEventTitle();
  expect(await eventTitle.textContent()).toBe("Some special event");
});

// Page Object Model

class BookingPage extends PageObjectModel {
  async getEventTitle() {
    const selector = "h2.title .content";
    const result = await page.$(selector);
    if (!result) throw new Error(`Could not find selector: "${selector}"`);
    return result;
  }
}

如果这是一个好方法,那么对于所有查找来说似乎都是一件痛苦的事情。将 page.$ 包装在另一个只为我做的函数中是个好主意吗?改变 page.$ 本身不是一个好主意吗?因此,也许可以创建一个包装器方法来进行错误处理,然后调用 page.$?

所以我可以这样做:

class PageObjectModel {
  async $(selector) {
    const result = await page.$(selector);
    if (!result) throw new Error(`Could not find selector: "${selector}"`);
    return result;
  }
}

class BookingPage extends PageObjectModel {
  async getEventTitle() {
    return this.$("h2.title .content");
  }
}

这有点不错,但出于某种原因,堆栈跟踪仅链接到 some-test.jsPageObjectModel.js,而不链接到 BookingPage.js

我觉得我没有遗漏一些关于 JS 错误处理的一般信息? ¯_(ツ)_/¯

好吧,最后我发现你可以使用 page.waitForSelector,如果找到它,它也会 return 元素,如果没有找到,则会用 TimeoutError 拒绝,这是我想要的。

出于某种原因,堆栈跟踪仍然仅链接到 some-test.jsPageObjectModel.js,但是如果我捕获并重新将其放入 BookingPage.js,那么它确实会将其添加到堆栈中跟踪。

我其实不需要扔,我只需要注销即可。所以这就是我要使用的解决方案:

// some-test.js - ** unchanged **
it("should display the event title", async () => {
  let eventTitle = await this.bookingPage.getEventTitle();
  expect(await eventTitle.textContent()).toBe("Some special event");
});
class PageObjectModel {
  async $(selector) {
    return page.waitForSelector(selector);
  }
}
class BookingPage extends PageObjectModel {
  async getEventTitle() {
    return await this.$("h2.title .content").catch(console.error);
  }
}

这有点奇怪,因为根据 this article await return 在 try/catch 之外是多余的,但我想因为我使用的是 .catch 它在功能上与试试看?

无论如何,这给了我想要的堆栈跟踪。