javascript - Playwright.js element not found error handling - Stack Overflow

I'm converting a bunch of tests from Selenium + Jest to Playwright + Jest, and one of the differen

I'm converting a bunch of tests from Selenium + Jest to Playwright + Jest, and one of the differences is that for element lookups, await page.$(".whatever") doesn't reject if it doesn't find the element.

I'm doing a lot of element lookups as we've built out Page Object Models for a lot of ponents.

My question is, do I need to manually add some error handling, or am I missing something here? Jest will tell me which test fails but there's no stack trace so it can be hard to track down what went wrong. Also, is this a good way to do it?

// 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;
  }
}

If it is a good approach it seems like a pain to have to do for all lookups. Would it be a good idea to wrap page.$ in another function that just does it for me? It would be a bad idea to mutate page.$ itself right? So maybe create a wrapper method that does the error handling and it and then calls page.$?

So I could do something like this:

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");
  }
}

Which is kinda nice but then for some reason the stack trace only links to some-test.js and PageObjectModel.js, and not to BookingPage.js.

I feel like I'm not missing something about JS error handling in general? ¯_(ツ)_/¯

I'm converting a bunch of tests from Selenium + Jest to Playwright + Jest, and one of the differences is that for element lookups, await page.$(".whatever") doesn't reject if it doesn't find the element.

I'm doing a lot of element lookups as we've built out Page Object Models for a lot of ponents.

My question is, do I need to manually add some error handling, or am I missing something here? Jest will tell me which test fails but there's no stack trace so it can be hard to track down what went wrong. Also, is this a good way to do it?

// 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;
  }
}

If it is a good approach it seems like a pain to have to do for all lookups. Would it be a good idea to wrap page.$ in another function that just does it for me? It would be a bad idea to mutate page.$ itself right? So maybe create a wrapper method that does the error handling and it and then calls page.$?

So I could do something like this:

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");
  }
}

Which is kinda nice but then for some reason the stack trace only links to some-test.js and PageObjectModel.js, and not to BookingPage.js.

I feel like I'm not missing something about JS error handling in general? ¯_(ツ)_/¯

Share Improve this question edited Mar 3, 2021 at 12:50 Steven asked Mar 3, 2021 at 12:39 StevenSteven 3055 silver badges15 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

Okay so in the end I found that you can use page.waitForSelector which will also return the element if it's found and will reject with a TimeoutError if it's not found, which is what I wanted.

For some reason the stack-trace still only links to some-test.js and PageObjectModel.js however if I catch and re-throw it in BookingPage.js then it does add that to the stack trace.

I don't actually need to throw it, I just need to log it out. So this is the solution I'm going with:

// 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);
  }
}

It's a bit weird as according to this article await return is redundant outside of try/catch, but I guess because I'm using .catch it's functionally the same as try catch?

Anyway, this gives me the stack trace that I want.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745159349a4614317.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信