SSiertsema avatar

vue-development

Vue 3 and Nuxt 3 development with TDD workflow, QA gates, and E2E test generation. Enforces unit tes

提供方 SSiertsema|开源

Vue Development Skill

This skill guides development of Vue 3 and Nuxt 3 applications using a test-driven development approach with quality assurance gates and E2E test generation from acceptance criteria.

When This Skill Activates

Use this skill when:

  • Creating or modifying .vue files
  • Writing composables (use*.ts)
  • Working with Nuxt-specific files (pages/, layouts/, middleware/, composables/)
  • User mentions Vue, Nuxt, or component development
  • Building reactive UI components
  • Implementing user stories with Gherkin acceptance criteria

Core Workflow: TDD + QA + E2E

ALWAYS follow this workflow:

1. UNDERSTAND  → Parse user story + Gherkin acceptance criteria
2. TEST FIRST  → Write failing unit tests (Vitest + Vue Test Utils)
3. IMPLEMENT   → Write minimal code to pass tests
4. REFACTOR    → Clean up while keeping tests green
5. QA CHECK    → Validate against Vue checklist (see qa/vue-checklist.md)
6. E2E WRITE   → Generate Playwright test files from Gherkin AC
7. E2E RUN     → Execute tests and verify all AC pass
8. REPORT      → Generate JSON report with E2E results

Input handling

Follow shared foundation §7 — interview mode. If the user story is missing or incomplete (missing narrative, acceptance criteria, or technical constraints), enter interview mode to gather the missing elements before proceeding. Skill-specific dimensions:

DimensionRequired
Narrative (As a/I want/So that)Yes
Acceptance criteria (Gherkin Given/When/Then)Yes
Technical constraintsNo (inferred from codebase)
Component scope (what to build)Yes

Input: User Story Format

This skill accepts user stories with Gherkin acceptance criteria:

## US-001: {Story Title}

> **As a** {persona},
> **I want** {goal},
> **So that** {benefit}.

### Acceptance Criteria

#### AC1: {Happy Path}

```gherkin
Given {precondition}
When {action}
Then {expected result}

AC2: {Error Scenario}

Given {precondition}
When {invalid action}
Then {error handling}

**See:** `e2e/acceptance-criteria.md` for detailed parsing guide.

## Step-by-Step Instructions

### Step 1: Understand Requirements

Before writing any code:
- **Parse the user story** to understand persona, goal, and benefit
- **Extract acceptance criteria** (Gherkin Given/When/Then)
- Identify props, emits, and slots needed
- Determine reactive state requirements
- Map acceptance criteria to testable behaviors

### Step 2: Write Tests First

**Create test file BEFORE implementation:**

```typescript
// src/components/__tests__/MyComponent.spec.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import MyComponent from '../MyComponent.vue'

describe('MyComponent', () => {
  it('renders with default props', () => {
    const wrapper = mount(MyComponent)
    expect(wrapper.exists()).toBe(true)
  })

  it('displays label prop correctly', () => {
    const wrapper = mount(MyComponent, {
      props: { label: 'Click me' }
    })
    expect(wrapper.text()).toContain('Click me')
  })

  it('emits click event when clicked', async () => {
    const wrapper = mount(MyComponent)
    await wrapper.trigger('click')
    expect(wrapper.emitted('click')).toBeTruthy()
  })
})

Run tests to confirm they fail:

npm run test -- MyComponent.spec.ts

Step 3: Implement Component

Write the minimal code to make tests pass:

<script setup lang="ts">
interface Props {
  label?: string
}

const props = withDefaults(defineProps<Props>(), {
  label: 'Button'
})

const emit = defineEmits<{
  click: []
}>()

function handleClick() {
  emit('click')
}
</script>

<template>
  <button @click="handleClick">
    {{ label }}
  </button>
</template>

Step 4: Verify Tests Pass

npm run test -- MyComponent.spec.ts

All tests must be green before proceeding.

Step 5: QA Validation

Go through the Vue QA Checklist (see qa/vue-checklist.md). The checklist is structured on the ISO/IEC 25010:2023 product quality model — all 9 characteristics, one item per sub-characteristic (~40 items). Validate every applicable item and mark genuinely irrelevant items N/A (N/A items are excluded from scoring, never counted as failures).

The 9 characteristics:

