Heroku 中的 Playwright 和 Chrome 浏览器测试

来源:undefined 2025-02-13 03:02:14 1021

我一直喜欢观看我的单元测试运行(并通过)。它们速度很快,并且通过测试让我确信我的个人作品表现得像他们应该的那样。相反,我经常很难确定浏览器端到端测试的优先级,因为编写和运行它们的速度非常慢。

幸运的是,多年来,用于端到端浏览器内测试的工具已经变得更好更快。通过无头浏览器设置,我可以运行浏览器测试作为 ci 的一部分。

最近,我看到这篇 heroku 博客文章,讨论在 heroku ci 中使用无头 chrome 实现浏览器内测试的自动化。 heroku 有一个安装 headless chrome 的构建包,您可以在 ci 管道中调用它来进行测试。

博客文章中的示例设置是使用 puppeteer 和 jest 测试的 react 应用程序。这是一个很好的开始……但是如果我使用 playwright 而不是 puppeteer 呢?可以吗?

我决定调查一下。事实证明 — 是的,您也可以使用 playwright 来做到这一点!因此,我捕获了在 heroku ci 中使用的无头 chrome 浏览器上运行 playwright 测试所需的步骤。在这篇文章中,我将引导您完成设置步骤。

关于端到端测试的浏览器自动化的简短介绍

端到端测试捕获用户如何在浏览器中实际与您的应用交互,从而验证完整的工作流程。 playwright 通过在 chrome、firefox 和 safari 中进行测试,使这一过程变得非常无缝。当然,在 ci 中运行完整的浏览器测试非常繁重,这就是无头模式有帮助的原因。

heroku 的用于测试的 chrome 构建包将 chrome 安装在 heroku 应用程序上,因此您可以通过非常轻量级的设置在 heroku ci 中运行 playwright 测试。

测试申请简介

因为我只是尝试这个,所以我分叉了最初在 heroku 博客文章中引用的 github 存储库。该应用程序是一个简单的 react 应用程序,带有链接、文本输入和提交按钮。共有三个测试:

验证链接是否有效并重定向到正确的位置。

验证文本输入是否正确显示用户输入。

验证提交表单是否会更新页面上显示的文本。

非常简单。现在,我只需更改代码以使用 playwright 而不是 puppeteer 和 jest。哦,我还想使用 pnpm 而不是 npm。这是我分叉的 github 存储库的链接。

修改代码以使用 playwright

让我们来看看我修改代码的步骤。我从我的分叉存储库开始,与 heroku-examples 存储库相同。

使用pnpm

我想使用 pnpm 而不是 npm。 (个人喜好。)所以,这就是我首先做的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

~/project$ corepack enable pnpm

~/project$ corepack use pnpm@latest

installing pnpm@9.12.3 in the project…

progress: resolved 1444, reused 1441, downloaded 2, added 1444, done

done in 14.4s

~/project$ rm package-lock.json

~/project$ pnpm install # just to show everythings good

lockfile is up to date, resolution step is skipped

already up to date

done in 1.3s

登录后复制

将剧作家添加到项目中

接下来,我删除了 puppeteer 和 jest,并添加了 playwright。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

~/project$ pnpm remove

babel-jest jest jest-puppeteer @testing-library/jest-dom

~/project$ $ pnpm create playwright

getting started with writing end-to-end tests with playwright:

initializing project in .

✔ do you want to use typescript or javascript? · javascript

✔ where to put your end-to-end tests? · tests

✔ add a github actions workflow? (y/n) · false

✔ install playwright browsers (can be done manually via pnpm exec playwright install)? (y/n) · false

✔ install playwright operating system dependencies (requires sudo / root - can be done manually via sudo pnpm exec playwright install-deps)? (y/n) · false

installing playwright test (pnpm add --save-dev @playwright/test)…

installing types (pnpm add --save-dev @types/node)…

done in 2.7s

writing playwright.config.js.

writing tests/example.spec.js.

writing tests-examples/demo-todo-app.spec.js.

writing package.json.

登录后复制

将 playwright 配置为仅使用 chromium

您可以在 chrome、firefox 和 safari 中运行 playwright 测试。由于我专注于 chrome,因此我从生成的 playwright.config.js 文件的项目部分中删除了其他浏览器:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/* configure projects for major browsers */

