ホームページ > ウェブフロントエンド > jsチュートリアル > Heroku での Playwright と Chrome ブラウザのテスト

Heroku での Playwright と Chrome ブラウザのテスト

Mary-Kate Olsen
リリース: 2024-12-06 10:35:12
オリジナル
227 人が閲覧しました

私はいつも単体テストが実行される (そして合格する) のを見るのが大好きでした。それらは高速であり、テストに合格すると、私の個々の部分が想定どおりに動作するという保証が得られます。逆に、ブラウザのエンドツーエンド テストの作成と実行が恐ろしく遅いため、優先順位を付けるのに苦労することがよくありました。

幸いなことに、ブラウザ内でエンドツーエンドのテストを行うためのツールは、長年にわたってはるかに優れ、高速になってきました。また、ヘッドレス ブラウザをセットアップすると、CI の一部としてブラウザ テストを実行できます。

最近、私は Heroku CI 内のヘッドレス Chrome を使用したブラウザ内テストの自動化について説明している、この Heroku ブログ投稿を見つけました。 Heroku にはヘッドレス Chrome をインストールするビルドパックがあり、CI パイプラインでテストのために呼び出すことができます。

ブログ投稿のセットアップ例は、Puppeteer と Jest でテストされた React アプリでした。それは素晴らしいスタートです…しかし、Puppeteer の代わりに Playwright を使用したらどうなるでしょうか?可能でしょうか?

私は調査することにしました。結局のところ、 — はい、Playwright でもこれを行うことができます。そこで、Heraku CI で使用されるヘッドレス Chrome ブラウザで Playwright テストを実行するために必要な手順をキャプチャしました。この投稿では、セットアップの手順を説明します。

エンドツーエンド テストのためのブラウザ自動化についての簡単な説明

エンドツーエンドのテストでは、ユーザーがブラウザーで実際にアプリをどのように操作するかをキャプチャし、完全なワークフローを検証します。 Playwright は、Chrome、Firefox、Safari でのテストを行うことで、このプロセスを非常にシームレスにします。もちろん、CI でブラウザー テストをすべて実行するとかなり負荷がかかるため、ヘッドレス モードが役立ちます。

Heraku の Chrome for Testing ビルドパックは Heroku アプリに Chrome をインストールするため、非常に軽量なセットアップで Heroku CI で Playwright テストを実行できます。

テスト用アプリケーションの概要

私はこれを試していたところだったので、もともと Heroku ブログ投稿で参照されていた GitHub リポジトリをフォークしました。このアプリケーションは、リンク、テキスト入力、送信ボタンを備えたシンプルな React アプリでした。 3 つのテストがありました:

  1. リンクが機能し、正しい場所にリダイレクトされることを確認します。

  2. テキスト入力にユーザー入力が適切に表示されていることを確認します。

  3. フォームを送信すると、ページに表示されるテキストが更新されることを確認します。

とてもシンプルです。ここで、Puppeteer と Jest の代わりに Playwright を使用するようにコードを変更する必要がありました。ああ、npm の代わりに pnpm も使いたかったです。これは、フォークされた GitHub リポジトリへのリンクです。

Playwright を使用するようにコードを変更する

コードを変更するために行った手順を見てみましょう。私は、heroku-examples リポジトリと同じ、フォークされたリポジトリから始めました。

pnpmを使用する

npm の代わりに pnpm を使いたかったのです。 (個人的な好みです。) それで、私が最初にやったことは次のとおりです:

~/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 everything's good


Lockfile is up to date, resolution step is skipped
Already up to date
Done in 1.3s
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

Playwright をプロジェクトに追加する

次に、Puppeteer と Jest を削除し、Playwright を追加しました。

~/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.
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

package.json から Jest 構成セクションも削除しました。

Chromium のみを使用するように Playwright を設定する

