home / skills / shaul1991 / shaul-agents-plugin / qa-interaction

qa-interaction skill

/skills/qa-interaction

This skill plans user interaction tests and writes Playwright E2E tests based on UX/UI specifications to ensure quality flows.

npx playbooks add skill shaul1991/shaul-agents-plugin --skill qa-interaction

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
8.2 KB
---
name: qa-interaction
description: QA Interaction Agent. 사용자 인터랙션 테스트 계획 및 Playwright E2E 테스트 작성을 담당합니다. UX/UI 명세 기반의 상세한 테스트 시나리오를 설계합니다.
allowed-tools: Bash(npm:*, npx:playwright*), Read, Write, Edit, Grep, Glob, mcp__playwright__*
---

# QA Interaction Agent

## 역할

사용자 인터랙션을 중심으로 테스트를 계획하고, Playwright를 사용하여 E2E 테스트를 작성/실행합니다.

## 담당 업무

### 1. 사용자 인터랙션 테스트 계획
- UX/UI 명세 기반 테스트 시나리오
- 사용자 플로우별 테스트 케이스
- 상태 전환 테스트

### 2. Playwright E2E 테스트 작성
- 페이지 네비게이션 테스트
- 폼 입력 및 제출 테스트
- 인터랙션 테스트 (클릭, 호버, 드래그)

### 3. 접근성 테스트
- 키보드 네비게이션
- 스크린 리더 호환성
- WCAG 준수 확인

## 테스트 시나리오 템플릿

### 사용자 플로우 테스트

```markdown
## 테스트 시나리오: [플로우명]

### 전제 조건
- [ ] 사용자 로그인 상태
- [ ] 필요한 데이터 준비

### 테스트 단계
| # | 동작 | 예상 결과 | 검증 방법 |
|---|------|----------|----------|
| 1 | 페이지 접근 | 페이지 로드 완료 | URL, 제목 확인 |
| 2 | 버튼 클릭 | 모달 표시 | 요소 visibility |
| 3 | 폼 입력 | 유효성 통과 | 에러 메시지 없음 |
| 4 | 제출 | 성공 메시지 | 토스트/알림 |

### 엣지 케이스
- [ ] 네트워크 오류 시
- [ ] 타임아웃 발생 시
- [ ] 동시 요청 시
```

## Playwright 테스트 패턴

### 기본 페이지 테스트

```typescript
import { test, expect } from '@playwright/test';

test.describe('User Profile Page', () => {
  test.beforeEach(async ({ page }) => {
    // 로그인 및 페이지 접근
    await page.goto('/login');
    await page.fill('[data-testid="email"]', '[email protected]');
    await page.fill('[data-testid="password"]', 'password123');
    await page.click('[data-testid="login-button"]');
    await page.waitForURL('/dashboard');
  });

  test('should display user profile', async ({ page }) => {
    await page.goto('/profile');

    await expect(page.locator('[data-testid="user-name"]')).toBeVisible();
    await expect(page.locator('[data-testid="user-email"]')).toBeVisible();
  });

  test('should edit profile successfully', async ({ page }) => {
    await page.goto('/profile');

    // 편집 모드 진입
    await page.click('[data-testid="edit-button"]');

    // 이름 변경
    await page.fill('[data-testid="name-input"]', 'New Name');

    // 저장
    await page.click('[data-testid="save-button"]');

    // 성공 확인
    await expect(page.locator('[data-testid="success-toast"]')).toBeVisible();
    await expect(page.locator('[data-testid="user-name"]')).toHaveText('New Name');
  });
});
```

### 폼 인터랙션 테스트

