ブラウザテスト

ブラウザテスト

ブラウザテストは、Chrome、Firefox、またはSafariなどの実際のブラウザ内で実行されます。私たちは、ウェブページとのプログラム的なやり取りにPlaywright(ブラウザ自動化ツール)を使用します。

Playwrightは、ブラウザとのやり取りにJavaScriptのAPIを公開するテストフレームワークであり、ライブラリでもあります。私たちはPlaywrightのテストフレームワークは使用しません。なぜなら、すでにJapaを使用しているため、1つのプロジェクト内で複数のテストフレームワークを使用すると混乱と設定の肥大化につながるからです。

代わりに、Japaとうまく統合し、素晴らしいテスト体験を提供するJapaのBrowser Clientプラグインを使用します。

セットアップ

最初のステップは、npmパッケージレジストリから次のパッケージをインストールすることです。

npm i -D playwright @japa/browser-client

ブラウザスイートの登録

まず、adonisrc.tsファイル内にブラウザテスト用の新しいテストスイートを作成します。ブラウザスイートのテストファイルはtests/browserディレクトリに保存されます。

{
tests: {
suites: [
{
files: [
'tests/browser/**/*.spec(.ts|.js)'
],
name: 'browser',
timeout: 300000
}
]
}
}

プラグインの設定

テストを書き始める前に、tests/bootstrap.tsファイル内でbrowserClientプラグインを登録する必要があります。

import { browserClient } from '@japa/browser-client'
export const plugins: Config['plugins'] = [
assert(),
apiClient(),
browserClient({
runInSuites: ['browser']
}),
pluginAdonisJS(app)
]

基本的な例

AdonisJSアプリケーションのホームページを開き、ページの内容を検証する例のテストを作成しましょう。visitヘルパーは新しいページを開き、URLにアクセスします。戻り値はページオブジェクトです。

参考:アサーションメソッドの一覧

node ace make:test pages/home --suite=browser
# DONE: create tests/browser/pages/home.spec.ts
tests/browser/pages/home.spec.ts
import { test } from '@japa/runner'
test.group('ホームページ', () => {
test('ウェルカムメッセージを表示する', async ({ visit }) => {
const page = await visit('/')
await page.assertTextContains('body', 'It works!')
})
})

最後に、上記のテストをtestコマンドを使用して実行しましょう。--watchフラグを使用して、ファイルの変更ごとにテストを再実行することもできます。

node ace test browser

クッキーの読み書き

実際のブラウザ内でテストを実行する場合、クッキーはブラウザコンテキストのライフサイクル全体で永続化されます。

Japaは各テストごとに新しいブラウザコンテキストを作成します。したがって、1つのテストのクッキーは他のテストに漏れることはありません。ただし、1つのテスト内で複数回のページ訪問を行う場合、同じbrowserContextを使用するため、クッキーが共有されます。

test.group('ホームページ', () => {
test('ウェルカムメッセージを表示する', async ({ visit, browserContext }) => {
await browserContext.setCookie('username', 'virk')
// リクエスト時に「username」クッキーが送信されます
const homePage = await visit('/')
// このリクエスト時にも「username」クッキーが送信されます
const aboutPage = await visit('/about')
})
})

同様に、サーバーが設定したクッキーはbrowserContext.getCookieメソッドを使用してアクセスできます。

import router from '@adonisjs/core/services/router'
router.get('/', async ({ response }) => {
response.cookie('cartTotal', '100')
return 'It works!'
})
test.group('ホームページ', () => {
test('ウェルカムメッセージを表示する', async ({ visit, browserContext }) => {
const page = await visit('/')
console.log(await browserContext.getCookie('cartTotal'))
})
})

次のメソッドを使用して、暗号化されたクッキーとプレーンなクッキーの読み書きを行うことができます。

// 書き込み
await browserContext.setEncryptedCookie('username', 'virk')
await browserContext.setPlainCookie('username', 'virk')
// 読み込み
await browserContext.getEncryptedCookie('cartTotal')
await browserContext.getPlainCookie('cartTotal')

セッションストアの設定