projects: [

{

name: chromium,

use: { ...devices[desktop chrome] },

},

//    {

//      name: firefox,

//      use: { ...devices[desktop firefox] },

//    },

//

//    {

//      name: webkit,

//      use: { ...devices[desktop safari] },

//    },

],

登录后复制

将 puppeteer 测试代码交换为 playwright 测试代码

原始代码有一个 puppeteer 测试文件,位于 src/tests/puppeteer.test.js。我将该文件移至tests/playwright.spec.js。然后,我更新了测试以使用剧作家的约定,它映射得相当干净。新的测试文件如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

const root_url = http://localhost:8080;

const { test, expect } = require(@playwright/test);

const inputselector = input[name="name"];

const submitbuttonselector = button[type="submit"];

const greetingselector = h5#greeting;

const name = john doe;

test.beforeeach(async ({ page }) => {

await page.goto(root_url);

});

test.describe(playwright link, () => {

test(should navigate to playwright documentation page, async ({ page }) => {

await page.click(a[href="https://playwright.dev/"]);

await expect(page.title()).resolves.tomatch(| playwright);

});

});

test.describe(text input, () => {

test(should display the entered text in the text input, async ({ page }) => {

await page.fill(inputselector, name);

// verify the input value

const inputvalue = await page.inputvalue(inputselector);

expect(inputvalue).tobe(name);

});

});

test.describe(form submission, () => {

test(should display the "hello, x" message after form submission, async ({ page }) => {

const expectedgreeting = `hello, ${name}.`;

await page.fill(inputselector, name);

await page.click(submitbuttonselector);

await page.waitforselector(greetingselector);

const greetingtext = await page.textcontent(greetingselector);

expect(greetingtext).tobe(expectedgreeting);

});

});

登录后复制

删除 start-server-and-test,改用 playwright 的 webserver

