採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

Vue — Playwright (E2E)

テクノロジ系 / L07 test — テスト

Vue — Playwright (E2E)

install

$ pnpm create playwright

playwright.config.ts, tests/example.spec.ts が生成。

基本

import { test, expect } from "@playwright/test";

test("homepage", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveTitle(/My Vue App/);
});

test("navigate", async ({ page }) => {
  await page.goto("/");
  await page.getByRole("link", { name: "About" }).click();
  await expect(page).toHaveURL("/about");
  await expect(page.getByRole("heading", { name: "About" })).toBeVisible();
});

React と全く同じ API (フレームワーク非依存)。

ユーザ動線

test("login → dashboard", async ({ page }) => {
  await page.goto("/login");
  await page.getByLabel("Email").fill("test@example.com");
  await page.getByLabel("Password").fill("password");
  await page.getByRole("button", { name: "Login" }).click();
  await expect(page).toHaveURL("/dashboard");
});

test("create item", async ({ page }) => {
  await loginAs(page, "test@example.com");
  await page.getByRole("button", { name: "New Item" }).click();
  await page.getByLabel("Name").fill("My Item");
  await page.getByRole("button", { name: "Save" }).click();
  await expect(page.getByText("My Item")).toBeVisible();
});

設定

import { defineConfig } from "@playwright/test";

export default defineConfig({
  testDir: "./tests/e2e",
  use: {
    baseURL: "http://localhost:5173",
    trace: "on-first-retry",
  },
  webServer: {
    command: "pnpm dev",
    url: "http://localhost:5173",
    reuseExistingServer: !process.env.CI,
  },
});

webServer で自動起動。

デバッグ

$ pnpm exec playwright test --headed       # ブラウザ表示
$ pnpm exec playwright test --debug         # 1行ずつステップ
$ pnpm exec playwright test --ui            # UI モード (最強)

smoke だけに絞る

✅ ログイン → ダッシュボード
✅ メイン機能の主要動線 1〜3本
✅ お金が動くフロー
❌ 全フィールドのバリデーション (vitest+VTU で)

E2E は遅いので 網羅でなくスモークに留める

CI

- run: pnpm install
- run: pnpm exec playwright install --with-deps
- run: pnpm exec playwright test

まとめ

  • Playwright は フレームワーク非依存、React と同じ API
  • 主要動線だけに絞る (smoke)
  • --ui モードでデバッグ最強
  • webServer で自動起動 + テスト

Vue 補強完了。

お疲れさまでした。

Vue 補強完走 — 次の進路

関心進む先
バックエンドbackend/express / backend/fastapi
React もfrontend/react
型強化frontend/typescript
Nuxt(将来 Phase 2 で別教材)

考えてみよう

既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。

Vue + Playwright (E2E) — 演習

pnpm create playwright

(React リポと同内容、Vue も同じ API)

Lv1: 基本 — Homepage test

問題

import { test, expect } from "@playwright/test";

test("homepage", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveTitle(/Vue/);
});

test("can navigate", async ({ page }) => {
  await page.goto("/");
  await page.getByRole("link", { name: "About" }).click();
  await expect(page).toHaveURL(/.*about/);
});

合格基準

2 test pass。

Lv2: 応用 — フォーム送信

問題

test("user can submit form", async ({ page }) => {
  await page.goto("/contact");
  await page.getByLabel("Name").fill("Taro");
  await page.getByLabel("Email").fill("taro@example.com");
  await page.getByLabel("Message").fill("Hi");
  await page.getByRole("button", { name: "Send" }).click();
  await expect(page.getByText("送信しました")).toBeVisible();
});

合格基準

入力 → 送信 → 結果確認。

Lv3: 発展 — smoke の絞り込み + CI

問題

「smoke テストとして残すべき」 vs 「Unit に任せるべき」を分類。

テストsmoke / unit
ログイン → ダッシュボード遷移smoke
メイン機能の主要動線 (1〜3本)smoke
課金フローsmoke
全フィールドのバリデーションunit (vitest + VTU)
全エラーケースunit
Edge ケース (空文字 / 巨大入力)unit

CI で smoke だけ走らせる設定:

- run: pnpm exec playwright test --grep="@smoke"
test("@smoke login flow", async ({ page }) => { ... });
test("login error edge case", async ({ page }) => { ... });   // smoke 外

合格基準

  • 分類できる
  • CI で smoke だけ実行する方法を理解

提出

submission.md に3問の回答を。

Vue リポ補強完走

L01〜L07 の補強分すべて完了。L00 / L08 (既存) と合わせて Vue 3 + Composition API + TS の全体像を網羅。

次は他リポ (React / Express / TS / FastAPI) へ。