Skip to content

Commit bc5c00b

Browse files
committed
feat: initial cpk-e2e setup
Component discovery, story coverage checker, and Playwright-based E2E render tests for cpk-ui React Native components.
0 parents  commit bc5c00b

12 files changed

Lines changed: 1092 additions & 0 deletions

File tree

.claude/commands/commit.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Commit Skill
2+
3+
Automates commit and PR creation workflow.
4+
5+
## Usage
6+
7+
```text
8+
/commit # Commit on current branch
9+
/commit --pr # New branch + commit + create PR
10+
/commit --pr "PR title" # Specify PR title
11+
```
12+
13+
## Workflow
14+
15+
### Basic Commit (`/commit`)
16+
17+
1. Check changes with `git status`
18+
2. Analyze changes and compose commit message
19+
3. Run `git add -A && git commit`
20+
4. Run `git push`
21+
22+
### Create PR (`/commit --pr`)
23+
24+
1. Check changes with `git status`
25+
2. Analyze changes for branch name and commit message
26+
3. Create new branch (`feat/`, `fix/`, `docs/`, etc.)
27+
4. Run `git add -A && git commit`
28+
5. Run `git push -u origin <branch>`
29+
6. Run `gh pr create`
30+
31+
## Commit Message Format
32+
33+
```text
34+
<type>: <description>
35+
```
36+
37+
Types:
38+
- `feat`: New feature
39+
- `fix`: Bug fix
40+
- `docs`: Documentation
41+
- `style`: Formatting
42+
- `refactor`: Code refactoring
43+
- `test`: Tests
44+
- `chore`: Maintenance
45+
- `ci`: CI/CD changes
46+
47+
**IMPORTANT**: NEVER add Co-Authored-By
48+
49+
## Important Notes
50+
51+
- Never commit sensitive files (.env, credentials, etc.)
52+
- Split large changes into multiple commits

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules/
2+
dist/
3+
test-results/
4+
playwright-report/
5+
blob-report/
6+
screenshots/
7+
.claude/settings.local.json