Playwright テストは Chrome、Firefox、Safari で実行できます。 Chrome に焦点を当てていたため、生成された playwright.config.js ファイルのプロジェクト セクションから他のブラウザを削除しました:

  /* 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 のテストコードに交換します

元のコードには、src/tests/puppeteer.test.js に Puppeteer テスト ファイルがありました。そのファイルをtests/playwright.spec.jsに移動しました。次に、Playwright の規則を使用するようにテストを更新しました。これは非常にきれいにマッピングされました。新しいテスト ファイルは次のようになります:

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 を削除しました。

~/project$ pnpm remove start-server-and-test
ログイン後にコピー
ログイン後にコピー

playwright.config.js で、下部にある webServer セクションのコメントを解除し、次のように変更しました。

  /* 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 スクリプトを削除しました。代わりに、私のテスト スクリプトは次のようになりました:

  "scripts": {
    …
    "test": "playwright test --project=chromium --reporter list"
  },
ログイン後にコピー
ログイン後にコピー

Playwright ブラウザをローカルマシンにインストールする

Playwright は、テストに使用する最新のブラウザ バイナリをインストールします。そのため、ローカル マシンに Playwright のバージョンの Chromium をインストールする必要がありました。

~/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 for Testing ビルドパックは、テストに使用するブラウザをインストールします。 Playwright が独自のブラウザーをインストールするのに時間とリソースを費やす代わりに、そのブラウザーを使用するように CI をセットアップします。

ローカルでテストを実行する

これで準備は完了です。ローカルでテストを試してみる時が来ました。

~/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 | });
ログイン後にコピー

ああ!それは正しい。アプリ内のリンクから Puppeteer のドキュメントではなく Playwright のドキュメントに移動できるようにテストを変更しました。 src/App.js の 19 行目を更新する必要がありました:

<Link href="https://playwright.dev/" rel="noopener">
  Playwright Documentation
</Link>
ログイン後にコピー

さて、再びテストを実行する時が来ました…

~/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)
ログイン後にコピー

テストは合格しました!次に、Heraku CI に移行します。

Heroku にデプロイして CI パイプラインを使用する

私は Heroku ブログ投稿の手順に従って、アプリを Heroku CI パイプラインにセットアップしました。

Heroku パイプラインを作成する

Heraku で新しいパイプラインを作成し、フォークした GitHub リポジトリに接続しました。

Playwright and Chrome Browser Testing in Heroku

次に、アプリをステージングに追加しました。

Playwright and Chrome Browser Testing in Heroku

次に、テスト タブに移動し、Heraku CI を有効にする をクリックします。

Playwright and Chrome Browser Testing in Heroku

最後に、app.json ファイルを変更して、npm test:ci を呼び出すように設定されたテスト スクリプトを削除しました。 package.json ファイルから test:ci スクリプトをすでに削除していました。 package.json 内のテスト スクリプトが使用されるようになり、Heraku CI はデフォルトでそのスクリプトを検索します。

Chrome for Testing ビルドパックを使用するようにした私の app.json ファイルは次のようになります:

~/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 everything's good


Lockfile is up to date, resolution step is skipped
Already up to date
Done in 1.3s
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

最初のテストの実行

コードを GitHub にプッシュすると、Heraku CI でのテスト実行がトリガーされました。

Playwright and Chrome Browser Testing in Heroku

試運転は失敗しましたが、心配はしていませんでした。 Playwright の設定を行う必要があることはわかっていました。

テストログを調べてみると、次のことがわかりました:

~/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 は Chrome ブラウザのインス​​タンスを探していました。 CI テスト設定の一部として、playwright install chromium コマンドを使用してインストールできました。しかし、それは Chrome for Testing ビルドパックの目的全体を無効にしてしまいます。 Chrome はすでにインストールされています。それを適切に指す必要があっただけです。

Heraku のテスト設定ログを振り返ると、次の行が見つかりました:

  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },

//    {
//      name: 'firefox',
//      use: { ...devices['Desktop Firefox'] },
//    },
//
//    {
//      name: 'webkit',
//      use: { ...devices['Desktop Safari'] },
//    },


  ],
…
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

つまり、私が使用したいブラウザは /app/.chrome-for-testing/chrome-linux64/chrome にありました。 Playwright に探してもらうだけです。

Playwright がインストールされている Chrome ブラウザを見つけられるようにする

注: ここでの核心的な詳細に興味がない場合は、このセクションをスキップして、完全な app.json を下にコピーしてください。これにより、Heraku CI で Playwright を起動して実行するために必要なものが得られます。

Playwright のドキュメントで、すべてのブラウザーのインストールにカスタムの場所を使用したかどうかを Playwright に伝える環境変数を設定できることがわかりました。その環境変数は PLAYWRIGHT_BROWSERS_PATH です。そこから始めることにしました。

app.json で、次のように環境変数を設定します。

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);
  });
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

CI でのテストで何が起こるかを確認するためにコードを GitHub にプッシュしました。

予想通り、また失敗しました。ただし、ログ エラーには次のことが示されていました:

~/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 everything's good


Lockfile is up to date, resolution step is skipped
Already up to date
Done in 1.3s
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これでかなり近づいてきました。私はこれをやろうと決めました:

  • Playwright が Chrome ブラウザーを想定している場所に必要なフォルダーを作成します。それは次のようなコマンドになります。
~/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.
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • このフォルダーにシンボリックリンクを作成して、Heraku ビルドパックによってインストールされた Chrome バイナリをポイントします。それは次のようになります。
  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },

//    {
//      name: 'firefox',
//      use: { ...devices['Desktop Firefox'] },
//    },
//
//    {
//      name: 'webkit',
//      use: { ...devices['Desktop Safari'] },
//    },


  ],
…
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

しかし、これが将来性があるかどうかが心配でした。最終的に、Playwright は新しいバージョンの Chromium を使用することになり、chromium-1140 フォルダーには表示されなくなります。 Playwright がどこを見ているかをどうやって知ることができますか?

そのとき、ブラウザのインス​​トールの予行演習ができることを知りました。

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);
  });
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

その「インストール場所」行は重要でした。そして、PLAYWRIGHT_BROWSERS_PATH を設定すると、次のようになります:

~/project$ pnpm remove start-server-and-test
ログイン後にコピー
ログイン後にコピー

それが私が望むものです。ちょっと気の利いた魔法を使って、こんなことをしてみました:

  /* Run your local dev server before starting the tests */
  webServer: {
     command: 'pnpm start',
     url: 'http://127.0.0.1:8080',
     reuseExistingServer: !process.env.CI,
  },
