specweave 1.0.239 → 1.0.241
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +31 -30
- package/README.md +1 -1
- package/bin/specweave.js +16 -0
- package/dist/plugins/specweave-ado/lib/ado-permission-gate.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-permission-gate.js +17 -2
- package/dist/plugins/specweave-ado/lib/ado-permission-gate.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +7 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +53 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +17 -2
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -1
- package/dist/plugins/specweave-testing/lib/playwright-cli-detector.d.ts +1 -0
- package/dist/plugins/specweave-testing/lib/playwright-cli-detector.d.ts.map +1 -1
- package/dist/plugins/specweave-testing/lib/playwright-cli-detector.js +7 -3
- package/dist/plugins/specweave-testing/lib/playwright-cli-detector.js.map +1 -1
- package/dist/plugins/specweave-testing/lib/playwright-cli-runner.d.ts.map +1 -1
- package/dist/plugins/specweave-testing/lib/playwright-cli-runner.js +27 -19
- package/dist/plugins/specweave-testing/lib/playwright-cli-runner.js.map +1 -1
- package/dist/plugins/specweave-testing/lib/playwright-routing.d.ts +8 -0
- package/dist/plugins/specweave-testing/lib/playwright-routing.d.ts.map +1 -1
- package/dist/plugins/specweave-testing/lib/playwright-routing.js +10 -7
- package/dist/plugins/specweave-testing/lib/playwright-routing.js.map +1 -1
- package/dist/src/adapters/agents-md-generator.js +1 -1
- package/dist/src/adapters/agents-md-generator.js.map +1 -1
- package/dist/src/adapters/claude/README.md +1 -1
- package/dist/src/adapters/claude-md-generator.js +1 -1
- package/dist/src/adapters/claude-md-generator.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +10 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/refresh-marketplace.d.ts.map +1 -1
- package/dist/src/cli/commands/refresh-marketplace.js +7 -67
- package/dist/src/cli/commands/refresh-marketplace.js.map +1 -1
- package/dist/src/cli/commands/team.d.ts +20 -0
- package/dist/src/cli/commands/team.d.ts.map +1 -0
- package/dist/src/cli/commands/team.js +101 -0
- package/dist/src/cli/commands/team.js.map +1 -0
- package/dist/src/cli/helpers/init/claude-settings-env.d.ts +16 -0
- package/dist/src/cli/helpers/init/claude-settings-env.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/claude-settings-env.js +44 -0
- package/dist/src/cli/helpers/init/claude-settings-env.js.map +1 -0
- package/dist/src/cli/helpers/init/plugin-installer.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/plugin-installer.js +9 -13
- package/dist/src/cli/helpers/init/plugin-installer.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +12 -6
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.d.ts +2 -0
- package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.js.map +1 -1
- package/dist/src/core/increment/discipline-checker.js +1 -1
- package/dist/src/core/increment/discipline-checker.js.map +1 -1
- package/dist/src/core/increment/status-commands.d.ts.map +1 -1
- package/dist/src/core/increment/status-commands.js +7 -0
- package/dist/src/core/increment/status-commands.js.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts +2 -2
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.js +63 -25
- package/dist/src/core/lazy-loading/llm-plugin-detector.js.map +1 -1
- package/dist/src/core/reflection/reflect-handler.js +2 -2
- package/dist/src/core/reflection/reflect-handler.js.map +1 -1
- package/dist/src/core/session/handoff-context.js +2 -2
- package/dist/src/core/session/handoff-context.js.map +1 -1
- package/dist/src/sync/ado-reconciler.d.ts.map +1 -1
- package/dist/src/sync/ado-reconciler.js +21 -2
- package/dist/src/sync/ado-reconciler.js.map +1 -1
- package/dist/src/sync/engine.d.ts.map +1 -1
- package/dist/src/sync/engine.js +2 -0
- package/dist/src/sync/engine.js.map +1 -1
- package/dist/src/sync/github-reconciler.d.ts.map +1 -1
- package/dist/src/sync/github-reconciler.js +52 -26
- package/dist/src/sync/github-reconciler.js.map +1 -1
- package/dist/src/sync/jira-reconciler.d.ts.map +1 -1
- package/dist/src/sync/jira-reconciler.js +16 -3
- package/dist/src/sync/jira-reconciler.js.map +1 -1
- package/dist/src/sync/providers/ado.d.ts.map +1 -1
- package/dist/src/sync/providers/ado.js +4 -2
- package/dist/src/sync/providers/ado.js.map +1 -1
- package/dist/src/sync/providers/github.d.ts.map +1 -1
- package/dist/src/sync/providers/github.js +11 -0
- package/dist/src/sync/providers/github.js.map +1 -1
- package/dist/src/sync/providers/jira.d.ts.map +1 -1
- package/dist/src/sync/providers/jira.js +14 -2
- package/dist/src/sync/providers/jira.js.map +1 -1
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +31 -6
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/utils/auto-install.js +4 -4
- package/dist/src/utils/auto-install.js.map +1 -1
- package/package.json +2 -2
- package/plugins/FINAL-AUDIT-RECOMMENDATIONS.md +3 -3
- package/plugins/SKILLS-VS-AGENTS.md +1 -1
- package/plugins/specweave/PLUGIN.md +0 -2
- package/plugins/specweave/commands/export-skills.md +1 -1
- package/plugins/specweave/commands/role-orchestrator.md +1 -1
- package/plugins/specweave/hooks/log-decision.sh +6 -0
- package/plugins/specweave/hooks/stop-auto-v5.sh +17 -1
- package/plugins/specweave/hooks/stop-reflect.sh +16 -2
- package/plugins/specweave/hooks/stop-sync.sh +17 -9
- package/plugins/specweave/hooks/user-prompt-submit.sh +119 -35
- package/plugins/specweave/lib/vendor/sync/github-reconciler.js +52 -26
- package/plugins/specweave/lib/vendor/sync/github-reconciler.js.map +1 -1
- package/plugins/specweave/scripts/read-grill-context.sh +149 -0
- package/plugins/specweave/skills/code-review/SKILL.md +608 -0
- package/plugins/specweave/skills/done/SKILL.md +1 -1
- package/plugins/specweave/skills/grill/SKILL.md +91 -0
- package/plugins/specweave/skills/performance/SKILL.md +6 -0
- package/plugins/specweave/skills/security/SKILL.md +7 -0
- package/plugins/specweave/skills/security-patterns/SKILL.md +6 -0
- package/plugins/specweave/skills/tdd-orchestrator/SKILL.md +1 -1
- package/plugins/specweave/skills/team-build/SKILL.md +1 -1
- package/plugins/specweave/skills/team-orchestrate/SKILL.md +1 -1
- package/plugins/specweave/skills/tech-lead/SKILL.md +7 -0
- package/plugins/specweave-ado/lib/ado-permission-gate.js +18 -2
- package/plugins/specweave-ado/lib/ado-permission-gate.ts +19 -2
- package/plugins/specweave-frontend/skills/frontend/SKILL.md +138 -2
- package/plugins/specweave-frontend/skills/i18n-expert/SKILL.md +989 -0
- package/plugins/specweave-github/hooks/github-auto-create-handler.sh +23 -1
- package/plugins/specweave-github/lib/github-feature-sync.js +41 -0
- package/plugins/specweave-github/lib/github-feature-sync.ts +62 -0
- package/plugins/specweave-infrastructure/PLUGIN.md +2 -1
- package/plugins/specweave-infrastructure/skills/gcp-deep-dive/SKILL.md +1172 -0
- package/plugins/specweave-infrastructure/skills/observability/SKILL.md +6 -0
- package/plugins/specweave-infrastructure/skills/opentelemetry/SKILL.md +6 -0
- package/plugins/specweave-jira/lib/jira-permission-gate.js +18 -2
- package/plugins/specweave-jira/lib/jira-permission-gate.ts +19 -2
- package/plugins/specweave-mobile/PLUGIN.md +1 -2
- package/plugins/specweave-mobile/README.md +13 -12
- package/plugins/specweave-mobile/skills/capacitor-ionic/SKILL.md +4 -18
- package/plugins/specweave-mobile/skills/deep-linking-push/SKILL.md +4 -22
- package/plugins/specweave-mobile/skills/expo/SKILL.md +4 -24
- package/plugins/specweave-mobile/skills/mobile-testing/SKILL.md +4 -22
- package/plugins/specweave-mobile/skills/react-native-expert/SKILL.md +404 -47
- package/plugins/specweave-testing/PLUGIN.md +3 -11
- package/plugins/specweave-testing/lib/playwright-cli-detector.js +8 -3
- package/plugins/specweave-testing/lib/playwright-cli-detector.ts +8 -3
- package/plugins/specweave-testing/lib/playwright-cli-runner.js +25 -20
- package/plugins/specweave-testing/lib/playwright-cli-runner.ts +24 -19
- package/plugins/specweave-testing/lib/playwright-routing.js +1 -6
- package/plugins/specweave-testing/lib/playwright-routing.ts +11 -8
- package/plugins/specweave-testing/skills/accessibility-testing/SKILL.md +998 -0
- package/plugins/specweave-testing/skills/e2e-testing/SKILL.md +29 -28
- package/plugins/specweave-testing/skills/mutation-testing/SKILL.md +769 -0
- package/plugins/specweave-testing/skills/performance-testing/SKILL.md +961 -0
- package/plugins/specweave-testing/skills/qa-engineer/SKILL.md +2 -0
- package/plugins/specweave/.specweave/logs/decisions.jsonl +0 -12
- package/plugins/specweave/.specweave/logs/reflect/reflect.log +0 -8
- package/plugins/specweave/.specweave/logs/stop-auto.log +0 -6
- package/plugins/specweave/.specweave/logs/stop-sync.log +0 -10
- package/plugins/specweave/.specweave/state/dashboard.json +0 -43
- package/plugins/specweave/skills/infrastructure/SKILL.md +0 -86
- package/plugins/specweave/skills/qa-lead/SKILL.md +0 -77
- package/plugins/specweave-mobile/skills/mobile-architect/SKILL.md +0 -30
- package/plugins/specweave-testing/commands/e2e-setup.md +0 -1103
- package/plugins/specweave-testing/commands/test-coverage.md +0 -983
- package/plugins/specweave-testing/commands/test-generate.md +0 -1160
- package/plugins/specweave-testing/commands/test-init.md +0 -413
- package/plugins/specweave-testing/commands/ui-automate.md +0 -182
- package/plugins/specweave-testing/commands/ui-inspect.md +0 -82
|
@@ -1,413 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Initialize comprehensive testing infrastructure with Vitest, Playwright, and testing best practices.
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# /sw-testing:test-init
|
|
6
|
-
|
|
7
|
-
Initialize comprehensive testing infrastructure with Vitest, Playwright, and testing best practices.
|
|
8
|
-
|
|
9
|
-
You are an expert testing engineer who sets up production-ready test infrastructure.
|
|
10
|
-
|
|
11
|
-
## Your Task
|
|
12
|
-
|
|
13
|
-
Set up a complete testing framework covering unit tests, integration tests, and E2E tests.
|
|
14
|
-
|
|
15
|
-
### 1. Testing Stack
|
|
16
|
-
|
|
17
|
-
**Unit Testing (Vitest)**:
|
|
18
|
-
- Fast, Vite-powered test runner
|
|
19
|
-
- Compatible with Jest API
|
|
20
|
-
- Built-in coverage (c8/istanbul)
|
|
21
|
-
- ESM and TypeScript support
|
|
22
|
-
- Watch mode for TDD
|
|
23
|
-
|
|
24
|
-
**E2E Testing (Playwright)**:
|
|
25
|
-
- Cross-browser testing (Chromium, Firefox, WebKit)
|
|
26
|
-
- Reliable auto-wait mechanisms
|
|
27
|
-
- Powerful selectors and assertions
|
|
28
|
-
- Parallel test execution
|
|
29
|
-
- Screenshots and video recording
|
|
30
|
-
|
|
31
|
-
**Component Testing**:
|
|
32
|
-
- React Testing Library
|
|
33
|
-
- Vue Testing Library
|
|
34
|
-
- User-centric testing approach
|
|
35
|
-
- Accessibility testing integration
|
|
36
|
-
|
|
37
|
-
### 2. Vitest Configuration
|
|
38
|
-
|
|
39
|
-
**vitest.config.ts**:
|
|
40
|
-
```typescript
|
|
41
|
-
import { defineConfig } from 'vitest/config';
|
|
42
|
-
import react from '@vitejs/plugin-react';
|
|
43
|
-
import path from 'path';
|
|
44
|
-
|
|
45
|
-
export default defineConfig({
|
|
46
|
-
plugins: [react()],
|
|
47
|
-
test: {
|
|
48
|
-
globals: true,
|
|
49
|
-
environment: 'jsdom',
|
|
50
|
-
setupFiles: ['./tests/setup.ts'],
|
|
51
|
-
include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
52
|
-
exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'],
|
|
53
|
-
coverage: {
|
|
54
|
-
provider: 'v8',
|
|
55
|
-
reporter: ['text', 'json', 'html', 'lcov'],
|
|
56
|
-
exclude: [
|
|
57
|
-
'node_modules/',
|
|
58
|
-
'tests/',
|
|
59
|
-
'**/*.d.ts',
|
|
60
|
-
'**/*.config.*',
|
|
61
|
-
'**/mockData',
|
|
62
|
-
],
|
|
63
|
-
all: true,
|
|
64
|
-
lines: 80,
|
|
65
|
-
functions: 80,
|
|
66
|
-
branches: 80,
|
|
67
|
-
statements: 80,
|
|
68
|
-
},
|
|
69
|
-
testTimeout: 10000,
|
|
70
|
-
},
|
|
71
|
-
resolve: {
|
|
72
|
-
alias: {
|
|
73
|
-
'@': path.resolve(__dirname, './src'),
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**tests/setup.ts**:
|
|
80
|
-
```typescript
|
|
81
|
-
import '@testing-library/jest-dom';
|
|
82
|
-
import { cleanup } from '@testing-library/react';
|
|
83
|
-
import { afterEach, vi } from 'vitest';
|
|
84
|
-
|
|
85
|
-
// Cleanup after each test
|
|
86
|
-
afterEach(() => {
|
|
87
|
-
cleanup();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Mock window.matchMedia
|
|
91
|
-
Object.defineProperty(window, 'matchMedia', {
|
|
92
|
-
writable: true,
|
|
93
|
-
value: vi.fn().mockImplementation((query) => ({
|
|
94
|
-
matches: false,
|
|
95
|
-
media: query,
|
|
96
|
-
onchange: null,
|
|
97
|
-
addListener: vi.fn(),
|
|
98
|
-
removeListener: vi.fn(),
|
|
99
|
-
addEventListener: vi.fn(),
|
|
100
|
-
removeEventListener: vi.fn(),
|
|
101
|
-
dispatchEvent: vi.fn(),
|
|
102
|
-
})),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Mock IntersectionObserver
|
|
106
|
-
global.IntersectionObserver = class IntersectionObserver {
|
|
107
|
-
constructor() {}
|
|
108
|
-
disconnect() {}
|
|
109
|
-
observe() {}
|
|
110
|
-
takeRecords() {
|
|
111
|
-
return [];
|
|
112
|
-
}
|
|
113
|
-
unobserve() {}
|
|
114
|
-
} as any;
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### 3. Playwright Configuration
|
|
118
|
-
|
|
119
|
-
**playwright.config.ts**:
|
|
120
|
-
```typescript
|
|
121
|
-
import { defineConfig, devices } from '@playwright/test';
|
|
122
|
-
|
|
123
|
-
export default defineConfig({
|
|
124
|
-
testDir: './tests/e2e',
|
|
125
|
-
fullyParallel: true,
|
|
126
|
-
forbidOnly: !!process.env.CI,
|
|
127
|
-
retries: process.env.CI ? 2 : 0,
|
|
128
|
-
workers: process.env.CI ? 1 : undefined,
|
|
129
|
-
reporter: 'html',
|
|
130
|
-
use: {
|
|
131
|
-
baseURL: 'http://localhost:3000',
|
|
132
|
-
trace: 'on-first-retry',
|
|
133
|
-
screenshot: 'only-on-failure',
|
|
134
|
-
video: 'retain-on-failure',
|
|
135
|
-
},
|
|
136
|
-
projects: [
|
|
137
|
-
{
|
|
138
|
-
name: 'chromium',
|
|
139
|
-
use: { ...devices['Desktop Chrome'] },
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
name: 'firefox',
|
|
143
|
-
use: { ...devices['Desktop Firefox'] },
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: 'webkit',
|
|
147
|
-
use: { ...devices['Desktop Safari'] },
|
|
148
|
-
},
|
|
149
|
-
// Mobile viewports
|
|
150
|
-
{
|
|
151
|
-
name: 'Mobile Chrome',
|
|
152
|
-
use: { ...devices['Pixel 5'] },
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
name: 'Mobile Safari',
|
|
156
|
-
use: { ...devices['iPhone 12'] },
|
|
157
|
-
},
|
|
158
|
-
],
|
|
159
|
-
webServer: {
|
|
160
|
-
command: 'npm run dev',
|
|
161
|
-
url: 'http://localhost:3000',
|
|
162
|
-
reuseExistingServer: !process.env.CI,
|
|
163
|
-
},
|
|
164
|
-
});
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### 4. Test Utilities
|
|
168
|
-
|
|
169
|
-
**tests/utils/test-utils.tsx** (React):
|
|
170
|
-
```typescript
|
|
171
|
-
import { render, RenderOptions } from '@testing-library/react';
|
|
172
|
-
import { ReactElement } from 'react';
|
|
173
|
-
import { BrowserRouter } from 'react-router-dom';
|
|
174
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
175
|
-
|
|
176
|
-
const queryClient = new QueryClient({
|
|
177
|
-
defaultOptions: {
|
|
178
|
-
queries: { retry: false },
|
|
179
|
-
mutations: { retry: false },
|
|
180
|
-
},
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
function AllTheProviders({ children }: { children: React.ReactNode }) {
|
|
184
|
-
return (
|
|
185
|
-
<QueryClientProvider client={queryClient}>
|
|
186
|
-
<BrowserRouter>
|
|
187
|
-
{children}
|
|
188
|
-
</BrowserRouter>
|
|
189
|
-
</QueryClientProvider>
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function customRender(ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) {
|
|
194
|
-
return render(ui, { wrapper: AllTheProviders, ...options });
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export * from '@testing-library/react';
|
|
198
|
-
export { customRender as render };
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**tests/utils/mocks/handlers.ts** (MSW):
|
|
202
|
-
```typescript
|
|
203
|
-
import { http, HttpResponse } from 'msw';
|
|
204
|
-
|
|
205
|
-
export const handlers = [
|
|
206
|
-
http.get('/api/users', () => {
|
|
207
|
-
return HttpResponse.json([
|
|
208
|
-
{ id: '1', name: 'John Doe' },
|
|
209
|
-
{ id: '2', name: 'Jane Smith' },
|
|
210
|
-
]);
|
|
211
|
-
}),
|
|
212
|
-
|
|
213
|
-
http.post('/api/login', async ({ request }) => {
|
|
214
|
-
const { email, password } = await request.json();
|
|
215
|
-
|
|
216
|
-
if (email === 'test@example.com' && password === 'password') {
|
|
217
|
-
return HttpResponse.json({
|
|
218
|
-
token: 'mock-jwt-token',
|
|
219
|
-
user: { id: '1', email },
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return HttpResponse.json(
|
|
224
|
-
{ error: 'Invalid credentials' },
|
|
225
|
-
{ status: 401 }
|
|
226
|
-
);
|
|
227
|
-
}),
|
|
228
|
-
];
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**tests/utils/mocks/server.ts**:
|
|
232
|
-
```typescript
|
|
233
|
-
import { setupServer } from 'msw/node';
|
|
234
|
-
import { handlers } from './handlers';
|
|
235
|
-
|
|
236
|
-
export const server = setupServer(...handlers);
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### 5. Package Dependencies
|
|
240
|
-
|
|
241
|
-
```json
|
|
242
|
-
{
|
|
243
|
-
"devDependencies": {
|
|
244
|
-
"@playwright/test": "^1.40.0",
|
|
245
|
-
"@testing-library/jest-dom": "^6.1.5",
|
|
246
|
-
"@testing-library/react": "^14.1.2",
|
|
247
|
-
"@testing-library/user-event": "^14.5.1",
|
|
248
|
-
"@vitest/coverage-v8": "^1.0.4",
|
|
249
|
-
"@vitest/ui": "^1.0.4",
|
|
250
|
-
"jsdom": "^23.0.1",
|
|
251
|
-
"msw": "^2.0.0",
|
|
252
|
-
"vitest": "^1.0.4"
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### 6. NPM Scripts
|
|
258
|
-
|
|
259
|
-
```json
|
|
260
|
-
{
|
|
261
|
-
"scripts": {
|
|
262
|
-
"test": "vitest",
|
|
263
|
-
"test:ui": "vitest --ui",
|
|
264
|
-
"test:coverage": "vitest --coverage",
|
|
265
|
-
"test:e2e": "playwright test",
|
|
266
|
-
"test:e2e:ui": "playwright test --ui",
|
|
267
|
-
"test:e2e:debug": "playwright test --debug",
|
|
268
|
-
"test:all": "npm run test:coverage && npm run test:e2e"
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
### 7. CI/CD Configuration
|
|
274
|
-
|
|
275
|
-
**GitHub Actions (.github/workflows/test.yml)**:
|
|
276
|
-
```yaml
|
|
277
|
-
name: Tests
|
|
278
|
-
|
|
279
|
-
on: [push, pull_request]
|
|
280
|
-
|
|
281
|
-
jobs:
|
|
282
|
-
test:
|
|
283
|
-
runs-on: ubuntu-latest
|
|
284
|
-
steps:
|
|
285
|
-
- uses: actions/checkout@v4
|
|
286
|
-
- uses: actions/setup-node@v4
|
|
287
|
-
with:
|
|
288
|
-
node-version: '20'
|
|
289
|
-
cache: 'npm'
|
|
290
|
-
|
|
291
|
-
- name: Install dependencies
|
|
292
|
-
run: npm ci
|
|
293
|
-
|
|
294
|
-
- name: Run unit tests
|
|
295
|
-
run: npm run test:coverage
|
|
296
|
-
|
|
297
|
-
- name: Install Playwright Browsers
|
|
298
|
-
run: npx playwright install --with-deps
|
|
299
|
-
|
|
300
|
-
- name: Run E2E tests
|
|
301
|
-
run: npm run test:e2e
|
|
302
|
-
|
|
303
|
-
- name: Upload coverage
|
|
304
|
-
uses: codecov/codecov-action@v3
|
|
305
|
-
with:
|
|
306
|
-
files: ./coverage/lcov.info
|
|
307
|
-
|
|
308
|
-
- name: Upload test results
|
|
309
|
-
if: always()
|
|
310
|
-
uses: actions/upload-artifact@v3
|
|
311
|
-
with:
|
|
312
|
-
name: playwright-report
|
|
313
|
-
path: playwright-report/
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
### 8. Testing Best Practices
|
|
317
|
-
|
|
318
|
-
**Unit Test Example**:
|
|
319
|
-
```typescript
|
|
320
|
-
import { render, screen, fireEvent } from './utils/test-utils';
|
|
321
|
-
import { LoginForm } from '@/components/LoginForm';
|
|
322
|
-
|
|
323
|
-
describe('LoginForm', () => {
|
|
324
|
-
it('renders login form correctly', () => {
|
|
325
|
-
render(<LoginForm />);
|
|
326
|
-
expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
|
|
327
|
-
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
|
|
328
|
-
expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument();
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
it('shows validation errors for empty fields', async () => {
|
|
332
|
-
render(<LoginForm />);
|
|
333
|
-
fireEvent.click(screen.getByRole('button', { name: /login/i }));
|
|
334
|
-
|
|
335
|
-
expect(await screen.findByText(/email is required/i)).toBeInTheDocument();
|
|
336
|
-
expect(await screen.findByText(/password is required/i)).toBeInTheDocument();
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
it('submits form with valid data', async () => {
|
|
340
|
-
const onSubmit = vi.fn();
|
|
341
|
-
render(<LoginForm onSubmit={onSubmit} />);
|
|
342
|
-
|
|
343
|
-
fireEvent.change(screen.getByLabelText(/email/i), {
|
|
344
|
-
target: { value: 'test@example.com' },
|
|
345
|
-
});
|
|
346
|
-
fireEvent.change(screen.getByLabelText(/password/i), {
|
|
347
|
-
target: { value: 'password123' },
|
|
348
|
-
});
|
|
349
|
-
fireEvent.click(screen.getByRole('button', { name: /login/i }));
|
|
350
|
-
|
|
351
|
-
await waitFor(() => {
|
|
352
|
-
expect(onSubmit).toHaveBeenCalledWith({
|
|
353
|
-
email: 'test@example.com',
|
|
354
|
-
password: 'password123',
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
**E2E Test Example**:
|
|
362
|
-
```typescript
|
|
363
|
-
import { test, expect } from '@playwright/test';
|
|
364
|
-
|
|
365
|
-
test.describe('Authentication Flow', () => {
|
|
366
|
-
test('should allow user to login', async ({ page }) => {
|
|
367
|
-
await page.goto('/login');
|
|
368
|
-
|
|
369
|
-
await page.fill('input[name="email"]', 'test@example.com');
|
|
370
|
-
await page.fill('input[name="password"]', 'password123');
|
|
371
|
-
await page.click('button[type="submit"]');
|
|
372
|
-
|
|
373
|
-
await expect(page).toHaveURL('/dashboard');
|
|
374
|
-
await expect(page.locator('h1')).toContainText('Dashboard');
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
test('should show error for invalid credentials', async ({ page }) => {
|
|
378
|
-
await page.goto('/login');
|
|
379
|
-
|
|
380
|
-
await page.fill('input[name="email"]', 'wrong@example.com');
|
|
381
|
-
await page.fill('input[name="password"]', 'wrongpassword');
|
|
382
|
-
await page.click('button[type="submit"]');
|
|
383
|
-
|
|
384
|
-
await expect(page.locator('[role="alert"]')).toContainText(
|
|
385
|
-
'Invalid credentials'
|
|
386
|
-
);
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
## Workflow
|
|
392
|
-
|
|
393
|
-
1. Ask about testing requirements and existing setup
|
|
394
|
-
2. Install testing dependencies (Vitest, Playwright, Testing Library)
|
|
395
|
-
3. Create Vitest configuration
|
|
396
|
-
4. Create Playwright configuration
|
|
397
|
-
5. Set up test utilities and helpers
|
|
398
|
-
6. Configure MSW for API mocking
|
|
399
|
-
7. Add test scripts to package.json
|
|
400
|
-
8. Create example tests
|
|
401
|
-
9. Set up CI/CD workflow
|
|
402
|
-
10. Provide testing guidelines and best practices
|
|
403
|
-
|
|
404
|
-
## When to Use
|
|
405
|
-
|
|
406
|
-
- Starting new projects with testing
|
|
407
|
-
- Migrating from Jest to Vitest
|
|
408
|
-
- Adding E2E testing to existing projects
|
|
409
|
-
- Setting up CI/CD testing pipeline
|
|
410
|
-
- Improving test coverage
|
|
411
|
-
- Implementing TDD workflow
|
|
412
|
-
|
|
413
|
-
Initialize production-ready testing infrastructure with modern tools!
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Create and execute automated browser workflows using Playwright for testing, web scraping, form automation, and UI interaction sequences.
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# UI Automate - Browser Automation Workflows
|
|
6
|
-
|
|
7
|
-
Create and execute automated browser workflows using Playwright. Generate scripts for testing, web scraping, form automation, and UI interaction sequences.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
/sw-ui:ui-automate <workflow-name> [options]
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## What I Do
|
|
16
|
-
|
|
17
|
-
1. **Workflow Planning**: Define step-by-step browser automation sequences
|
|
18
|
-
2. **Script Generation**: Create Playwright TypeScript/JavaScript code (code-first approach)
|
|
19
|
-
3. **Error Handling**: Add retry logic, timeouts, and fallbacks
|
|
20
|
-
4. **Output Collection**: Capture screenshots, data, and validation results
|
|
21
|
-
|
|
22
|
-
> **Why Code-First?** Anthropic research shows [code execution beats MCP tool calls](https://www.anthropic.com/engineering/code-execution-with-mcp) with 98% token reduction. Playwright code is reusable, committable, CI-runnable, and deterministic.
|
|
23
|
-
|
|
24
|
-
> **CLI Mode Available**: When `@playwright/cli` is installed, this command routes to the CLI by default for maximum token efficiency (~250 chars per interaction vs ~5K+ via MCP). The CLI keeps browser state external and returns file references instead of inline DOM trees. Install: `npm install -g @playwright/cli@latest`
|
|
25
|
-
|
|
26
|
-
## Workflow Types
|
|
27
|
-
|
|
28
|
-
### 1. Form Automation
|
|
29
|
-
```bash
|
|
30
|
-
/sw-ui:ui-automate form-fill --url https://example.com/form \
|
|
31
|
-
--fields "email=test@example.com,name=John Doe"
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 2. Data Extraction
|
|
35
|
-
```bash
|
|
36
|
-
/sw-ui:ui-automate scrape --url https://example.com/products \
|
|
37
|
-
--selectors "title=h1.product-title,price=.price"
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 3. UI Testing Sequence
|
|
41
|
-
```bash
|
|
42
|
-
/sw-ui:ui-automate test-login --url https://example.com/login \
|
|
43
|
-
--steps "fill:email,fill:password,click:submit,wait:dashboard"
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 4. Screenshot Capture
|
|
47
|
-
```bash
|
|
48
|
-
/sw-ui:ui-automate screenshot --url https://example.com \
|
|
49
|
-
--fullPage --output screenshots/homepage.png
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### 5. Multi-Page Navigation
|
|
53
|
-
```bash
|
|
54
|
-
/sw-ui:ui-automate navigate --start https://example.com \
|
|
55
|
-
--flow "home>products>cart>checkout"
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Options
|
|
59
|
-
|
|
60
|
-
### General Options
|
|
61
|
-
- `--url <url>` - Starting URL for automation
|
|
62
|
-
- `--browser <browser>` - chromium, firefox, webkit (default: chromium)
|
|
63
|
-
- `--headless` - Run in headless mode (default: true)
|
|
64
|
-
- `--output <path>` - Output directory for artifacts
|
|
65
|
-
|
|
66
|
-
### Workflow Options
|
|
67
|
-
- `--steps <steps>` - Comma-separated list of actions
|
|
68
|
-
- `--selectors <selectors>` - CSS selectors for elements
|
|
69
|
-
- `--fields <fields>` - Form field values (key=value pairs)
|
|
70
|
-
- `--wait <selector>` - Wait for element before proceeding
|
|
71
|
-
- `--timeout <ms>` - Max time to wait for operations (default: 30000)
|
|
72
|
-
|
|
73
|
-
### Data Collection
|
|
74
|
-
- `--screenshot` - Capture screenshots at each step
|
|
75
|
-
- `--extract <selector>` - Extract text/attributes from elements
|
|
76
|
-
- `--save-html` - Save page HTML at key steps
|
|
77
|
-
|
|
78
|
-
## Generated Script Features
|
|
79
|
-
|
|
80
|
-
### TypeScript Example
|
|
81
|
-
```typescript
|
|
82
|
-
import { chromium, Browser, Page } from 'playwright';
|
|
83
|
-
|
|
84
|
-
async function automateWorkflow() {
|
|
85
|
-
const browser: Browser = await chromium.launch({ headless: true });
|
|
86
|
-
const page: Page = await browser.newPage();
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
// Step 1: Navigate
|
|
90
|
-
await page.goto('https://example.com', { waitUntil: 'networkidle' });
|
|
91
|
-
|
|
92
|
-
// Step 2: Fill form
|
|
93
|
-
await page.fill('#email', 'test@example.com');
|
|
94
|
-
await page.fill('#password', 'secure-password');
|
|
95
|
-
|
|
96
|
-
// Step 3: Submit
|
|
97
|
-
await page.click('button[type="submit"]');
|
|
98
|
-
|
|
99
|
-
// Step 4: Wait for navigation
|
|
100
|
-
await page.waitForSelector('.dashboard', { timeout: 5000 });
|
|
101
|
-
|
|
102
|
-
// Step 5: Capture result
|
|
103
|
-
await page.screenshot({ path: 'result.png', fullPage: true });
|
|
104
|
-
|
|
105
|
-
console.log('✓ Automation completed successfully');
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error('✗ Automation failed:', error.message);
|
|
108
|
-
await page.screenshot({ path: 'error.png' });
|
|
109
|
-
throw error;
|
|
110
|
-
} finally {
|
|
111
|
-
await browser.close();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
automateWorkflow();
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Use Cases
|
|
119
|
-
|
|
120
|
-
### 1. Regression Testing
|
|
121
|
-
Automate critical user flows to catch UI regressions early.
|
|
122
|
-
|
|
123
|
-
### 2. Data Collection
|
|
124
|
-
Extract product information, prices, availability from multiple pages.
|
|
125
|
-
|
|
126
|
-
### 3. Load Testing
|
|
127
|
-
Simulate multiple users interacting with the application.
|
|
128
|
-
|
|
129
|
-
### 4. Visual Regression
|
|
130
|
-
Capture screenshots across environments to detect visual changes.
|
|
131
|
-
|
|
132
|
-
### 5. Form Submission
|
|
133
|
-
Bulk-fill forms with test data for QA purposes.
|
|
134
|
-
|
|
135
|
-
## Error Handling
|
|
136
|
-
|
|
137
|
-
### Retry Logic
|
|
138
|
-
```typescript
|
|
139
|
-
await page.click('button', { timeout: 5000 })
|
|
140
|
-
.catch(async () => {
|
|
141
|
-
console.log('Retrying click...');
|
|
142
|
-
await page.click('button', { force: true });
|
|
143
|
-
});
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Fallback Selectors
|
|
147
|
-
```typescript
|
|
148
|
-
const selectors = ['#submit', '.submit-btn', 'button[type="submit"]'];
|
|
149
|
-
for (const selector of selectors) {
|
|
150
|
-
if (await page.locator(selector).count() > 0) {
|
|
151
|
-
await page.click(selector);
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Best Practices
|
|
158
|
-
|
|
159
|
-
1. **Use Stable Selectors**: Prefer data-testid attributes over CSS classes
|
|
160
|
-
2. **Add Explicit Waits**: Don't rely on implicit timeouts
|
|
161
|
-
3. **Handle Errors Gracefully**: Capture screenshots on failures
|
|
162
|
-
4. **Clean Up Resources**: Always close browsers in finally blocks
|
|
163
|
-
5. **Avoid Hardcoded Delays**: Use waitForSelector instead of setTimeout
|
|
164
|
-
|
|
165
|
-
## Limitations
|
|
166
|
-
|
|
167
|
-
- Requires Playwright installation
|
|
168
|
-
- Cannot bypass CAPTCHAs or bot detection
|
|
169
|
-
- May fail on dynamically loaded content without proper waits
|
|
170
|
-
- Performance depends on network speed and page complexity
|
|
171
|
-
|
|
172
|
-
## Related Commands
|
|
173
|
-
|
|
174
|
-
- `/sw-ui:ui-inspect` - Inspect page elements for selectors
|
|
175
|
-
- `/sw-testing:e2e-setup` - Set up full E2E testing framework
|
|
176
|
-
- `/sw-testing:test-generate` - Generate test files from automation scripts
|
|
177
|
-
|
|
178
|
-
## Environment Variables
|
|
179
|
-
|
|
180
|
-
- `PLAYWRIGHT_BROWSERS_PATH` - Custom browser binaries location
|
|
181
|
-
- `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` - Skip browser download on install
|
|
182
|
-
- `HEADLESS` - Default headless mode (true/false)
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Inspect web page elements using browser automation to identify selectors, attributes, and structure for testing and scraping.
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# UI Inspect - Browser Element Inspection
|
|
6
|
-
|
|
7
|
-
Inspect web page elements using browser automation tools. Helps identify selectors, attributes, and structure for automated testing and web scraping.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
/sw-ui:ui-inspect <url> [options]
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## What I Do
|
|
16
|
-
|
|
17
|
-
1. **Load Target Page**: Launch browser and navigate to the specified URL
|
|
18
|
-
2. **Interactive Inspection**: Use browser DevTools to inspect elements
|
|
19
|
-
3. **Extract Selectors**: Generate CSS/XPath selectors for identified elements
|
|
20
|
-
4. **Element Properties**: Show attributes, text content, styles, and position
|
|
21
|
-
5. **Accessibility Info**: Check ARIA labels, roles, and screen reader compatibility
|
|
22
|
-
|
|
23
|
-
## Options
|
|
24
|
-
|
|
25
|
-
- `--selector <selector>` - Target a specific CSS selector
|
|
26
|
-
- `--screenshot` - Capture screenshot of the inspected page
|
|
27
|
-
- `--headless` - Run browser in headless mode (default: true)
|
|
28
|
-
- `--browser <browser>` - Choose browser: chromium, firefox, webkit (default: chromium)
|
|
29
|
-
|
|
30
|
-
## Examples
|
|
31
|
-
|
|
32
|
-
### Inspect a specific element
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
/sw-ui:ui-inspect https://example.com --selector "button.submit"
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Capture full-page screenshot
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
/sw-ui:ui-inspect https://example.com --screenshot
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### Inspect with visible browser
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
/sw-ui:ui-inspect https://example.com --headless=false
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Output
|
|
51
|
-
|
|
52
|
-
Provides:
|
|
53
|
-
- **Element Details**: Tag, classes, IDs, data attributes
|
|
54
|
-
- **Selectors**: Multiple selector strategies (CSS, XPath, text-based)
|
|
55
|
-
- **Accessibility**: ARIA attributes, semantic HTML usage
|
|
56
|
-
- **Visual Info**: Dimensions, position, visibility status
|
|
57
|
-
- **Screenshot**: Optional full-page or element screenshot
|
|
58
|
-
|
|
59
|
-
## Use Cases
|
|
60
|
-
|
|
61
|
-
- **Test Automation**: Find reliable selectors for Playwright/Selenium tests
|
|
62
|
-
- **Web Scraping**: Identify data extraction points
|
|
63
|
-
- **Accessibility Audit**: Check element accessibility
|
|
64
|
-
- **Bug Investigation**: Debug element behavior and properties
|
|
65
|
-
|
|
66
|
-
## Browser Mode
|
|
67
|
-
|
|
68
|
-
This command **prefers MCP mode** for rich DOM introspection. When the Playwright MCP plugin provides inline accessibility tree snapshots, the AI can reason about page structure and find optimal selectors.
|
|
69
|
-
|
|
70
|
-
If MCP is unavailable, falls back to `@playwright/cli snapshot` which saves the accessibility tree to a file (`.playwright-cli/*.yml`). The AI can then read the file, but loses the ability to iterate on snapshots without re-reading.
|
|
71
|
-
|
|
72
|
-
**Recommended**: Keep the Playwright MCP plugin installed for best `ui-inspect` experience.
|
|
73
|
-
|
|
74
|
-
## Requirements
|
|
75
|
-
|
|
76
|
-
- Playwright browser binaries (auto-installed on first use)
|
|
77
|
-
- Network access to target URL
|
|
78
|
-
|
|
79
|
-
## Related Commands
|
|
80
|
-
|
|
81
|
-
- `/sw-ui:ui-automate` - Create automated browser workflows
|
|
82
|
-
- `/sw-testing:e2e-setup` - Set up E2E testing framework
|