※本手順書ではソースディレクトリを「src」に変更している想定としています。テストコードは「src/e2eTest」に保存します。
※Vitestのインストール手順に関しては以下を参照ください。
https://n-laboratory.jp/articles/nuxt3-vitest-unittest
・Nuxt 3.5.2
・Vitest 0.31.4
・puppeteer 20.5.0
・VeeValidate 4.9.6
1. Puppeteerをインストールします。
$ npm install puppeteer
1. VeeValidateをインストールします。
$ npm install --save-dev vee-validate @vee-validate/i18n @vee-validate/rules
2. 「plugins」ディレクトリに「vee-validate-plugin.ts」を新規作成し、以下を追加します。
import { localize, setLocale } from '@vee-validate/i18n'
import ja from '@vee-validate/i18n/dist/locale/ja.json'
import AllRules from '@vee-validate/rules'
import { defineRule, configure } from 'vee-validate'
import { defineNuxtPlugin } from '#app'
export default defineNuxtPlugin((_nuxtApp) => {
configure({
generateMessage: localize({
ja
})
})
Object.keys(AllRules).forEach((rule) => {
// すべてのルールをインポート
defineRule(rule, AllRules[rule])
})
setLocale('ja')
})
1. 「pages」配下に「form.vue」を新規作成し、以下の内容で保存します。
<script lang="ts" setup>
import { Form, Field, ErrorMessage } from 'vee-validate'
const emailRef = ref('')
const foo = (values: Record<string, any>) => {
emailRef.value = values.email
}
</script>
<template>
<div>
<Form v-slot="{ meta }" data-testid="validation-form" @submit="foo">
<!-- バリデーション対象の項目 -->
<Field rules="required|email" name="email" as="input" type="text" data-testid="input-email" />
<!-- バリデーションエラーメッセージの表示 -->
<ErrorMessage name="email" data-testid="email-error-msg" />
<!-- meta.validは有効な値を入力された場合にtrueを返します -->
<button :disabled="!meta.valid" data-testid="submit-btn">
Submit
</button>
</Form>
<p>Result:{{ emailRef }}</p>
</div>
</template>
2. 以下のURLにアクセスします。フォーム画面が表示されており、送信ボタンが非活性であることを確認します。
http://localhost:3000/form
3. 入力欄に「a」を入力します。エラーメッセージが表示されることを確認します。
4. 入力欄を空欄にします。エラーメッセージが表示されることを確認します。
5. 入力欄に「a@a.com」を入力します。送信ボタンが活性していることを確認します。
6. 送信ボタンをクリックします。Resultに「a@a.com」が表示されていることを確認します。
src
└── e2eTest
├── form.spec.ts ← テストファイル
└── xxx.png ← 各テストケースのスクリーンショット(エビデンス)
1. 「e2eTest」配下に「form.spec.ts」を新規作成し、以下の内容で保存します。
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import { launch, PuppeteerLaunchOptions } from 'puppeteer'
import type { Browser, Page } from 'puppeteer'
// ブラウザの起動オプションの設定。使用できるパラメータに関しての詳細は以下を参照ください。
// https://pptr.dev/api/puppeteer.browserlaunchargumentoptions
const options: PuppeteerLaunchOptions = {
headless: false,
slowMo: 75,
defaultViewport: {
width: 1280,
height: 1024
},
devtools: true,
args: ['--window-size=1680,1024']
}
describe('form.vue', () => {
let browser: Browser
let page: Page
beforeAll(async () => {
browser = await launch(options)
page = await browser.newPage()
})
afterAll(async () => {
await browser.close()
})
test('1:フォーム画面が表示されること', async () => {
// Act
await page.goto('http://localhost:3000/form')
await page.waitForNavigation({ timeout: 5000, waitUntil: 'domcontentloaded' })
// スクリーンショット(エビデンス)の撮影
await page.screenshot({
path: './src/e2eTest/test1.png',
fullPage: true
})
const existsPage = await page.$eval(
'[data-testid="validation-form"]',
element => !!element
)
// Assert
expect(existsPage).toBe(true)
}, 20000)
describe('バリデーションチェック', () => {
test.each([
[
2,
'不正なメールアドレスを入力した',
'abcABC0123456789',
'emailは有効なメールアドレスではありません'
],
[
3,
'未入力の',
'',
'emailは必須項目です'
]
])(
'%s:メールアドレスの入力フィールドに[%s]場合、エラーメッセージが表示されること',
async (
testNo,
description,
inputValue,
expectedErrorMsg
) => {
// Act
await page.type('input[data-testid="input-email"]', inputValue)
await page.keyboard.press('Tab')
// スクリーンショット(エビデンス)の撮影
await page.screenshot({
path: `./src/e2eTest/test${testNo}.png`,
fullPage: true
})
// エラーメッセージの取得
const errorMsg = await page.$eval(
'[data-testid="email-error-msg"]',
element => element.textContent
)
// Assert
expect(errorMsg).toBe(expectedErrorMsg)
// 入力した値をリセット
await page.click('input[data-testid="input-email"]', {
clickCount: inputValue.length
})
await page.keyboard.press('Backspace')
},
200000
)
})
describe('Submitボタンの活性/非活性状態確認', () => {
test('4:初期状態では送信ボタンが非活性であること', async () => {
// Act
await page.goto('http://localhost:3000/form')
await page.waitForNavigation({ timeout: 5000, waitUntil: 'domcontentloaded' })
// Act
await page.screenshot({
path: './src/e2eTest/test4.png',
fullPage: true
})
const disabled = await page.$eval(
'[data-testid="submit-btn"]',
element => (element as HTMLButtonElement).disabled
)
// Assert
expect(disabled).toBe(true)
}, 10000)
test('5:有効なメールアドレスを入力した場合、送信ボタンが活性であること', async () => {
// Act
await page.type('input[data-testid="input-email"]', 'test@test.com')
await page.keyboard.press('Tab')
await page.screenshot({
path: './src/e2eTest/test5.png',
fullPage: true
})
const disabled = await page.$eval(
'[data-testid="submit-btn"]',
element => (element as HTMLButtonElement).disabled
)
// Assert
expect(disabled).toBeFalsy()
// 入力した値をリセット
await page.click('input[data-testid="input-email"]', { clickCount: 13 })
await page.keyboard.press('Backspace')
}, 10000)
})
test('6:Submitボタンを押下した場合、Result欄にメールアドレスが表示されること', async () => {
// Act
await page.type('input[data-testid="input-email"]', 'test@test.com')
await page.keyboard.press('Tab')
await page.click('[data-testid="submit-btn"]')
await page.screenshot({
path: './src/e2eTest/test6.png',
fullPage: true
})
const result = await page.$eval(
'[data-testid="result"]',
element => element.textContent
)
// Assert
expect(result).toBe('Result:test@test.com')
}, 10000)
})
2. package.jsonの「scripts」に以下を追加します。
{
"scripts": {
"dev": "nuxt dev",
"test": "vitest",
},
}
3. テストを実行します。
$ npm run dev
$ npm run test
4. ブラウザが自動で起動し、テストが実行されることを確認します。
5. テスト終了後はブラウザが自動で終了し、テストが全件passしていることを確認します。
> test
> vitest
✓ src/e2eTest/form.spec.ts (6) 18482ms
✓ form.vue (6) 18482ms
✓ 1:フォーム画面が表示されること 1455ms
✓ バリデーションチェック (2) 6388ms
✓ 2:メールアドレスの入力フィールドに[不正なメールアドレスを入力した]場合、エラーメッセージが表示されること 4715ms
✓ 3:メールアドレスの入力フィールドに[未入力の]場合、エラーメッセージが表示されること 1673ms
✓ Submitボタンの活性/非活性状態確認 (2) 5509ms
✓ 4:初期状態では送信ボタンが非活性であること 1283ms
✓ 5:有効なメールアドレスを入力した場合、送信ボタンが活性であること 4226ms
✓ 6:Submitボタンを押下した場合、Result欄にメールアドレスが表示されること 3494ms
Test Files 1 passed (1)
Tests 6 passed (6)
Start at 20:09:08
以上で全ての手順は完了になります