你会喜欢的 Playwright 面试问题

你会喜欢的 Playwright 面试问题

· 1,765 词 · 9 分钟 读完 playwright进阶 翻译

适用于中高级 QA 自动化工程师的 Playwright 面试问题

继我之前关于 Playwright 面试问题的文章之后,这里有 9 个Playwright 棘手问题

1. 显式等待

从测试搜索功能的角度来看,你会如何改进下面的代码:

test("The explicit waits", async ({ page }) => {
  await page.goto("https://blog.martioli.com/playwright-tips-and-tricks-2/");
  await page
    .getByText("Playwright tips and tricks #2")
    .scrollIntoViewIfNeeded();
  await expect(page.getByText("Playwright tips and tricks #2")).toBeVisible();
  await expect(
    page.getByRole("button", { name: "Search this site" })
  ).toBeVisible();
  await page.getByRole("button", { name: "Search this site" }).click();
  await expect(
    page
      .frameLocator('iframe[title="portal-popup"]')
      .getByPlaceholder("Search posts, tags and authors")
  ).toBeVisible();
  await page
    .frameLocator('iframe[title="portal-popup"]')
    .getByPlaceholder("Search posts, tags and authors")
    .fill("Cypress");
  await expect(
    page
      .frameLocator('iframe[title="portal-popup"]')
      .getByRole("heading", { name: "Cypress" })
      .first()
  ).toContainText("Cypress");
});

回答

  • 移除所有 toBeVisible() 断言
  • 移除 scrollIntoViewIfNeeded()
  • 将 iframe 存储在常量中以便重用和提高可读性
  • 在定位器中使用正则表达式,以便使用部分文本,例如 /Search posts/ 而不是 Search posts, tags and authors

查看代码和解释请见页面末尾 链接...

乙醇的解释 👀: 还是给个省流版本吧,我没看作者的解释,我按照自己的理解来编的 😳

  • 移除所有 toBeVisible() 断言: 因为这些断言没必要,如果你要操作 1 个元素的话,没必要断言这个元素toBeVisible,因为 playwright 会自动帮你做这件事情

  • 移除 scrollIntoViewIfNeeded(): 理由同上

  • 将 iframe 存储在常量中以便重用和提高可读性: 个人喜好问题,但是有道理

  • 在定位器中使用正则表达式,以便使用部分文本,例如 /Search posts/ 而不是 Search posts, tags and authors: 完全同意,尽量避免精准匹配的断言和定位器,当然了,playwright 默认情况下getByXXX中如果出现文本,都是模糊匹配的。


2. 可见的方法

这段代码将会做什么:

test("The visible methods", async ({ page }) => {
  await page.goto("https://blog.martioli.com/");
  await expect(page.getByRole("link", { name: "About" }).isVisible());
});

可能的答案:

  • 测试将失败,因为 isVisible() 不是一个有效的方法
  • 测试将失败,并显示关于属性 'then' 的错误
  • 测试将通过

回答

测试将失败,并显示错误:Error: expect: Property 'then' not found

查看解释请见页面末尾 链接...

省流版本

错误原因是 isVisible() 方法返回的是一个 Promise 对象,但 expect 断言方法不能直接处理 Promise 对象。需要使用 await 关键字来等待 Promise 对象的解析。

正确的代码应该是:

test("The visible methods", async ({ page }) => {
  await page.goto("https://blog.martioli.com/");
  const isVisible = await page.getByRole("link", { name: "About" }).isVisible();
  await expect(isVisible).toBe(true);
});

这样修改后,isVisible() 方法的返回结果会在被 expect 断言方法处理之前被正确解析。

乙醇的注释 👀:最好用 playwright 的 web 断言 await expect(locator).toBeVisible()

3. 忍者点击

以下代码将会发生什么:

test("The ninja", async ({ page }) => {
  await page.goto("https://www.clickspeedtester.com/mouse-test/");
  await page
    .getByRole("link", { name: "Second Clicker" })
    .click({ trial: true });
  await page.waitForURL("**/clicks-per-second-test/");
});

