无法运行剧作家"Writing Assertions"例子
Unable to run Playwright "Writing Assertions" example
TL;DR
Playwright Getting Started 页面中的“编写断言”示例无法正常工作。
全文
我正在查看 Playwright for writing tests. I'm working my way through the Getting Started 个示例,示例 #2(编写断言) 有问题。我正在我的工作机器 (macOS) 上执行此操作,但还没有机会在我家里的 Linux 机器上尝试它,如果这会有所作为的话。
有问题的例子是:
// example.spec.js
const { test, expect } = require('@playwright/test');
test('my test', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle('Playwright');
// Expect an attribute "to be strictly equal" to the value.
await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
// Expect an element "to be visible".
await expect(page.locator('text=Learn more')).toBeVisible();
await page.click('text=Get Started');
// Expect some text to be visible on the page.
await expect(page.locator('text=System requirements')).toBeVisible();
// Compare screenshot with a stored reference.
expect(await page.screenshot()).toMatchSnapshot('get-started.png');
});
我遇到的最初问题是此行失败:
await expect(page).toHaveTitle('Playwright');
我可以通过更改 .toHaveTitle()
来寻找正则表达式来解决它,所以现在它看起来像下面这样:
// 02_writing_assertions.spec.js
const { test, expect } = require('@playwright/test');
test('my test', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/); // Updated to regex
// Expect an attribute "to be strictly equal" to the value.
await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
// Expect an element "to be visible".
await expect(page.locator('text=Learn more')).toBeVisible();
await page.click('text=Get Started');
// Expect some text to be visible on the page.
await expect(page.locator('text=System requirements')).toBeVisible();
// Compare screenshot with a stored reference.
expect(await page.screenshot()).toMatchSnapshot('get-started.png');
});
但是,当我 运行 它时,我现在得到以下信息:
❯ npx playwright test tests/getting_started/02_writing_assertions.spec.js --headed
Running 1 test using 1 worker
✘ tests/getting_started/02_writing_assertions.spec.js:4:1 › my test (4s)
1) tests/getting_started/02_writing_assertions.spec.js:4:1 › my test =============================
locator.getAttribute: Evaluation failed: Error: strict mode violation: selector resolved to 2 elements.
at u.querySelector (<anonymous>:3:34807)
at eval (eval at evaluate (:3:1339), <anonymous>:7:32)
at i (<anonymous>:3:37685)
at <anonymous>:3:37773
at Object.run (<anonymous>:3:38253)
at eval (eval at evaluate (:3:1339), <anonymous>:1:14)
at t.default.evaluate (<anonymous>:3:1362)
at t.default.<anonymous> (<anonymous>:1:44)
=========================== logs ===========================
retrieving attribute "href" from "text=Get Started"
strict mode violation: selector resolved to 2 elements.
============================================================
9 |
10 | // Expect an attribute "to be strictly equal" to the value.
> 11 | await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
| ^
12 |
13 | // Expect an element "to be visible".
14 | await expect(page.locator('text=Learn more')).toBeVisible();
at /Users/me/node_modules/@playwright/test/lib/test/matchers/matchers.js:131:27
at /Users/me/node_modules/@playwright/test/lib/test/matchers/toMatchText.js:48:22
at pollUntilDeadline (/Users/me/node_modules/@playwright/test/lib/test/util.js:119:42)
at Object.toMatchText (/Users/me/node_modules/@playwright/test/lib/test/matchers/toMatchText.js:47:37)
at Object.toHaveAttribute (/Users/me/node_modules/@playwright/test/lib/test/matchers/matchers.js:130:35)
at Object.<anonymous> (/Users/me/node_modules/@playwright/test/lib/test/expect.js:94:30)
at __EXTERNAL_MATCHER_TRAP__ (/Users/me/node_modules/expect/build/index.js:342:30)
at Object.throwingMatcher (/Users/me/node_modules/expect/build/index.js:343:15)
at /Users/me/dev/playwright/playwright-test/tests/getting_started/02_writing_assertions.spec.js:11:50
at WorkerRunner._runTestWithBeforeHooks (/Users/me/node_modules/@playwright/test/lib/test/workerRunner.js:425:7)
1 failed
tests/getting_started/02_writing_assertions.spec.js:4:1 › my test ==============================
注释掉每个 await expect(...)
语句只会在下一个 await expect(...)
语句中重复错误。如果我将它们全部注释掉,那么 await page.click(...)
运行 会按预期出现,但下一个 await expect(...)
会再次失败。
更新
所以...看来问题是所写的 page.locator(...)
返回了多个元素,这应该是显而易见的,因为我看到了以下内容错误:
Evaluation failed: Error: strict mode violation: selector resolved to 2 elements.
所以我更改了以下行:
await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
至
await expect(page.locator('//a[text()="Get Started"][1]')).toHaveAttribute('href', '/docs/intro');
我认为这可以解决问题。但是,现在我超时了。
我能够解决(几乎)所有问题。我无法解决的初始脚本的一个问题是这一行:
// Expect some text to be visible on the page.
await expect(page.locator('text=System requirements')).toBeVisible();
该字符串在页面上出现了两次。在尝试以各种方式搜索字符串(即 xpath
)时,我的代码要么 returned 了两个元素,要么超时了。由于这是页面上的任意字符串,而不是需要单击才能继续下一步的元素,因此我只是替换了一个不同的字符串。
工作脚本如下:
// 02_writing_assertions.spec.js
const { test, expect } = require('@playwright/test');
test('my test', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
// Expect an attribute "to be strictly equal" to the value.
await expect(page.locator('(//a[translate(text(),"get started","GET STARTED")="GET STARTED"])[1]')).toHaveAttribute('href', '/docs/intro');
// Expect an element "to be visible".
await expect(page.locator('(//a[translate(text(),"learn more", "LEARN MORE")="LEARN MORE"])[1]')).toBeVisible();
// Click "Get Started"
await page.click('(//a[translate(text(),"get started","GET STARTED")="GET STARTED"])[1]')
// Expect some text to be visible on the page.
await expect(page.locator('(//h1[contains(translate(text(),"getting started","GETTING STARTED"),"GETTING STARTED")])[1]')).toBeVisible()
// Compare screenshot with a stored reference.
expect(await page.screenshot()).toMatchSnapshot('get-started.png');
});
关于我的 xpath
声明的一些项目:
我总是将我的文本字符串翻译成大写以进行比较,只是为了加强测试以防止将来将“Get Started”变成“GEt Started”的错字。
与始终引用特定元素设置的xpath
return相同;它可以防止将来有人添加相同 URL 的第二个实例。
TL;DR
Playwright Getting Started 页面中的“编写断言”示例无法正常工作。
全文
我正在查看 Playwright for writing tests. I'm working my way through the Getting Started 个示例,示例 #2(编写断言) 有问题。我正在我的工作机器 (macOS) 上执行此操作,但还没有机会在我家里的 Linux 机器上尝试它,如果这会有所作为的话。
有问题的例子是:
// example.spec.js
const { test, expect } = require('@playwright/test');
test('my test', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle('Playwright');
// Expect an attribute "to be strictly equal" to the value.
await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
// Expect an element "to be visible".
await expect(page.locator('text=Learn more')).toBeVisible();
await page.click('text=Get Started');
// Expect some text to be visible on the page.
await expect(page.locator('text=System requirements')).toBeVisible();
// Compare screenshot with a stored reference.
expect(await page.screenshot()).toMatchSnapshot('get-started.png');
});
我遇到的最初问题是此行失败:
await expect(page).toHaveTitle('Playwright');
我可以通过更改 .toHaveTitle()
来寻找正则表达式来解决它,所以现在它看起来像下面这样:
// 02_writing_assertions.spec.js
const { test, expect } = require('@playwright/test');
test('my test', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/); // Updated to regex
// Expect an attribute "to be strictly equal" to the value.
await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
// Expect an element "to be visible".
await expect(page.locator('text=Learn more')).toBeVisible();
await page.click('text=Get Started');
// Expect some text to be visible on the page.
await expect(page.locator('text=System requirements')).toBeVisible();
// Compare screenshot with a stored reference.
expect(await page.screenshot()).toMatchSnapshot('get-started.png');
});
但是,当我 运行 它时,我现在得到以下信息:
❯ npx playwright test tests/getting_started/02_writing_assertions.spec.js --headed
Running 1 test using 1 worker
✘ tests/getting_started/02_writing_assertions.spec.js:4:1 › my test (4s)
1) tests/getting_started/02_writing_assertions.spec.js:4:1 › my test =============================
locator.getAttribute: Evaluation failed: Error: strict mode violation: selector resolved to 2 elements.
at u.querySelector (<anonymous>:3:34807)
at eval (eval at evaluate (:3:1339), <anonymous>:7:32)
at i (<anonymous>:3:37685)
at <anonymous>:3:37773
at Object.run (<anonymous>:3:38253)
at eval (eval at evaluate (:3:1339), <anonymous>:1:14)
at t.default.evaluate (<anonymous>:3:1362)
at t.default.<anonymous> (<anonymous>:1:44)
=========================== logs ===========================
retrieving attribute "href" from "text=Get Started"
strict mode violation: selector resolved to 2 elements.
============================================================
9 |
10 | // Expect an attribute "to be strictly equal" to the value.
> 11 | await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
| ^
12 |
13 | // Expect an element "to be visible".
14 | await expect(page.locator('text=Learn more')).toBeVisible();
at /Users/me/node_modules/@playwright/test/lib/test/matchers/matchers.js:131:27
at /Users/me/node_modules/@playwright/test/lib/test/matchers/toMatchText.js:48:22
at pollUntilDeadline (/Users/me/node_modules/@playwright/test/lib/test/util.js:119:42)
at Object.toMatchText (/Users/me/node_modules/@playwright/test/lib/test/matchers/toMatchText.js:47:37)
at Object.toHaveAttribute (/Users/me/node_modules/@playwright/test/lib/test/matchers/matchers.js:130:35)
at Object.<anonymous> (/Users/me/node_modules/@playwright/test/lib/test/expect.js:94:30)
at __EXTERNAL_MATCHER_TRAP__ (/Users/me/node_modules/expect/build/index.js:342:30)
at Object.throwingMatcher (/Users/me/node_modules/expect/build/index.js:343:15)
at /Users/me/dev/playwright/playwright-test/tests/getting_started/02_writing_assertions.spec.js:11:50
at WorkerRunner._runTestWithBeforeHooks (/Users/me/node_modules/@playwright/test/lib/test/workerRunner.js:425:7)
1 failed
tests/getting_started/02_writing_assertions.spec.js:4:1 › my test ==============================
注释掉每个 await expect(...)
语句只会在下一个 await expect(...)
语句中重复错误。如果我将它们全部注释掉,那么 await page.click(...)
运行 会按预期出现,但下一个 await expect(...)
会再次失败。
更新
所以...看来问题是所写的 page.locator(...)
返回了多个元素,这应该是显而易见的,因为我看到了以下内容错误:
Evaluation failed: Error: strict mode violation: selector resolved to 2 elements.
所以我更改了以下行:
await expect(page.locator('text=Get Started')).toHaveAttribute('href', '/docs/intro');
至
await expect(page.locator('//a[text()="Get Started"][1]')).toHaveAttribute('href', '/docs/intro');
我认为这可以解决问题。但是,现在我超时了。
我能够解决(几乎)所有问题。我无法解决的初始脚本的一个问题是这一行:
// Expect some text to be visible on the page.
await expect(page.locator('text=System requirements')).toBeVisible();
该字符串在页面上出现了两次。在尝试以各种方式搜索字符串(即 xpath
)时,我的代码要么 returned 了两个元素,要么超时了。由于这是页面上的任意字符串,而不是需要单击才能继续下一步的元素,因此我只是替换了一个不同的字符串。
工作脚本如下:
// 02_writing_assertions.spec.js
const { test, expect } = require('@playwright/test');
test('my test', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
// Expect an attribute "to be strictly equal" to the value.
await expect(page.locator('(//a[translate(text(),"get started","GET STARTED")="GET STARTED"])[1]')).toHaveAttribute('href', '/docs/intro');
// Expect an element "to be visible".
await expect(page.locator('(//a[translate(text(),"learn more", "LEARN MORE")="LEARN MORE"])[1]')).toBeVisible();
// Click "Get Started"
await page.click('(//a[translate(text(),"get started","GET STARTED")="GET STARTED"])[1]')
// Expect some text to be visible on the page.
await expect(page.locator('(//h1[contains(translate(text(),"getting started","GETTING STARTED"),"GETTING STARTED")])[1]')).toBeVisible()
// Compare screenshot with a stored reference.
expect(await page.screenshot()).toMatchSnapshot('get-started.png');
});
关于我的 xpath
声明的一些项目:
我总是将我的文本字符串翻译成大写以进行比较,只是为了加强测试以防止将来将“Get Started”变成“GEt Started”的错字。
与始终引用特定元素设置的
xpath
return相同;它可以防止将来有人添加相同 URL 的第二个实例。