为了测试我的 react 应用程序,我需要首先在单独的进程中启动它(在 http://localhost:8080) 处,然后我可以运行我的测试。无论我使用 puppeteer 还是 playwright,情况都是如此。使用 puppeteer, heroku 示例使用了 start-server-and-test 包。但是,您可以在运行测试之前配置 playwright 来启动应用程序!

我从我的项目中删除了 start-server-and-test。

1

~/project$ pnpm remove start-server-and-test

登录后复制

在 playwright.config.js 中,我取消了底部 webserver 部分的注释,将其修改为如下所示:

1

2

3

4

5

6

/* run your local dev server before starting the tests */

webserver: {

command: pnpm start,

url: http://127.0.0.1:8080,

reuseexistingserver: !process.env.ci,

},

登录后复制

然后,我从原始 package.json 文件中删除了 test:ci 脚本。相反,我的测试脚本如下所示:

1

2

3

4

"scripts": {

"test": "playwright test --project=chromium --reporter list"

},

登录后复制

在我的本地计算机上安装 playwright 浏览器

playwright 安装最新的浏览器二进制文件以用于其测试。因此,在我的本地计算机上,我需要 playwright 安装其版本的 chromium。

1

2

3

4

5

6

~/project$ pnpm playwright install chromium

downloading chromium 130.0.6723.31 (playwright build v1140)

from https://playwright.azureedge.net/builds/chromium/1140/chromium-linux.zip

164.5 mib [====================] 100%

登录后复制

注意: heroku 上的用于测试的 chrome 构建包安装了我们将用于测试的浏览器。我们将设置 ci,以便 playwright 使用该浏览器,而不是花费时间和资源安装自己的浏览器。

在本地运行测试

这样,我就一切准备就绪了。是时候在本地尝试我的测试了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

~/project$ pnpm test

> playwright test --project=chromium --reporter list

running 3 tests using 3 workers

✓  1 [chromium] > playwright.spec.js:21:3 > text input > should display the entered text in the text input (911ms)

✘  2 [chromium] > playwright.spec.js:14:3 > playwright link > should navigate to playwright documentation page (5.2s)

✓  3 [chromium] > playwright.spec.js:31:3 > form submission > should display the "hello, x" message after form submission (959ms)

...

- waiting for locator(a[href="https://playwright.dev/"])

13 | test.describe(playwright link, () => {

14 |   test(should navigate to playwright documentation page, async ({ page }) => {

> 15 |     await page.click(a[href="https://playwright.dev/"]);

|                ^

16 |     await expect(page.title()).resolves.tomatch(| playwright);

17 |   });

18 | });

登录后复制

哦!这是正确的。我修改了测试,期望应用程序中的链接将我带到 playwright 的文档而不是 puppeteer 的文档。我需要在第 19 行更新 src/app.js:

1

2

3

<link href="https://playwright.dev/" rel="noopener">

playwright documentation

</link>

登录后复制

现在,是时候再次运行测试了......

1

2

3

4

5

6

7

8

9

10

11

~/project$ pnpm test

> playwright test --project=chromium --reporter list

running 3 tests using 3 workers

✓  1 [chromium] > playwright.spec.js:21:3 > text input > should display the entered text in the text input (1.1s)

✓  2 [chromium] > playwright.spec.js:14:3 > playwright link > should navigate to playwright documentation page (1.1s)

✓  3 [chromium] > playwright.spec.js:31:3 > form submission > should display the "hello, x" message after form submission (1.1s)

3 passed (5.7s)

登录后复制

测试通过了!接下来,是时候让我们进入 heroku ci 了。

部署到 heroku 以使用 ci 管道

我按照 heroku 博客文章中的说明在 heroku ci 管道中设置了我的应用程序。

创建 heroku 管道

在 heroku 中,我创建了一个新管道并将其连接到我分叉的 github 存储库。

接下来,我将我的应用添加到了 staging。

然后,我转到 测试 选项卡并单击 启用 heroku ci

最后,我修改了 app.json 文件以删除设置为调用 npm test:ci 的测试脚本。我已经从我的 package.json 文件中删除了 test:ci 脚本。现在要使用 package.json 中的测试脚本,heroku ci 将默认查找该脚本。

我的 app.json 文件确保使用 chrome 进行测试构建包,如下所示:

1

2

3

4

5

6

7

8

9

10

{

"environments": {

"test": {

"buildpacks": [

{ "url": "heroku-community/chrome-for-testing" },

{ "url": "heroku/nodejs" }

]

}

}

}

登录后复制

初始测试运行

我将代码推送到 github,这触发了 heroku ci 中的测试运行。

试运行失败了,但我并不担心。我知道需要做一些 playwright 配置。

在测试日志中挖掘,我发现了这个:

1

2

error: browsertype.launch: executable doesnt exist at

/app/.cache/ms-playwright/chromium-1140/chrome-linux/chrome

登录后复制

playwright 正在寻找 chrome 浏览器实例。我可以使用 playwright install chromium 命令安装它,作为我的 ci 测试设置的一部分。但这将违背 chrome 测试构建包的全部目的。 chrome 已安装;我只需要正确指出它即可。

回顾 heroku 的测试设置日志,我发现了这些行:

1

2

3

4

5

installed chrome dependencies for heroku-24

adding executables to path

/app/.chrome-for-testing/chrome-linux64/chrome

/app/.chrome-for-testing/chromedriver-linux64/chromedriver

installed chrome for testing stable version 130.0.6723.91

登录后复制

所以,我想使用的浏览器位于/app/.chrome-for-testing/chrome-linux64/chrome。我只需要剧作家去那里寻找它。

帮助 playwright 找到已安装的 chrome 浏览器

注意:如果您对此处的具体细节不感兴趣,您可以跳过此部分,只需将完整的 app.json 复制到下方即可。这应该为您提供在 heroku ci 上使用 playwright 启动和运行所需的信息。

在 playwright 的文档中,我发现您可以设置一个环境变量,告诉 playwright 您是否为其所有浏览器安装使用了自定义位置。该环境变量是 playwright_browsers_path。我决定从这里开始。

在 app.json 中,我设置了一个这样的环境变量:

1

2

3

4

5

6

7

{

"environments": {

"test": {

"env": {

"playwright_browsers_path": "/app/.chrome-for-testing"

},

...

登录后复制

我将代码推送到 github,看看 ci 中的测试会发生什么。

果然,又失败了。然而,日志错误显示:

1

2

error: browsertype.launch: executable doesnt exist at

/app/.chrome-for-testing/chromium-1140/chrome-linux/chrome

登录后复制

这让我非常接近。我决定这样做:

创建 playwright 期望 chrome 浏览器所在位置所需的文件夹。那将是一个像这样的命令:

1

mkdir -p "$playwright_browsers_path/chromium-1140/chrome-linux"

登录后复制
在此文件夹中创建一个符号链接以指向 heroku buildpack 安装的 chrome 二进制文件。那看起来像这样:

1

2

3

ln -s

$playwright_browsers_path/chrome-linux64/chrome

$playwright_browsers_path/chromium-1140/chrome-linux/chrome

登录后复制

但是,我担心这是否能经得起未来的考验。最终,playwright 将使用新版本的 chromium,并且它不会再出现在 chromium-1140 文件夹中。我怎样才能知道剧作家会看哪里?

就在那时我发现你可以进行浏览器安装试运行。

1

2

3

4

5

6

7

8

~/project$ pnpm playwright install chromium --dry-run

browser: chromium version 130.0.6723.31

install location:    /home/alvin/.cache/ms-playwright/chromium-1140

download url:        https://playwright.azureedge.net/builds/chromium/1140/chromium-linux.zip

download fallback 1: https://playwright-akamai.azureedge.net/builds/chromium/1140/chromium-linux.zip

download fallback 2: https://playwright-verizon.azureedge.net/builds/chromium/1140/chromium-linux.zip

登录后复制

“安装位置”这一行至关重要。而且,如果我们设置 playwright_browsers_path,我们将看到以下内容:

1

2

3

4

5

6

7

~/project$ playwright_browsers_path=/app/.chrome-for-testing

pnpm playwright install chromium --dry-run

browser: chromium version 130.0.6723.31

install location:    /app/.chrome-for-testing/chromium-1140

...

登录后复制

这就是我想要的。借助一点 awk 的魔力,我做到了:

1

2

3

4

5

6

7

8

9

10

~/project$ chromium_path=$(

playwright_browsers_path=/app/.chrome-for-testing

pnpm playwright install --dry-run chromium

| awk /install location/ {print $3}

)

~/project$ echo $chromium_path

/app/.chrome-for-testing/chromium-1140

登录后复制

弄清楚所有这些后,我只需要向 app.json 添加一个测试设置脚本即可。因为 playwright_browsers_path 已经在 env 中设置,所以我的脚本会更简单一些。这是我最终的 app.json 文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

{

"environments": {

"test": {

"env": {

"PLAYWRIGHT_BROWSERS_PATH": "/app/.chrome-for-testing"

},

"buildpacks": [

{ "url": "heroku-community/chrome-for-testing" },

{ "url": "heroku/nodejs" }

],

"scripts": {

"test-setup": "CHROMIUM_PATH=$(pnpm playwright install --dry-run chromium | awk /Install location/ {print $3}); mkdir -p "$CHROMIUM_PATH/chrome-linux"; ln -s $PLAYWRIGHT_BROWSERS_PATH/chrome-lin

ux64/chrome $CHROMIUM_PATH/chrome-linux/chrome"

}

}

}

}

登录后复制

我将简要介绍一下测试设置的作用:

考虑到 playwright_browsers_path,使用 playwright install -- dry-run 和 awk 来确定 playwright 将在其中查找 chrome 浏览器的根文件夹。将其设置为 chromium_path 变量的值。

在 chromium_path/chrome-linux 中创建一个新文件夹(以及任何必要的父文件夹),这是 playwright 将在其中查找 chrome 二进制文件的实际文件夹。

在该文件夹中创建一个符号链接,以便 chrome 指向 chrome 的 heroku buildpack 安装 (/app/.chrome-for-testing/chrome-linux64/chrome)。

再次运行测试

通过我更新的 app.json 文件,playwright 应该能够使用 buildpack 中的 chrome 安装。是时候再次运行测试了。

成功!

测试设置脚本按预期运行。

playwright 能够访问 chrome 二进制文件并运行测试,并且通过了。

结论

我的 web 应用程序的端到端测试变得不再那么麻烦,因此我越来越优先考虑它。最近几天,这意味着更多地使用剧作家。它灵活且快速。现在我已经完成了工作(对我和你!),在 heroku ci 中使用 chrome for test 构建包启动并运行它,我可以开始构建我的浏览器自动化测试套件了再次。

本演练的代码可在我的 github 存储库中找到。

编码愉快!

以上就是Heroku 中的 Playwright 和 Chrome 浏览器测试的详细内容,更多请关注php中文网其它相关文章!

最新文章