可能的答案:

  • 测试将失败,错误为 page.waitForURL: Test ended,因为点击操作未执行
  • 测试将失败,因为 waitForURL() 参数格式无效
  • 测试将在点击步骤失败,没有 trial:true 这样的选项

回答

测试将失败,错误为 page.waitForURL: Test ended。使用 trial:true Playwright 只执行是否可以被点击的检查,但跳过点击操作。


4. 你还好吗?

以下代码将会发生什么:

test("The you OK", async ({ page }) => {
  const response = await page.request.get("https://blog.martioli.com/");
  await expect(response).toBeOK();
});

可能的答案:

  • 测试将失败,因为没有 toBeOK() 这个方法
  • 测试将失败,因为 page 没有 request
  • 测试将通过

回答

测试将通过(前提是网站没挂的话)。toBeOK() 是一个确保响应状态码在 200..299 范围内的方法。


5. 特殊词

假设元素包含文本"Be the first to discover new tips and tricks about automation in software development",以下代码将会发生什么:

test("The innerText?", async ({ page }) => {
  await page.goto("https://blog.martioli.com");
  const innertText = page.locator(".gh-subscribe-description").innerText();
  await expect(innertText).toContain("Be the first to discover new tips");
});

可能的答案:

  • 测试将通过
  • 测试将失败,错误为 Error: expect Received object: {}
  • 测试将失败,因为我们不能在 innerText() 上使用 toContain()

回答

测试将失败,错误为 Error: expect Received object: {}。因为我们忘记在 innerText() 方法前加上 await 关键字,以解析 Promise 并提取文本。


6. 神奇的过滤器

过滤测试用例的最佳推荐方法是什么?

回答

tags是过滤测试最简单和最有效的方法。


7. 失败的一次

以下代码将会发生什么:

test("The fail", async ({ page }) => {
  test.fail();
  await page.goto("https://www.martioli.com/");
  await expect(page.getByText("Astronaut")).toBeVisible();
});

可能的答案:

  • 测试将通过,因为应用了 test.fail() 方法
  • 测试将失败,因为应用了 test.fail() 方法
  • 测试将执行所有步骤,但结果仍然失败

回答

测试将通过,因为应用了 test.fail() 方法

为什么?因为它在我的网站上找不到 "Astronaut" 这个词,因为找不到它,我们期望的测试整体失败,用例确实会失败,所以整体而言用例将通过


8. 健康检查

以下代码将会发生什么?你如何改进代码:

const locales = ["de", "com", "es"];

for (const location of locales) {
  test(`check health: ${location}`, async ({ page }) => {
    const response = await page.request.get(`https://www.google.${location}/`);
    expect(response).toBeOK();
  });
}

可能的答案:

  • 测试将通过
  • 测试将失败,因为不能进行这样的 for 循环
  • 测试将失败,因为 expect 没有 await 关键字

回答

测试将通过。你可以在 Playwright 中进行这样的检查,只需注意在测试中加入一些延迟。

如果你想知道为什么 expect 不需要 await 关键字,请见页面末尾的解释 链接...

省流版本: 在 Playwright 中,expect 断言方法不需要 await 关键字的原因是 Playwright 的 expect 方法是同步的,不返回 Promise 对象。它会立即检查传入的值或对象的状态,并且如果检查失败,它会立即抛出一个错误


9. 页面一

以下代码将会发生什么:

test("The page one", async ({ page }) => {
  await page.goto("https://blog.martioli.com/");
  await expect(getByText("Recommended Resources")).toBeVisible();
});

可能的答案:

  • 测试将通过,因为我们有 Recommended Resources
  • 测试将失败,因为引用错误
  • 测试将失败,因为我的博客中没有 Recommended Resources 文本

回答

测试将失败,错误为 ReferenceError: getByRole is not defined。注意我们用了 expect(getByText 而不是 expect(page.getByText.


如果你觉得这篇文章有用,请点击点赞按钮。或者请我喝杯咖啡,以

更好地激励我。

来源

来源网址:https://blog.martioli.com/playwright-interview-questions-that-you-are-going-to-love/

发布时间:2024-05-17T07:08:35.000Z