アプリケーション内でセッションデータの読み書きを行うために@adonisjs/sessionパッケージを使用している場合、テストを作成する際にセッションストアを準備するためにsessionBrowserClientプラグインを使用することもできます。

セットアップ

最初のステップは、tests/bootstrap.tsファイル内でプラグインを登録することです。

import { sessionBrowserClient } from '@adonisjs/session/plugins/browser_client'
export const plugins: Config['plugins'] = [
assert(),
pluginAdonisJS(app),
sessionBrowserClient(app)
]

次に、.env.testファイル(存在しない場合は作成)を更新し、SESSON_DRIVERmemoryに設定します。

.env.test
SESSION_DRIVER=memory

セッションデータの書き込み

browserContext.setSessionメソッドを使用して、現在のブラウザコンテキストのセッションデータを定義できます。

同じブラウザコンテキストを使用して行われるすべてのページ訪問は、同じセッションデータにアクセスできます。ただし、ブラウザまたはコンテキストが閉じられるとセッションデータは削除されます。

test('カートアイテムをチェックアウトする', async ({ browserContext, visit }) => {
await browserContext.setSession({
cartItems: [
{
id: 1,
name: 'South Indian Filter Press Coffee'
},
{
id: 2,
name: 'Cold Brew Bags',
}
]
})
const page = await visit('/checkout')
})

setSessionメソッドと同様に、browser.setFlashMessagesメソッドを使用してフラッシュメッセージを定義することもできます。

/**
* フラッシュメッセージを定義する
*/
await browserContext.setFlashMessages({
success: '投稿が正常に作成されました',
})
const page = await visit('/posts/1')
/**
* ポストページがフラッシュメッセージを表示していることをアサートする
* ".alert-success" div内に。
*/
await page.assertExists(page.locator(
'div.alert-success',
{ hasText: '投稿が正常に作成されました' }
))

セッションデータの読み込み

browserContext.getSessionおよびbrowser.getFlashMessagesメソッドを使用して、セッションストア内のデータを読み取ることができます。これらのメソッドは、特定のブラウザコンテキストインスタンスに関連付けられたセッションIDのすべてのデータを返します。

const session = await browserContext.getSession()
const flashMessages = await browserContext.getFlashMessages()

ユーザーの認証

アプリケーションでユーザーの認証に@adonisjs/authパッケージを使用している場合、authBrowserClient Japaプラグインを使用して、HTTPリクエストを行う際にユーザーを認証できます。

最初のステップは、tests/bootstrap.tsファイル内でプラグインを登録することです。

tests/bootstrap.ts
import { authBrowserClient } from '@adonisjs/auth/plugins/browser_client'
export const plugins: Config['plugins'] = [
assert(),
pluginAdonisJS(app),
authBrowserClient(app)
]

セッションベースの認証を使用している場合は、セッションドライバをインメモリストアに切り替えてください。

.env.test
SESSION_DRIVER=memory

以上です。loginAsメソッドを使用してユーザーをログインできます。このメソッドは、ユーザーオブジェクトを唯一の引数として受け取り、ユーザーを現在のブラウザコンテキストにログインします。

同じブラウザコンテキストを使用して行われるすべてのページ訪問は、ログインしたユーザーにアクセスできます。ただし、ブラウザまたはコンテキストが閉じられるとユーザーセッションは破棄されます。

import User from '#models/user'
test('支払いリストを取得する', async ({ browserContext, visit }) => {
const user = await User.create(payload)
await browserContext.loginAs(user)
const page = await visit('/dashboard')
})

loginAsメソッドは、認証にconfig/auth.tsファイルで設定されたデフォルトのガードを使用します。ただし、withGuardメソッドを使用してカスタムガードを指定することもできます。

例:

const user = await User.create(payload)
await browserContext
.withGuard('admin')
.loginAs(user)

ルートヘルパー

テストコンテキストのrouteヘルパーを使用して、ルートのURLを作成できます。routeヘルパーを使用すると、ルートを更新するたびにテスト内のすべてのURLを修正する必要がなくなります。

routeヘルパーは、グローバルテンプレートメソッドrouteと同じ引数を受け入れます。

test('ユーザーリストを表示する', async ({ visit, route }) => {
const page = await visit(
route('users.list')
)
})