@brunosps00/dev-workflow 0.0.5 → 0.0.6
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/bin/dev-workflow.js +6 -4
- package/lib/init.js +28 -11
- package/package.json +1 -1
- package/scaffold/pt-br/commands/dw-analyze-project.md +3 -3
- package/scaffold/pt-br/commands/dw-bugfix.md +6 -6
- package/scaffold/pt-br/commands/dw-code-review.md +2 -2
- package/scaffold/pt-br/commands/dw-create-tasks.md +4 -4
- package/scaffold/pt-br/commands/dw-generate-pr.md +3 -3
- package/scaffold/pt-br/commands/dw-help.md +50 -50
- package/scaffold/pt-br/commands/dw-review-implementation.md +3 -3
- package/scaffold/pt-br/commands/dw-run-plan.md +8 -8
- package/scaffold/pt-br/commands/dw-run-task.md +3 -3
- package/scaffold/pt-br/templates/tasks-template.md +2 -2
- package/scaffold/skills/agent-browser/SKILL.md +750 -0
- package/scaffold/skills/agent-browser/references/authentication.md +303 -0
- package/scaffold/skills/agent-browser/references/commands.md +295 -0
- package/scaffold/skills/agent-browser/references/profiling.md +120 -0
- package/scaffold/skills/agent-browser/references/proxy-support.md +194 -0
- package/scaffold/skills/agent-browser/references/session-management.md +193 -0
- package/scaffold/skills/agent-browser/references/snapshot-refs.md +219 -0
- package/scaffold/skills/agent-browser/references/video-recording.md +173 -0
- package/scaffold/skills/agent-browser/templates/authenticated-session.sh +105 -0
- package/scaffold/skills/agent-browser/templates/capture-workflow.sh +69 -0
- package/scaffold/skills/agent-browser/templates/form-automation.sh +62 -0
- package/scaffold/skills/humanizer/README.md +143 -0
- package/scaffold/skills/humanizer/SKILL.md +488 -0
- package/scaffold/skills/humanizer/WARP.md +53 -0
- package/scaffold/skills/remotion-best-practices/SKILL.md +61 -0
- package/scaffold/skills/remotion-best-practices/rules/3d.md +86 -0
- package/scaffold/skills/remotion-best-practices/rules/animations.md +27 -0
- package/scaffold/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/scaffold/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/scaffold/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +103 -0
- package/scaffold/skills/remotion-best-practices/rules/assets.md +78 -0
- package/scaffold/skills/remotion-best-practices/rules/audio-visualization.md +198 -0
- package/scaffold/skills/remotion-best-practices/rules/audio.md +169 -0
- package/scaffold/skills/remotion-best-practices/rules/calculate-metadata.md +134 -0
- package/scaffold/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/scaffold/skills/remotion-best-practices/rules/charts.md +120 -0
- package/scaffold/skills/remotion-best-practices/rules/compositions.md +154 -0
- package/scaffold/skills/remotion-best-practices/rules/display-captions.md +184 -0
- package/scaffold/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/scaffold/skills/remotion-best-practices/rules/ffmpeg.md +38 -0
- package/scaffold/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/scaffold/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/scaffold/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/scaffold/skills/remotion-best-practices/rules/get-video-duration.md +60 -0
- package/scaffold/skills/remotion-best-practices/rules/gifs.md +141 -0
- package/scaffold/skills/remotion-best-practices/rules/images.md +134 -0
- package/scaffold/skills/remotion-best-practices/rules/import-srt-captions.md +69 -0
- package/scaffold/skills/remotion-best-practices/rules/light-leaks.md +73 -0
- package/scaffold/skills/remotion-best-practices/rules/lottie.md +70 -0
- package/scaffold/skills/remotion-best-practices/rules/maps.md +412 -0
- package/scaffold/skills/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
- package/scaffold/skills/remotion-best-practices/rules/measuring-text.md +140 -0
- package/scaffold/skills/remotion-best-practices/rules/parameters.md +109 -0
- package/scaffold/skills/remotion-best-practices/rules/sequencing.md +118 -0
- package/scaffold/skills/remotion-best-practices/rules/sfx.md +26 -0
- package/scaffold/skills/remotion-best-practices/rules/subtitles.md +36 -0
- package/scaffold/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/scaffold/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/scaffold/skills/remotion-best-practices/rules/timing.md +179 -0
- package/scaffold/skills/remotion-best-practices/rules/transcribe-captions.md +70 -0
- package/scaffold/skills/remotion-best-practices/rules/transitions.md +197 -0
- package/scaffold/skills/remotion-best-practices/rules/transparent-videos.md +106 -0
- package/scaffold/skills/remotion-best-practices/rules/trimming.md +51 -0
- package/scaffold/skills/remotion-best-practices/rules/videos.md +171 -0
- package/scaffold/skills/remotion-best-practices/rules/voiceover.md +99 -0
- package/scaffold/skills/security-review/LICENSE +22 -0
- package/scaffold/skills/security-review/SKILL.md +312 -0
- package/scaffold/skills/security-review/infrastructure/docker.md +432 -0
- package/scaffold/skills/security-review/languages/javascript.md +388 -0
- package/scaffold/skills/security-review/languages/python.md +363 -0
- package/scaffold/skills/security-review/references/api-security.md +519 -0
- package/scaffold/skills/security-review/references/authentication.md +353 -0
- package/scaffold/skills/security-review/references/authorization.md +372 -0
- package/scaffold/skills/security-review/references/business-logic.md +443 -0
- package/scaffold/skills/security-review/references/cryptography.md +329 -0
- package/scaffold/skills/security-review/references/csrf.md +398 -0
- package/scaffold/skills/security-review/references/data-protection.md +378 -0
- package/scaffold/skills/security-review/references/deserialization.md +410 -0
- package/scaffold/skills/security-review/references/error-handling.md +436 -0
- package/scaffold/skills/security-review/references/file-security.md +457 -0
- package/scaffold/skills/security-review/references/injection.md +259 -0
- package/scaffold/skills/security-review/references/logging.md +433 -0
- package/scaffold/skills/security-review/references/misconfiguration.md +435 -0
- package/scaffold/skills/security-review/references/modern-threats.md +475 -0
- package/scaffold/skills/security-review/references/ssrf.md +415 -0
- package/scaffold/skills/security-review/references/supply-chain.md +405 -0
- package/scaffold/skills/security-review/references/xss.md +336 -0
- package/scaffold/skills/vercel-react-best-practices/AGENTS.md +3648 -0
- package/scaffold/skills/vercel-react-best-practices/README.md +123 -0
- package/scaffold/skills/vercel-react-best-practices/SKILL.md +146 -0
- package/scaffold/skills/vercel-react-best-practices/rules/_sections.md +46 -0
- package/scaffold/skills/vercel-react-best-practices/rules/_template.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/scaffold/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/scaffold/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-defer-await.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/scaffold/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/scaffold/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/scaffold/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/scaffold/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/scaffold/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/scaffold/skills/webapp-testing/SKILL.md +133 -0
- package/scaffold/skills/webapp-testing/assets/test-helper.js +56 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Parallel Data Fetching with Component Composition
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: eliminates server-side waterfalls
|
|
5
|
+
tags: server, rsc, parallel-fetching, composition
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Parallel Data Fetching with Component Composition
|
|
9
|
+
|
|
10
|
+
React Server Components execute sequentially within a tree. Restructure with composition to parallelize data fetching.
|
|
11
|
+
|
|
12
|
+
**Incorrect (Sidebar waits for Page's fetch to complete):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
export default async function Page() {
|
|
16
|
+
const header = await fetchHeader()
|
|
17
|
+
return (
|
|
18
|
+
<div>
|
|
19
|
+
<div>{header}</div>
|
|
20
|
+
<Sidebar />
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function Sidebar() {
|
|
26
|
+
const items = await fetchSidebarItems()
|
|
27
|
+
return <nav>{items.map(renderItem)}</nav>
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Correct (both fetch simultaneously):**
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
async function Header() {
|
|
35
|
+
const data = await fetchHeader()
|
|
36
|
+
return <div>{data}</div>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function Sidebar() {
|
|
40
|
+
const items = await fetchSidebarItems()
|
|
41
|
+
return <nav>{items.map(renderItem)}</nav>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default function Page() {
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
<Header />
|
|
48
|
+
<Sidebar />
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Alternative with children prop:**
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
async function Header() {
|
|
58
|
+
const data = await fetchHeader()
|
|
59
|
+
return <div>{data}</div>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function Sidebar() {
|
|
63
|
+
const items = await fetchSidebarItems()
|
|
64
|
+
return <nav>{items.map(renderItem)}</nav>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function Layout({ children }: { children: ReactNode }) {
|
|
68
|
+
return (
|
|
69
|
+
<div>
|
|
70
|
+
<Header />
|
|
71
|
+
{children}
|
|
72
|
+
</div>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default function Page() {
|
|
77
|
+
return (
|
|
78
|
+
<Layout>
|
|
79
|
+
<Sidebar />
|
|
80
|
+
</Layout>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Parallel Nested Data Fetching
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: eliminates server-side waterfalls
|
|
5
|
+
tags: server, rsc, parallel-fetching, promise-chaining
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Parallel Nested Data Fetching
|
|
9
|
+
|
|
10
|
+
When fetching nested data in parallel, chain dependent fetches within each item's promise so a slow item doesn't block the rest.
|
|
11
|
+
|
|
12
|
+
**Incorrect (a single slow item blocks all nested fetches):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
const chats = await Promise.all(
|
|
16
|
+
chatIds.map(id => getChat(id))
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
const chatAuthors = await Promise.all(
|
|
20
|
+
chats.map(chat => getUser(chat.author))
|
|
21
|
+
)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If one `getChat(id)` out of 100 is extremely slow, the authors of the other 99 chats can't start loading even though their data is ready.
|
|
25
|
+
|
|
26
|
+
**Correct (each item chains its own nested fetch):**
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
const chatAuthors = await Promise.all(
|
|
30
|
+
chatIds.map(id => getChat(id).then(chat => getUser(chat.author)))
|
|
31
|
+
)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Each item independently chains `getChat` → `getUser`, so a slow chat doesn't block author fetches for the others.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Minimize Serialization at RSC Boundaries
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: reduces data transfer size
|
|
5
|
+
tags: server, rsc, serialization, props
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Minimize Serialization at RSC Boundaries
|
|
9
|
+
|
|
10
|
+
The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.
|
|
11
|
+
|
|
12
|
+
**Incorrect (serializes all 50 fields):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
async function Page() {
|
|
16
|
+
const user = await fetchUser() // 50 fields
|
|
17
|
+
return <Profile user={user} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
'use client'
|
|
21
|
+
function Profile({ user }: { user: User }) {
|
|
22
|
+
return <div>{user.name}</div> // uses 1 field
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Correct (serializes only 1 field):**
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
async function Page() {
|
|
30
|
+
const user = await fetchUser()
|
|
31
|
+
return <Profile name={user.name} />
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
'use client'
|
|
35
|
+
function Profile({ name }: { name: string }) {
|
|
36
|
+
return <div>{name}</div>
|
|
37
|
+
}
|
|
38
|
+
```
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: webapp-testing
|
|
3
|
+
description: Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Web Application Testing
|
|
7
|
+
|
|
8
|
+
This skill enables comprehensive testing and debugging of local web applications using Playwright automation.
|
|
9
|
+
|
|
10
|
+
You should use the Playwright MCP Server to undertake the work if possible. If the MCP Server is unavailable, you can run the code in a local Node.js environment with Playwright installed.
|
|
11
|
+
|
|
12
|
+
## When to Use This Skill
|
|
13
|
+
|
|
14
|
+
Use this skill when you need to:
|
|
15
|
+
|
|
16
|
+
- Test frontend functionality in a real browser
|
|
17
|
+
- Verify UI behavior and interactions
|
|
18
|
+
- Debug web application issues
|
|
19
|
+
- Capture screenshots for documentation or debugging
|
|
20
|
+
- Inspect browser console logs
|
|
21
|
+
- Validate form submissions and user flows
|
|
22
|
+
- Check responsive design across viewports
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
|
|
26
|
+
- Node.js installed on the system
|
|
27
|
+
- A locally running web application (or accessible URL)
|
|
28
|
+
- Playwright will be installed automatically if not present
|
|
29
|
+
|
|
30
|
+
## Core Capabilities
|
|
31
|
+
|
|
32
|
+
### 1. Browser Automation
|
|
33
|
+
|
|
34
|
+
- Navigate to URLs
|
|
35
|
+
- Click buttons and links
|
|
36
|
+
- Fill form fields
|
|
37
|
+
- Select dropdowns
|
|
38
|
+
- Handle dialogs and alerts
|
|
39
|
+
|
|
40
|
+
### 2. Verification
|
|
41
|
+
|
|
42
|
+
- Assert element presence
|
|
43
|
+
- Verify text content
|
|
44
|
+
- Check element visibility
|
|
45
|
+
- Validate URLs
|
|
46
|
+
- Test responsive behavior
|
|
47
|
+
|
|
48
|
+
### 3. Debugging
|
|
49
|
+
|
|
50
|
+
- Capture screenshots
|
|
51
|
+
- View console logs
|
|
52
|
+
- Inspect network requests
|
|
53
|
+
- Debug failed tests
|
|
54
|
+
|
|
55
|
+
## Usage Examples
|
|
56
|
+
|
|
57
|
+
### Example 1: Basic Navigation Test
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
// Navigate to a page and verify title
|
|
61
|
+
await page.goto("http://localhost:3000");
|
|
62
|
+
const title = await page.title();
|
|
63
|
+
console.log("Page title:", title);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Example 2: Form Interaction
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// Fill out and submit a form
|
|
70
|
+
await page.fill("#username", "testuser");
|
|
71
|
+
await page.fill("#password", "password123");
|
|
72
|
+
await page.click('button[type="submit"]');
|
|
73
|
+
await page.waitForURL("**/dashboard");
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Example 3: Screenshot Capture
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
// Capture a screenshot for debugging
|
|
80
|
+
await page.screenshot({ path: "debug.png", fullPage: true });
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Guidelines
|
|
84
|
+
|
|
85
|
+
1. **Always verify the app is running** - Check that the local server is accessible before running tests
|
|
86
|
+
2. **Use explicit waits** - Wait for elements or navigation to complete before interacting
|
|
87
|
+
3. **Capture screenshots on failure** - Take screenshots to help debug issues
|
|
88
|
+
4. **Clean up resources** - Always close the browser when done
|
|
89
|
+
5. **Handle timeouts gracefully** - Set reasonable timeouts for slow operations
|
|
90
|
+
6. **Test incrementally** - Start with simple interactions before complex flows
|
|
91
|
+
7. **Use selectors wisely** - Prefer data-testid or role-based selectors over CSS classes
|
|
92
|
+
|
|
93
|
+
## Common Patterns
|
|
94
|
+
|
|
95
|
+
### Pattern: Wait for Element
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
await page.waitForSelector("#element-id", { state: "visible" });
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Pattern: Check if Element Exists
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
const exists = (await page.locator("#element-id").count()) > 0;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Pattern: Get Console Logs
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
page.on("console", (msg) => console.log("Browser log:", msg.text()));
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Pattern: Handle Errors
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
try {
|
|
117
|
+
await page.click("#button");
|
|
118
|
+
} catch (error) {
|
|
119
|
+
await page.screenshot({ path: "error.png" });
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Limitations
|
|
125
|
+
|
|
126
|
+
- Requires Node.js environment
|
|
127
|
+
- Cannot test native mobile apps (use React Native Testing Library instead)
|
|
128
|
+
- May have issues with complex authentication flows
|
|
129
|
+
- Some modern frameworks may require specific configuration
|
|
130
|
+
|
|
131
|
+
## Helper Functions
|
|
132
|
+
|
|
133
|
+
Some helper functions are available in [`test-helper.js`](./assets/test-helper.js) to simplify common tasks like waiting for elements, capturing screenshots, and handling errors. You can import and use these functions in your tests to improve readability and maintainability.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper utilities for web application testing with Playwright
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Wait for a condition to be true with timeout
|
|
7
|
+
* @param {Function} condition - Function that returns boolean
|
|
8
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
9
|
+
* @param {number} interval - Check interval in milliseconds
|
|
10
|
+
*/
|
|
11
|
+
async function waitForCondition(condition, timeout = 5000, interval = 100) {
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
while (Date.now() - startTime < timeout) {
|
|
14
|
+
if (await condition()) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
await new Promise(resolve => setTimeout(resolve, interval));
|
|
18
|
+
}
|
|
19
|
+
throw new Error('Condition not met within timeout');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Capture browser console logs
|
|
24
|
+
* @param {Page} page - Playwright page object
|
|
25
|
+
* @returns {Array} Array of console messages
|
|
26
|
+
*/
|
|
27
|
+
function captureConsoleLogs(page) {
|
|
28
|
+
const logs = [];
|
|
29
|
+
page.on('console', msg => {
|
|
30
|
+
logs.push({
|
|
31
|
+
type: msg.type(),
|
|
32
|
+
text: msg.text(),
|
|
33
|
+
timestamp: new Date().toISOString()
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
return logs;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Take screenshot with automatic naming
|
|
41
|
+
* @param {Page} page - Playwright page object
|
|
42
|
+
* @param {string} name - Base name for screenshot
|
|
43
|
+
*/
|
|
44
|
+
async function captureScreenshot(page, name) {
|
|
45
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
46
|
+
const filename = `${name}-${timestamp}.png`;
|
|
47
|
+
await page.screenshot({ path: filename, fullPage: true });
|
|
48
|
+
console.log(`Screenshot saved: ${filename}`);
|
|
49
|
+
return filename;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
waitForCondition,
|
|
54
|
+
captureConsoleLogs,
|
|
55
|
+
captureScreenshot
|
|
56
|
+
};
|