#CharacteristicFront-end focus
1Functional SuitabilityAC→test coverage, correctness, no scope creep
2Performance Efficiencycomputed memoization, cleanup, list capacity
3Compatibilityscoped styles, typed public contract
4Interaction Capabilitykeyboard, WCAG 2.2 AA, feedback states
5Reliabilityedge cases, SSR/hydration, error handling, recovery
6Securityno secrets, no XSS sinks, auth guards, input hardening
7MaintainabilitySRP, composables, typing, no prop mutation, TDD
8Flexibilityresponsive/tokens, scalability, replaceability
9Safetyconfirm destructive actions, fail-safe, boundary validation

Score per characteristic and overall: score = (items_passed / total_applicable_items) × 10.

Step 6: Write E2E Test Files

Generate Playwright test files from Gherkin acceptance criteria.

For each user story, create a test file:

Location: tests/e2e/{feature-slug}.spec.ts

Test File Structure

// tests/e2e/user-login.spec.ts
import { test, expect } from '@playwright/test'

/**
 * US-001: User Login
 * As a registered user, I want to login with my credentials,
 * so that I can access my account.
 */
test.describe('US-001: User Login', () => {

  test('AC1: Successful login', async ({ page }) => {
    // Given I am on the login page
    await page.goto('/login')

    // When I fill "email" with "user@example.com"
    await page.fill('[name="email"]', 'user@example.com')

    // And I fill "password" with "password123"
    await page.fill('[name="password"]', 'password123')

    // And I click "Login"
    await page.click('button:has-text("Login")')

    // Then I am redirected to the dashboard
    await expect(page).toHaveURL(/dashboard/)

    // And I see "Welcome back"
    await expect(page.locator('text=Welcome back')).toBeVisible()
  })

  test('AC2: Invalid password', async ({ page }) => {
    // Given I am on the login page
    await page.goto('/login')

    // When I fill "email" with "user@example.com"
    await page.fill('[name="email"]', 'user@example.com')

    // And I fill "password" with "wrong"
    await page.fill('[name="password"]', 'wrong')

    // And I click "Login"
    await page.click('button:has-text("Login")')

    // Then I see "Invalid credentials"
    await expect(page.locator('text=Invalid credentials')).toBeVisible()
  })

})

Gherkin to Playwright Mapping

GherkinPlaywright Code
Given I am on "{url}"await page.goto('{url}')
When I click "{text}"await page.click('text={text}')
When I click the "{selector}" buttonawait page.click('{selector}')
When I fill "{field}" with "{value}"await page.fill('[name="{field}"]', '{value}')
When I select "{option}" from "{field}"await page.selectOption('[name="{field}"]', '{option}')
When I press "{key}"await page.keyboard.press('{key}')
Then I see "{text}"await expect(page.locator('text={text}')).toBeVisible()
Then I am redirected to "{url}"await expect(page).toHaveURL(/{url}/)
Then the "{element}" is visibleawait expect(page.locator('{element}')).toBeVisible()
Then the "{element}" is not visibleawait expect(page.locator('{element}')).not.toBeVisible()

File Naming Convention

  • Story ID in filename: {story-id}-{feature-slug}.spec.ts
  • Examples:
    • us-001-user-login.spec.ts
    • us-042-password-reset.spec.ts
    • us-103-checkout-flow.spec.ts

See: e2e/playwright-patterns.md for complete mapping reference.

Step 7: Run E2E Tests

Execute the generated Playwright tests to validate acceptance criteria.

Run Tests

# Run specific test file
npx playwright test tests/e2e/user-login.spec.ts

# Run all E2E tests
npx playwright test tests/e2e/

# Run with UI mode for debugging
npx playwright test tests/e2e/user-login.spec.ts --ui

Verify Results

All acceptance criteria must pass:

Running 2 tests using 1 worker

  ✓ US-001: User Login › AC1: Successful login (2.1s)
  ✓ US-001: User Login › AC2: Invalid password (1.8s)

  2 passed (4.2s)

Handle Failures

If tests fail:

  1. Review the error - Check which AC failed and why
  2. Fix the implementation - Update component/page code
  3. Re-run tests - Verify fix works
  4. Do NOT modify the test unless the AC was wrong
If AC fails → Fix implementation, NOT the test
If AC is wrong → Update user story first, then regenerate test

Step 8: Generate Report

REQUIRED: Create a JSON report with E2E validation results.

