🎯

qa-interaction

🎯Skill

from shaul1991/shaul-agents-plugin

VibeIndex|
What it does

Designs and executes comprehensive user interaction and end-to-end tests using Playwright, focusing on UX/UI specifications and detailed test scenarios.

πŸ“¦

Part of

shaul1991/shaul-agents-plugin(18 items)

qa-interaction

Installation

npxRun with npx
npx playwright test
πŸ“– Extracted from docs: shaul1991/shaul-agents-plugin
1Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

QA Interaction Agent. μ‚¬μš©μž μΈν„°λž™μ…˜ ν…ŒμŠ€νŠΈ κ³„νš 및 Playwright E2E ν…ŒμŠ€νŠΈ μž‘μ„±μ„ λ‹΄λ‹Ήν•©λ‹ˆλ‹€. UX/UI λͺ…μ„Έ 기반의 μƒμ„Έν•œ ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μ„€κ³„ν•©λ‹ˆλ‹€.

Overview

# 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"]', 'test@example.com');

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"]', 'new@example.com');

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: [ν”Œλ‘œμš°λͺ…]

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/

More from this repository10

🎯
backend-reviewer🎯Skill

Reviews backend code comprehensively, checking TypeScript, NestJS patterns, security, performance, and providing detailed, actionable feedback.

🎯
backend-golang🎯Skill

Develops high-performance Go backend services using Gin, Echo, GORM, and microservice architectures with best practices.

🎯
pm-planner🎯Skill

Helps project managers plan and track project tasks, milestones, and timelines using AI-powered scheduling and prioritization.

🎯
dba-architect🎯Skill

Assists database architects in designing, optimizing, and modeling complex database schemas with intelligent recommendations and structural insights.

🎯
pm-analyst🎯Skill

Analyzes project management data, generating insights and recommendations for improving team productivity and project efficiency.

🎯
frontend-api🎯Skill

Generates and integrates frontend API clients, implementing robust data fetching and client-side API interaction strategies.

🎯
frontend-hook🎯Skill

Designs and implements custom React hooks with advanced state management and side effect handling.

🎯
qa-analyst🎯Skill

Assists quality assurance analysts in documenting, tracking, and managing software testing processes and defect reports efficiently.

🎯
devops-infra🎯Skill

Manages DevOps infrastructure by handling Docker resources, scaling, backup, network configuration, and system maintenance tasks across development and production environments.

🎯
data-engineer🎯Skill

Automates data engineering tasks by providing tools and workflows for extracting, transforming, and loading data across various sources and formats.