2020 年 5 月の頭頃、Playwright が 1.0 に到達した際に、作成チームによって書かれた記事がホットエントリーになっていました。
https://medium.com/@arjunattam/fast-and-reliable-cross-browser-testing-with-playwright-155c0e8a821f
タイミング良くクロスブラウザテストを書く機会があったので、簡単なテストを書いてみました。
※ ブラウザ毎に挙動の異なる API のテストだと良かったのですが、こちらで実施するのはボタンをクリックして innerText の変更をテストするのみです。
ソースはこちらにあります。
https://github.com/nnashiki/playwright_sample
Playwrigh とは
Chromium、Firefox、Safari を簡単にクロスブラウザテストするための、Node library とのことです。
Playwright is a Node library to automate Chromium, Firefox and WebKit with a single API. Playwright is built to enable cross-browser web automation that is ever-green, capable, reliable and fast.
https://playwright.dev/
https://github.com/microsoft/playwright
冒頭に挙げた medium の記事では、Chromium、WebKit、FireFox、WebDriver などに協力を得た(巨人の肩に乗ってるんだぜ!)とあります。
アーリアダプターはこんな感じに充実しています。
テスト対象
"ボタン押下前"と書かれているボタンを押すと"ボタン押下前"に変わる簡単なものです。
以下コマンドでサービスを立ち上げます。
docker run --rm --name sample -p 8090:80 -v $PWD/src/app:/usr/share/nginx/html -d nginx
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>ボタンテスト</title>
<link rel="icon" href="favicon.ico" />
<!- bootstrap4 ->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous"
/>
<!- bootstrap4 ->
</head>
<body>
<div class="container">
<button id="test_button1" type="button" class="btn btn-primary">
ボタン押下前
</button>
</div>
<script type="text/javascript" src="./index.js?0.0"></script>
<!- bootstrap4 ->
<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"
></script>
<!- bootstrap4 ->
</body>
</html>
const button1 = document.getElementById("test_button1");
button1.addEventListener("click", (e) => {
document.getElementById(e.target.id).innerText = "ボタン押下後";
});
テストコード
利用コード
test runner は Jest を使用しています。
各ブラウザで自動操縦でボタンをクリックして、表記の変化を確認するテストです。
ブラウザ単位でテスト結果を確認したいので分割しました。
const playwright = require("playwright");
// #test_button1 のボタンを押下して、ボタンの表記を取得する
const croll_click = async (browserType) => {
const browser = await playwright[browserType].launch();
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("http://localhost:8090");
await page.click("#test_button1");
const click_after_text = await page.evaluate(() => {
return document.getElementById("test_button1").innerText;
});
await browser.close();
return click_after_text;
};
test("click chromium", async () => {
let result = await croll_click("chromium");
expect(result).toMatch(/ボタン押下後/);
});
test("click firefox", async () => {
let result = await croll_click("firefox");
expect(result).toMatch(/ボタン押下後/);
});
test("click webkit", async () => {
let result = await croll_click("webkit");
expect(result).toMatch(/ボタン押下後/);
});
page の中での javascript(webAPI)の実行は以下を参考にしました。
https://playwright.dev/#version=v1.0.2&path=docs%2Fverification.md&q=evaluating-javascript
Jest の set up、tear down でブラウザの呼び出しと終了をするには以下が参考になります。
https://playwright.dev/#version=v1.0.2&path=docs%2Ftest-runners.md&q=jest--jasmine
環境構築
Playwright、 Jest を install します。
npm install --save-dev playwright
npm install --save-dev jest
実行してみる
jest src/test
を実行します。
ブラウザ毎のテストを実行することができました。
> jest src/test
PASS src/test/button_action.test.js (7.1 s)
✓ click chromium (1327 ms)
✓ click firefox (4186 ms)
✓ click webkit (1073 ms)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 7.594 s
Ran all test suites matching /src\/test/i.
tips
そのまま実行すると、Jest の default time out が引っかかることがありました。
FAIL src/test/button_action.test.js (8.725 s)
✓ click chromium (2076 ms)
✕ click firefox (5002 ms)
✓ click webkit (1018 ms)
● click firefox
: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
22 | });
23 |
> 24 | test("click firefox", async () => {
| ^
25 | let result = await croll_click("firefox");
26 | expect(result).toMatch(/ボタン押下後/);
27 | });
at new Spec (node_modules/jest-jasmine2/build/jasmine/Spec.js:116:22)
at Object.<anonymous> (src/test/button_action.test.js:24:1)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 2 passed, 3 total
Snapshots: 0 total
Time: 9.605 s, estimated 12 s
Ran all test suites.
そこで、timeout を伸ばして実行しました。
jest src/test --testTimeout=10000
5000mm を超えても実行できています。
$ jest src/test --testTimeout=10000
PASS src/test/button_action.test.js (11.592 s)
✓ click chromium (3831 ms)
✓ click firefox (5042 ms)
✓ click webkit (1948 ms)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 12.957 s
Ran all test suites matching /src\/test/i.
まとめ
puppeteer は使った事が無いので、比較はできませんが利用の開始はとても簡単でした。
Playwright は普及しそうなので、今後も追ってみたいと思います。