Location: .qa-reports/{uuid}.vue-development-skill.json

Generate a UUID and write the report:

{
  "id": "generated-uuid-here",
  "skill": "vue-development",
  "timestamp": "2025-12-01T10:30:00Z",
  "task_description": "Created MyComponent button with click handling",

  "user_story": {
    "id": "US-001",
    "title": "User Login",
    "persona": "registered user",
    "goal": "to login with my credentials",
    "benefit": "I can access my account"
  },

  "files": {
    "created": ["src/components/MyComponent.vue"],
    "modified": [],
    "test_files": ["src/components/__tests__/MyComponent.spec.ts"],
    "e2e_test_files": ["tests/e2e/us-001-user-login.spec.ts"]
  },

  "tdd": {
    "tests_written_first": true,
    "test_command": "npm run test -- MyComponent.spec.ts",
    "tests_passing": true,
    "coverage_estimate": "high"
  },

  "qa": {
    "standard": "ISO/IEC 25010:2023",
    "score": 9.1,
    "status": "PASS",
    "checklist": {
      "functional_suitability": { "passed": 3, "total": 3, "issues": [] },
      "performance_efficiency": { "passed": 3, "total": 3, "issues": [] },
      "compatibility": { "passed": 2, "total": 2, "issues": [] },
      "interaction_capability": { "passed": 7, "total": 8, "issues": ["user assistance: no helper text on password field"] },
      "reliability": { "passed": 4, "total": 4, "issues": [] },
      "security": { "passed": 4, "total": 4, "na": ["non_repudiation", "accountability"], "issues": ["N/A: pure auth form, no audit trail required"] },
      "maintainability": { "passed": 5, "total": 5, "issues": [] },
      "flexibility": { "passed": 4, "total": 4, "issues": [] },
      "safety": { "passed": 0, "total": 0, "na": ["operational_constraint", "risk_identification", "fail_safe", "hazard_warning", "safe_integration"], "issues": ["N/A: no destructive or irreversible operations"] }
    }
  },

  "e2e_validation": {
    "test_file": "tests/e2e/us-001-user-login.spec.ts",
    "test_command": "npx playwright test tests/e2e/us-001-user-login.spec.ts",
    "executed": true,
    "acceptance_criteria": [
      {
        "id": "AC1",
        "title": "Successful login",
        "gherkin": "Given I am on login page\nWhen I fill credentials\nThen I see dashboard",
        "status": "PASS"
      },
      {
        "id": "AC2",
        "title": "Invalid password",
        "gherkin": "Given I am on login page\nWhen I enter wrong password\nThen I see error",
        "status": "PASS"
      }
    ],
    "passed": 2,
    "failed": 0,
    "status": "PASS"
  },

  "completion": {
    "unit_tests": "PASS",
    "qa_checklist": "PASS",
    "e2e_validation": "PASS",
    "overall": "COMPLETE"
  }
}

Quality Thresholds

ScoreStatusAction
9-10PASSReady for E2E validation
7-8ACCEPTABLEReady, but note issues
0-6NEEDS_WORKFix issues before handoff

Formula: score = (checks_passed / total_applicable_checks) × 10

File References

  • QA Checklist: See qa/vue-checklist.md for full criteria (ISO/IEC 25010:2023, 9 characteristics / ~40 sub-characteristics)
  • Report Schema: See qa/report-template.json for JSON structure
  • TDD Guide: See tdd/workflow.md for detailed process
  • Testing Patterns: See tdd/testing-patterns.md for Vitest examples
  • Vue Patterns: See patterns/composition-api.md
  • Nuxt Patterns: See patterns/nuxt3.md
  • TypeScript: See patterns/typescript.md
  • Debugging: See debugging/common-issues.md
  • E2E Patterns: See e2e/playwright-patterns.md for Gherkin-to-Playwright mapping
  • Acceptance Criteria: See e2e/acceptance-criteria.md for parsing user stories

Important Rules

  1. NEVER skip tests - Write tests before implementation
  2. NEVER skip E2E validation - Validate all acceptance criteria with Playwright
  3. NEVER skip the report - Include E2E results in report
  4. NEVER leave tests failing - All unit tests AND E2E must pass
  5. ALWAYS use TypeScript - No JavaScript, no any
  6. ALWAYS follow Composition API - No Options API
  7. ALWAYS validate against Gherkin AC - If user story provided, all AC must pass