```typescript
test.describe('Registration Form', () => {
  test('should validate required fields', async ({ page }) => {
    await page.goto('/register');

    // 빈 폼 제출
    await page.click('[data-testid="submit-button"]');

    // 에러 메시지 확인
    await expect(page.locator('[data-testid="email-error"]')).toHaveText('이메일을 입력하세요');
    await expect(page.locator('[data-testid="password-error"]')).toHaveText('비밀번호를 입력하세요');
  });

  test('should show password strength indicator', async ({ page }) => {
    await page.goto('/register');

    // 약한 비밀번호
    await page.fill('[data-testid="password"]', '123');
    await expect(page.locator('[data-testid="strength-weak"]')).toBeVisible();

    // 강한 비밀번호
    await page.fill('[data-testid="password"]', 'StrongP@ss123!');
    await expect(page.locator('[data-testid="strength-strong"]')).toBeVisible();
  });

  test('should handle form submission', async ({ page }) => {
    await page.goto('/register');

    await page.fill('[data-testid="email"]', '[email protected]');
    await page.fill('[data-testid="password"]', 'SecureP@ss123');
    await page.fill('[data-testid="confirm-password"]', 'SecureP@ss123');
    await page.check('[data-testid="terms-checkbox"]');

    await page.click('[data-testid="submit-button"]');

    // 성공 페이지로 리다이렉트
    await page.waitForURL('/register/success');
    await expect(page.locator('h1')).toHaveText('가입 완료');
  });
});
```

### 상태 전환 테스트

```typescript
test.describe('Shopping Cart', () => {
  test('should update cart count on add', async ({ page }) => {
    await page.goto('/products');

    // 초기 카트 수량
    await expect(page.locator('[data-testid="cart-count"]')).toHaveText('0');

    // 상품 추가
    await page.click('[data-testid="add-to-cart-1"]');

    // 카트 수량 업데이트
    await expect(page.locator('[data-testid="cart-count"]')).toHaveText('1');
  });

  test('should show loading state during checkout', async ({ page }) => {
    await page.goto('/cart');

    await page.click('[data-testid="checkout-button"]');

    // 로딩 상태 확인
    await expect(page.locator('[data-testid="loading-spinner"]')).toBeVisible();

    // 완료 후 리다이렉트
    await page.waitForURL('/checkout/success');
  });
});
```

### 접근성 테스트

```typescript
test.describe('Accessibility', () => {
  test('should be keyboard navigable', async ({ page }) => {
    await page.goto('/');

    // Tab 키로 네비게이션
    await page.keyboard.press('Tab');
    await expect(page.locator(':focus')).toHaveAttribute('data-testid', 'nav-home');

    await page.keyboard.press('Tab');
    await expect(page.locator(':focus')).toHaveAttribute('data-testid', 'nav-products');

    // Enter 키로 활성화
    await page.keyboard.press('Enter');
    await page.waitForURL('/products');
  });

  test('should have proper ARIA labels', async ({ page }) => {
    await page.goto('/');

    // 주요 영역 ARIA 확인
    await expect(page.locator('nav')).toHaveAttribute('aria-label', 'Main navigation');
    await expect(page.locator('main')).toHaveAttribute('role', 'main');
    await expect(page.locator('footer')).toHaveAttribute('role', 'contentinfo');
  });
});
```

### 반응형 테스트

```typescript
test.describe('Responsive Design', () => {
  test('should show mobile menu on small screens', async ({ page }) => {
    // 모바일 뷰포트
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/');

    // 햄버거 메뉴 표시
    await expect(page.locator('[data-testid="mobile-menu-button"]')).toBeVisible();
    await expect(page.locator('[data-testid="desktop-nav"]')).not.toBeVisible();

    // 메뉴 열기
    await page.click('[data-testid="mobile-menu-button"]');
    await expect(page.locator('[data-testid="mobile-nav"]')).toBeVisible();
  });

  test('should show desktop nav on large screens', async ({ page }) => {
    // 데스크톱 뷰포트
    await page.setViewportSize({ width: 1280, height: 720 });
    await page.goto('/');

    await expect(page.locator('[data-testid="desktop-nav"]')).toBeVisible();
    await expect(page.locator('[data-testid="mobile-menu-button"]')).not.toBeVisible();
  });
});
```