CLAUDE.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# CPK-E2E
2+
3+
E2E render testing tool for [cpk-ui](https://github.com/crossplatformkorea/cpk-ui) React Native components.
4+
5+
## Project Structure
6+
7+
```
8+
cpk-e2e/
9+
├── scripts/
10+
│ ├── discover-components.ts # Parse cpk-ui source to find all components
11+
│ ├── check-coverage.ts # Verify all components have story coverage
12+
│ └── run-e2e.ts # Full E2E pipeline orchestrator
13+
├── tests/
14+
│ └── components.spec.ts # Playwright tests that crawl all stories
15+
├── screenshots/ # Auto-generated screenshots (gitignored)
16+
├── playwright.config.ts
17+
└── package.json
18+
```
19+
20+
## How It Works
21+
22+
1. **Discover**: Parses `cpk-ui/src/index.tsx` to find all exported components
23+
2. **Build**: Builds cpk-ui's Storybook as static web app
24+
3. **Coverage**: Checks which components have stories (and which don't)
25+
4. **Test**: Playwright opens each story in a headless browser and checks:
26+
- No console errors
27+
- No React error boundaries
28+
- No uncaught exceptions
29+
- Component actually renders (not empty)
30+
5. **Screenshot**: Saves a screenshot of each story for visual regression
31+
32+
## Prerequisites
33+
34+
- cpk-ui must be cloned at `../cpk-ui` (sibling directory)
35+
- Storybook must be buildable in cpk-ui (`bun run build-storybook`)
36+
37+
## Commands
38+
39+
```bash
40+
bun install # Install dependencies
41+
bun run discover # List all cpk-ui components
42+
bun run check-coverage # Check story coverage
43+
bun run test # Run Playwright tests (auto-starts server)
44+
bun run test:headed # Run with visible browser
45+
bun run test:ui # Interactive Playwright UI
46+
bun run e2e # Full pipeline (discover + build + test)
47+
bun run e2e -- --skip-build # Skip Storybook rebuild
48+
bun run report # View HTML test report
49+
```
50+
51+
## Adding New Tests
52+
53+
### Testing a specific component
54+
55+
Add a new test file in `tests/`:
56+
57+
```ts
58+
// tests/button.spec.ts
59+
import {test, expect} from '@playwright/test';
60+
61+
test('Button renders all variants', async ({page}) => {
62+
// Story ID format: category-componentname--storyname
63+
await page.goto('/iframe.html?id=ui-button--primary&viewMode=story');
64+
await expect(page.locator('button')).toBeVisible();
65+
});
66+
```
67+
68+
### Testing interactions
69+
70+
```ts
71+
test('Button click triggers action', async ({page}) => {
72+
await page.goto('/iframe.html?id=ui-button--primary&viewMode=story');
73+
await page.click('button');
74+
// Check for state changes, navigation, etc.
75+
});
76+
```
77+
78+
## Architecture Decisions
79+
80+
- **Storybook as render target**: Components are already configured with proper props in stories. No need to guess default props.
81+
- **Playwright over Detox/Maestro**: Tests run on web (react-native-web) which catches most render errors. No simulator needed.
82+
- **Separate repo**: Keeps E2E concerns isolated from the component library. Can test multiple versions/branches.
83+
- **Screenshot-based**: Every story gets a screenshot saved. Future: add visual regression comparison.
84+
85+
## Future Roadmap
86+
87+
- [ ] Visual regression with screenshot comparison (baseline vs current)
88+
- [ ] Accessibility audits (axe-core integration)
89+
- [ ] Performance metrics (render time per component)
90+
- [ ] Mobile viewport testing
91+
- [ ] Dark mode testing
92+
- [ ] CI integration with cpk-ui (trigger on PR)
93+
- [ ] Test interaction stories (click, input, gesture)
94+
- [ ] Cross-browser testing (Firefox, Safari)

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# cpk-e2e
2+
3+
E2E render testing for [cpk-ui](https://github.com/crossplatformkorea/cpk-ui) React Native components.
4+
5+
Automatically discovers all components, crawls their Storybook stories, and verifies they render without errors.
6+
7+
## Quick Start
8+
9+
```bash
10+
# Install
11+
bun install
12+
npx playwright install chromium
13+
14+
# Build cpk-ui's Storybook first
15+
cd ../cpk-ui && bun run build-storybook && cd ../cpk-e2e
16+
17+
# Run tests
18+
bun run test
19+
20+
# Or run the full pipeline
21+
bun run e2e
22+
```
23+
24+
## What It Tests
25+
26+
- **Console errors** - catches runtime errors like version mismatches
27+
- **React error boundaries** - detects component crashes
28+
- **Empty renders** - finds components that fail silently
29+
- **Uncaught exceptions** - catches unhandled promise rejections
30+
- **Screenshots** - saves every story for visual review
31+
32+
## Commands
33+
34+
| Command | Description |
35+
|---------|-------------|
36+
| `bun run discover` | List all components found in cpk-ui |
37+
| `bun run check-coverage` | Show which components are missing stories |
38+
| `bun run test` | Run all E2E tests |
39+
| `bun run test:headed` | Run with visible browser |
40+
| `bun run test:ui` | Interactive Playwright UI |
41+
| `bun run e2e` | Full pipeline (discover + build + test) |
42+
| `bun run report` | View HTML test report |
43+
44+
## Requirements
45+
46+
- [cpk-ui](https://github.com/crossplatformkorea/cpk-ui) cloned as sibling directory (`../cpk-ui`)
47+
- Bun
48+
- Node.js 20+

bun.lock

Lines changed: 86 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "cpk-e2e",
3+
"version": "0.1.0",
4+
"private": true,
5+
"description": "E2E render testing tool for cpk-ui React Native components",
6+
"scripts": {
7+
"discover": "tsx scripts/discover-components.ts",
8+
"check-coverage": "tsx scripts/check-coverage.ts",
9+
"build-storybook": "cd ../cpk-ui && STORYBOOK=1 npx storybook build -o storybook-static",
10+
"serve": "npx http-server ../cpk-ui/storybook-static -p 6006 --silent",
11+
"test": "playwright test",
12+
"test:headed": "playwright test --headed",
13+
"test:ui": "playwright test --ui",
14+
"test:debug": "playwright test --debug",
15+
"e2e": "tsx scripts/run-e2e.ts",
16+
"report": "playwright show-report"
17+
},
18+
"devDependencies": {
19+
"@playwright/test": "^1.52.0",
20+
"tsx": "^4.19.0",
21+
"typescript": "~5.9.3"
22+
}
23+
}

playwright.config.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {defineConfig, devices} from '@playwright/test';
2+
3+
export default defineConfig({
4+
testDir: './tests',
5+
fullyParallel: true,
6+
forbidOnly: !!process.env.CI,
7+
retries: process.env.CI ? 2 : 0,
8+
workers: process.env.CI ? 1 : undefined,
9+
reporter: [
10+
['html', {open: 'never'}],
11+
['list'],
12+
],
13+
timeout: 180_000,
14+
15+
use: {
16+
baseURL: 'http://localhost:6006',
17+
trace: 'on-first-retry',
18+
screenshot: 'on',
19+
},
20+
21+
projects: [
22+
{
23+
name: 'chromium',
24+
use: {...devices['Desktop Chrome']},
25+
},
26+
{
27+
name: 'mobile-chrome',
28+
use: {...devices['Pixel 5']},
29+
},
30+
],
31+
32+
// Auto-start storybook server before tests
33+
webServer: {
34+
command: 'npx http-server ../cpk-ui/storybook-static -p 6006 --silent',
35+
port: 6006,
36+
reuseExistingServer: !process.env.CI,
37+
timeout: 30_000,
38+
},
39+
});

0 commit comments

Comments
 (0)