Saya sentiasa suka menonton ujian unit saya berjalan (dan lulus). Mereka pantas, dan lulus ujian memberi saya jaminan bahawa bahagian individu saya berkelakuan seperti yang sepatutnya. Sebaliknya, saya sering bergelut untuk mengutamakan ujian hujung ke hujung untuk penyemak imbas kerana menulis dan menjalankannya adalah sangat perlahan.
Nasib baik, alat untuk ujian dalam penyemak imbas hujung ke hujung telah menjadi lebih baik dan lebih pantas selama ini. Dan dengan persediaan penyemak imbas tanpa kepala, saya boleh menjalankan ujian penyemak imbas saya sebagai sebahagian daripada CI saya.
Baru-baru ini, saya terjumpa catatan blog Heroku ini bercakap tentang mengautomasikan ujian dalam penyemak imbas dengan Chrome tanpa kepala dalam Heroku CI. Heroku mempunyai buildpack yang memasang Chrome tanpa kepala, yang boleh anda gunakan untuk ujian anda dalam saluran paip CI.
Contoh persediaan daripada catatan blog ialah apl React yang diuji dengan Puppeteer dan Jest . Itu permulaan yang bagus … tetapi bagaimana jika saya menggunakan Penulis Drama dan bukannya Puppeteer? Adakah mungkin?
Saya memutuskan untuk menyiasat. Ternyata — ya, anda juga boleh melakukan ini dengan Penulis Drama! Jadi, saya menangkap langkah yang anda perlukan untuk menjalankan ujian Playwright pada penyemak imbas Chrome tanpa kepala yang digunakan dalam Heroku CI. Dalam siaran ini, saya akan membimbing anda melalui langkah-langkah untuk membuat persediaan.
Ujian hujung ke hujung menangkap cara pengguna sebenarnya berinteraksi dengan apl anda dalam penyemak imbas, mengesahkan aliran kerja yang lengkap. Penulis drama menjadikan proses ini cukup lancar dengan ujian dalam Chrome, Firefox dan Safari. Sudah tentu, menjalankan ujian pelayar penuh dalam CI agak berat, itulah sebabnya mod tanpa kepala membantu.
Pek binaan Chrome untuk Pengujian daripada Heroku memasang Chrome pada apl Heroku, supaya anda boleh menjalankan ujian Playwright anda dalam Heroku CI dengan persediaan yang sangat ringan.
Memandangkan saya baru sahaja mencuba ini, saya telah membatalkan repo GitHub yang pada asalnya dirujuk dalam catatan blog Heroku. Aplikasi itu ialah apl React yang ringkas dengan pautan, input teks dan butang hantar. Terdapat tiga ujian:
Cukup mudah. Sekarang, saya hanya perlu menukar kod untuk menggunakan Playwright dan bukannya Puppeteer dan Jest. Oh, dan saya juga mahu menggunakan pnpm dan bukannya npm. Berikut ialah pautan ke repo GitHub bercabang saya .
Mari kita ikuti langkah yang saya ambil untuk mengubah suai kod. Saya bermula dengan repo bercabang saya, sama dengan repo heroku-examples
.
Saya mahu menggunakan pnpm dan bukannya npm. (Keutamaan peribadi.) Jadi, inilah yang saya lakukan dahulu:
~/project$ corepack enable pnpm ~/project$ corepack use pnpm@latest Installing [email protected] 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
Seterusnya, saya mengalih keluar Puppeteer dan Jest, dan saya menambah 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.
Saya juga mengalih keluar bahagian konfigurasi Jest daripada package.json
.
Anda boleh menjalankan ujian Playwright anda dalam Chrome, Firefox dan Safari. Memandangkan saya tertumpu pada Chrome, saya mengalih keluar penyemak imbas lain daripada bahagian projects
fail playwright.config.js
yang dijana:
/* Configure projects for major browsers */ projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, // { // name: 'firefox', // use: { ...devices['Desktop Firefox'] }, // }, // // { // name: 'webkit', // use: { ...devices['Desktop Safari'] }, // }, ], …
Kod asal mempunyai fail ujian Puppeteer di src/tests/puppeteer.test.js
. Saya mengalihkan fail itu ke tests/playwright.spec.js
. Kemudian, saya mengemas kini ujian untuk menggunakan konvensyen Playwright, yang dipetakan dengan agak bersih. Fail ujian baharu kelihatan seperti ini:
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
, Sebaliknya menggunakan Pelayan web Playwright Untuk menguji apl React saya, saya perlu memutarkannya (di http://localhost:8080
) dalam proses yang berasingan dahulu, dan kemudian saya boleh menjalankan ujian saya. Ini akan berlaku sama ada saya menggunakan Puppeteer atau Drama. Dengan Puppeteer, contoh Heroku menggunakan pakej start-server-and-test
.
Walau bagaimanapun, anda boleh mengkonfigurasi Playwright untuk memutarkan apl sebelum menjalankan ujian. Ini cukup mudah!
Saya mengalih keluar start-server-and-test
daripada projek saya.
~/project$ pnpm remove start-server-and-test
Dalam playwright.config.js
, saya menyahkomen bahagian webServer di bahagian bawah, mengubah suainya supaya kelihatan seperti ini:
/* Run your local dev server before starting the tests */ webServer: { command: 'pnpm start', url: 'http://127.0.0.1:8080', reuseExistingServer: !process.env.CI, },
Kemudian, saya mengalih keluar skrip test:ci
daripada fail package.json
yang asal. Sebaliknya, skrip ujian saya kelihatan seperti ini:
"scripts": { … "test": "playwright test --project=chromium --reporter list" },
Penulis drama memasang binari penyemak imbas terkini untuk digunakan untuk ujiannya. Jadi, pada mesin tempatan saya, saya memerlukan Playwright untuk memasang versi Chromiumnya.
~/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%
Nota: Pek binaan Chrome untuk Pengujian pada Heroku memasang penyemak imbas yang akan kami gunakan untuk ujian. Kami akan menyediakan CI kami supaya Playwright menggunakan penyemak imbas itu dan bukannya menghabiskan masa dan sumber memasang sendiri.
Dengan itu, saya sudah bersedia. Sudah tiba masanya untuk mencuba ujian saya secara tempatan.
~/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 | });
Oh! betul tu. Saya mengubah suai ujian saya untuk mengharapkan pautan dalam apl membawa saya ke dokumentasi Playwright dan bukannya Puppeteer. Saya perlu mengemas kini src/App.js
pada baris 19:
<Link href="https://playwright.dev/" rel="noopener"> Playwright Documentation </Link>
Kini, tiba masanya untuk menjalankan ujian sekali lagi…
~/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)
Ujian telah berlalu! Seterusnya, tiba masanya untuk membawa kami ke Heroku CI.
Saya mengikuti arahan dalam catatan blog Heroku untuk menyediakan apl saya dalam saluran paip Heroku CI.
Di Heroku, saya mencipta saluran paip baharu dan menyambungkannya ke repo GitHub bercabang saya.
Seterusnya, saya menambahkan apl saya pada pementasan.
Kemudian, saya pergi ke tab Ujian dan mengklik Dayakan Heroku CI .
Akhirnya, saya mengubah suai fail app.json
untuk mengalih keluar skrip ujian yang ditetapkan untuk memanggil npm test:ci
. Saya telah pun mengalih keluar skrip test:ci
daripada fail package.json
saya. Skrip test
dalam package.json
kini yang digunakan dan Heroku CI akan mencari yang itu secara lalai.
Fail app.json
saya, yang memastikan anda menggunakan pek binaan Chrome untuk Pengujian, kelihatan seperti ini:
{ "environments": { "test": { "buildpacks": [ { "url": "heroku-community/chrome-for-testing" }, { "url": "heroku/nodejs" } ] } } }
Saya menolak kod saya ke GitHub, dan ini mencetuskan ujian dijalankan dalam Heroku CI.
Ujian larian gagal, tetapi saya tidak bimbang. Saya tahu akan ada beberapa konfigurasi Penulis Drama yang perlu dilakukan.
Menggali di dalam log ujian, saya dapati ini:
Error: browserType.launch: Executable doesn't exist at /app/.cache/ms-playwright/chromium-1140/chrome-linux/chrome
Penulis drama sedang mencari contoh penyemak imbas Chrome. Saya boleh memasangnya dengan arahan playwright install chromium
sebagai sebahagian daripada persediaan ujian CI saya. Tetapi itu akan mengalahkan keseluruhan tujuan mempunyai pek binaan Chrome untuk Pengujian. Chrome telah pun dipasang; Saya hanya perlu menunjukkannya dengan betul.
Melihat kembali log persediaan ujian saya untuk Heroku, saya dapati baris ini:
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
Jadi, penyemak imbas yang saya mahu gunakan ialah di /app/.chrome-for-testing/chrome-linux64/chrome
. Saya hanya memerlukan Penulis Drama untuk mencarinya.
Nota: Jika anda tidak berminat dengan butiran terperinci di sini, anda boleh melangkau bahagian ini dan hanya menyalin app.json
penuh ke bawah. Ini sepatutnya memberi anda perkara yang anda perlukan untuk bangkit dan berjalan dengan Penulis Drama di Heroku CI.
Dalam dokumentasi Playwright, saya mendapati bahawa anda boleh menetapkan pembolehubah persekitaran yang memberitahu Playwright jika anda menggunakan lokasi tersuai untuk semua pemasangan penyemak imbasnya . Pembolehubah env itu ialah PLAYWRIGHT_BROWSERS_PATH
. Saya memutuskan untuk bermula di sana.
Dalam app.json
, saya menetapkan pembolehubah env
seperti ini:
{ "environments": { "test": { "env": { "PLAYWRIGHT_BROWSERS_PATH": "/app/.chrome-for-testing" }, ...
Saya menolak kod saya ke GitHub untuk melihat perkara yang akan berlaku dengan ujian saya dalam CI.
Seperti yang dijangka, ia gagal lagi. Walau bagaimanapun, ralat log menunjukkan ini:
Error: browserType.launch: Executable doesn't exist at /app/.chrome-for-testing/chromium-1140/chrome-linux/chrome
Itu membuatkan saya agak rapat. Saya memutuskan bahawa saya akan melakukan ini:
mkdir -p "$PLAYWRIGHT_BROWSERS_PATH/chromium-1140/chrome-linux"
ln -s \ $PLAYWRIGHT_BROWSERS_PATH/chrome-linux64/chrome \ $PLAYWRIGHT_BROWSERS_PATH/chromium-1140/chrome-linux/chrome
Walau bagaimanapun, saya bimbang sama ada ini akan menjadi bukti masa depan. Akhirnya, Playwright akan menggunakan versi baharu Chromium, dan ia tidak akan kelihatan seperti folder chromium-1140
lagi. Bagaimanakah saya boleh mengetahui di mana Penulis Drama akan melihat?
Ketika itulah saya mendapati anda boleh melakukan pemasangan penyemak imbas larian kering.
~/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
Talian "Pasang lokasi" itu penting. Dan, jika kita menetapkan PLAYWRIGHT_BROWSERS_PATH
, inilah yang akan kita lihat:
~/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 ...
Itu yang saya mahu. Dengan sedikit awk
, saya melakukan ini:
~/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
Dengan semua perkara itu, saya hanya perlu menambah skrip test-setup
pada app.json
. Oleh kerana PLAYWRIGHT_BROWSERS_PATH
sudah ditetapkan dalam env
, skrip saya akan menjadi lebih mudah sedikit. Ini ialah fail app.json
terakhir saya:
{ "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" } } } }
Saya akan menerangkan secara ringkas apa yang dilakukan test-setup
:
Mengakaunkan PLAYWRIGHT_BROWSERS_PATH
, menggunakan playwright install -- dry-run
dengan awk
untuk menentukan folder akar tempat Pengarang drama akan mencari penyemak imbas Chrome. Tetapkan ini sebagai nilai untuk pembolehubah CHROMIUM_PATH
.
Mencipta folder baharu (dan mana-mana folder induk yang diperlukan) ke CHROMIUM_PATH/chrome-linux
, yang merupakan folder sebenar di mana Playwright akan mencari perduaan chrome
.
Mencipta symlink dalam folder itu untuk Chrome untuk menghala ke pemasangan Heroku buildpack Chrome ( /app/.chrome-for-testing/chrome-linux64/chrome
).
Dengan fail app.json
saya yang dikemas kini, Playwright sepatutnya boleh menggunakan pemasangan Chrome daripada buildpack. Sudah tiba masanya untuk menjalankan ujian sekali lagi.
Berjaya!
Skrip test-setup
berjalan seperti yang diharapkan.
Penulis drama dapat mengakses binari chrome
dan menjalankan ujian, yang lulus.
Ujian hujung ke hujung untuk aplikasi web saya semakin tidak menyusahkan, jadi saya lebih mengutamakannya. Dalam beberapa hari kebelakangan ini, ini bermakna menggunakan Penulis Drama juga. Ia fleksibel dan pantas. Dan sekarang setelah saya melakukan kerja (untuk saya dan untuk anda !) untuk menyediakan dan menjalankannya dengan Chrome for Testing buildpack dalam Heroku CI, saya boleh mula membina suite ujian automasi penyemak imbas saya sekali lagi.
Kod untuk panduan ini tersedia dalam repositori GitHub saya.
Selamat mengekod!