## 테스트 명령어

```bash
# Playwright 테스트 실행
npx playwright test

# 특정 파일 실행
npx playwright test user-profile.spec.ts

# UI 모드로 실행
npx playwright test --ui

# 디버그 모드
npx playwright test --debug

# 특정 브라우저
npx playwright test --project=chromium

# 리포트 생성
npx playwright show-report
```

## 테스트 계획 문서 구조

```markdown
# [기능명] 인터랙션 테스트 계획

## 1. 테스트 범위
### 포함
### 제외

## 2. 테스트 환경
- 브라우저: Chrome, Firefox, Safari
- 디바이스: Desktop, Tablet, Mobile

## 3. 사용자 플로우별 테스트
### 플로우 1: [플로우명]
### 플로우 2: [플로우명]

## 4. 엣지 케이스

## 5. 성능 기준
- 페이지 로드: < 3초
- 인터랙션 응답: < 100ms

## 6. 접근성 요구사항
- WCAG 2.1 Level AA

## 7. 테스트 데이터
```

## 산출물 위치

- 테스트 계획: `docs/features/<기능명>/test-plans/interaction-tests.md`
- E2E 테스트: `e2e/**/*.spec.ts`
- 테스트 리포트: `playwright-report/`
- 스크린샷: `test-results/`

Overview

This skill is a QA Interaction Agent that plans user-interaction test strategies and writes Playwright end-to-end tests from UX/UI specifications. It generates detailed user-flow scenarios, edge-case matrices, and executable Playwright test suites to validate navigation, forms, state transitions, responsiveness, and accessibility. The agent also defines where artifacts live and how to run tests and reports.

How this skill works

It inspects UX/UI specs and user flows to produce test-plan documents and scenario templates, then translates scenarios into Playwright test files that exercise clicks, hovers, drags, form inputs, navigation, and keyboard interactions. The agent includes accessibility checks (keyboard navigation, ARIA attributes, WCAG validations), responsive viewport tests, and state-transition assertions. It outputs runnable Playwright code, test commands, and locations for reports, screenshots, and artifacts.

When to use it

  • When you need E2E coverage driven by UX/UI specifications
  • When validating complex user flows and state transitions
  • When enforcing accessibility and keyboard navigation requirements
  • When adding automated regression tests for forms and navigation
  • When preparing cross-browser and responsive design verification

Best practices

  • Start from clear UX/UI specs and defined user flows before writing tests
  • Use data-testid attributes to make selectors resilient and readable
  • Separate test plans (docs) from executable test files (e2e/) for traceability
  • Include edge-case and network-failure scenarios in each flow
  • Run accessibility checks and keyboard navigation tests in CI
  • Keep tests deterministic: mock external services or seed test data

Example use cases

  • Generate an interaction test plan for a profile editing flow and create Playwright specs that verify edit/save behaviors and success toasts
  • Write registration form tests that assert validation messages, password strength indicators, and successful redirect on submit
  • Implement cart state tests: add/remove items, update counts, and verify loading states during checkout
  • Create responsive tests that assert mobile hamburger menu behavior and desktop navigation visibility
  • Add accessibility tests that validate ARIA labels, tab order, and screen-reader compatible roles

FAQ

What outputs does the agent produce?

It produces a test-plan document, Playwright .spec.ts files in e2e/, and guidance on running tests and locating reports/screenshots.

How do I run the tests?

Use Playwright CLI commands such as npx playwright test, npx playwright test --project=chromium, or npx playwright test --ui. Reports are available via npx playwright show-report.

Does it cover accessibility?

Yes. It generates keyboard navigation tests, ARIA attribute checks, and WCAG 2.1 Level AA validation steps to include in CI.

Where are artifacts stored?

Standard paths: test plans under docs/features/<feature>/test-plans/, E2E specs under e2e/**/*.spec.ts, test reports in playwright-report/, and screenshots in test-results/.