ログイン後にコピー
ログイン後にコピー

以上のことを理解したら、あとはテストセットアップ スクリプトを app.json に追加するだけです。 PLAYWRIGHT_BROWSERS_PATH は既に env に設定されているため、スクリプトはもう少し単純になります。これが私の最後の app.json ファイルでした:

  "scripts": {
    …
    "test": "playwright test --project=chromium --reporter list"
  },
ログイン後にコピー
ログイン後にコピー

test-setup の機能について簡単に説明します。

  1. PLAYWRIGHT_BROWSERS_PATH を考慮して、Playwright install -- awk によるドライランを使用して、Playwright が Chrome ブラウザを検索するルート フォルダーを決定します。これを CHROMIUM_PATH 変数の値として設定します。

  2. CHROMIUM_PATH/chrome-linux に新しいフォルダー (および必要な親フォルダー) を作成します。これは、Playwright が Chrome バイナリを検索する実際のフォルダーです。

  3. Chrome が Chrome の Heroku ビルドパック インストール (/app/.chrome-for-testing/chrome-linux64/chrome) を指すように、そのフォルダーにシンボリックリンクを作成します。

テストを再度実行する

更新された app.json ファイルを使用すると、Playwright はビルドパックからの Chrome インストールを使用できるようになります。もう一度テストを実行する時が来ました。

Playwright and Chrome Browser Testing in Heroku

成功!

テストセットアップ スクリプトは期待どおりに実行されました。

Playwright and Chrome Browser Testing in Heroku

Playwright は Chrome バイナリにアクセスしてテストを実行でき、テストは成功しました。

Playwright and Chrome Browser Testing in Heroku

結論

Web アプリケーションのエンドツーエンドのテストは煩雑ではなくなってきているので、ますます優先順位を上げています。最近では、Playwright の使用も増えています。柔軟かつ高速です。 Heroku CI の Chrome for Testing ビルドパックを立ち上げて実行するための作業 (私 と皆さん !) が完了したので、ブラウザ自動テスト スイートの構築を一度開始できます。またまた。

このチュートリアルのコードは、私の GitHub リポジトリから入手できます。

コーディングを楽しんでください!

以上がHeroku での Playwright と Chrome ブラウザのテストの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート