Notes Used to Craft this Lesson
Unlike the API Client, where we are making API requests similar to Axios and asserting against the responses, the Browser Client allows us to run tests with an actual browser. This gives us powerful assertion abilities against the actual HTML document that is rendered. So, for example, we'd be able to assert that a specific input is disabled using a query selector.
There is a ton of depth with this plugin; it could be a series on its own. Our focus here is just going to be a soft introduction to it. Needless to say, since we'll be testing with actual browsers here, these are going to be the slowest of our tests.
To start, let's go ahead and get it installed. The Browser Client uses Playwright to run the browser instances, so we'll need to install both here.
npm i -D playwright @japa/browser-clientCopied!
Now, for Playwright to work, it needs executables for the browsers. We can install those via:
npx playwright installCopied!
That should pull down Chromeium, Firefox, WebKit, and FFMPEG. The output will look similar to the one below, depending on your system/shell.
> npx playwright install Downloading Chromium 143.0.7499.4 (playwright build v1200) from https://cdn.playwright.dev/dbazure/download/playwright/builds/chromium/1200/chromium-mac-arm64.zip 159.6 MiB [====================] 100% 0.0s Chromium 143.0.7499.4 (playwright build v1200) downloaded to /Users/<user>/Library/Caches/ms-playwright/chromium-1200 Downloading Chromium Headless Shell 143.0.7499.4 (playwright build v1200) from https://cdn.playwright.dev/dbazure/download/playwright/builds/chromium/1200/chromium-headless-shell-mac-arm64.zip 89.7 MiB [====================] 100% 0.0s Chromium Headless Shell 143.0.7499.4 (playwright build v1200) downloaded to /Users/<user>/Library/Caches/ms-playwright/chromium_headless_shell-1200 Downloading Firefox 144.0.2 (playwright build v1497) from https://cdn.playwright.dev/dbazure/download/playwright/builds/firefox/1497/firefox-mac-arm64.zip 91.5 MiB [====================] 100% 0.0s Firefox 144.0.2 (playwright build v1497) downloaded to /Users/<user>/Library/Caches/ms-playwright/firefox-1497 Downloading Webkit 26.0 (playwright build v2227) from https://cdn.playwright.dev/dbazure/download/playwright/builds/webkit/2227/webkit-mac-15-arm64.zip 71.9 MiB [====================] 100% 0.0s Webkit 26.0 (playwright build v2227) downloaded to /Users/<user>/Library/Caches/ms-playwright/webkit-2227 Downloading FFMPEG playwright build v1011 from https://cdn.playwright.dev/dbazure/download/playwright/builds/ffmpeg/1011/ffmpeg-mac-arm64.zip 1 MiB [====================] 100% 0.0s FFMPEG playwright build v1011 downloaded to /Users/<user>/Library/Caches/ms-playwright/ffmpeg-1011Copied!
Next, we'll add a suite specifically for these so that it is only run when needed.
// adonisrc.ts export default defineConfig({ // ... tests: { suites: [ { files: ["tests/unit/**/*.spec(.ts|.js)"], name: "unit", timeout: 2000, }, { files: ["tests/functional/**/*.spec(.ts|.js)"], name: "functional", timeout: 30000, }, { files: ["tests/browser/**/*.spec(.ts|.js)"], name: "browser", timeout: 30000, }, ], forceExit: false, }, });Copied!
Then, we'll register the plugin. As part of its options, we can provide which suite it should run in, and we'll want to set that to browser.
import { browserClient } from "@japa/browser-client"; export const plugins: Config["plugins"] = [ assert(), openapi({ schemas: [new URL("../docs/openapi.json", import.meta.url)], }), apiClient(), browserClient({ runInSuites: ["browser"], }), pluginAdonisJS(app), sessionApiClient(app), authApiClient(app), shieldApiClient(), disallowPinnedTests({ disallow: !!process.env.CI, }), ];Copied!
- tests
- bootstrap.ts
Great, finally let's give it a test run!
node ace make:test pages/auth/login --suite=browserCopied!
For our test, let's just confirm that our login page shows "Login" within an H1 element.
test.group("Pages auth login", () => { test("see an h1 saying login", async ({ visit, route }) => {}); });Copied!
Similar to how the API Client provides a client to our tests, the Browser Client provides a visit which we can use to visit URLs and get back the rendered page. That page is an instance of Playwright's page, which contains a ton of methods to perform selections, actions, and determinations on the page itself. We'll walk through an example of those in the next lesson.
test.group("Pages auth login", () => { test("see an h1 saying login", async ({ visit, route }) => { const page = await visit(route("auth.login.show")); }); });Copied!
Japa's plugin also adds a number of assertion utilities to the Playwright page, making testing super convenient.
test.group("Pages auth login", () => { test("see an h1 saying login", async ({ visit, route }) => { const page = await visit(route("auth.login.show")); await page.assertText("h1", "Login"); }); });Copied!
Here, with assertText, we're providing the query selector h1, which behaves similarly to running document.querySelector('h1') inside a browser. Then the method itself is asserting that the found H1 element's innerText equals "Login".