@brunosps00/dev-workflow 1.0.5 → 1.1.0
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/README.md +17 -13
- package/bin/dev-workflow.js +5 -0
- package/lib/constants.js +6 -4
- package/lib/install-deps.js +88 -3
- package/lib/setup-wsl-browser.js +149 -0
- package/package.json +1 -1
- package/scaffold/en/agent-instructions.md +7 -5
- package/scaffold/en/commands/dw-analyze-project.md +22 -0
- package/scaffold/en/commands/dw-autopilot.md +158 -275
- package/scaffold/en/commands/dw-bugfix.md +3 -2
- package/scaffold/en/commands/dw-functional-doc.md +11 -3
- package/scaffold/en/commands/dw-generate-pr.md +2 -2
- package/scaffold/en/commands/dw-goal.md +136 -0
- package/scaffold/en/commands/dw-help.md +9 -7
- package/scaffold/en/commands/dw-plan.md +9 -3
- package/scaffold/en/commands/dw-qa.md +1 -1
- package/scaffold/en/commands/dw-redesign-ui.md +2 -2
- package/scaffold/en/commands/dw-review.md +7 -5
- package/scaffold/en/commands/dw-secure-audit.md +72 -15
- package/scaffold/en/templates/constitution-template.md +8 -3
- package/scaffold/en/templates/functional-doc/playwright.flow.mjs.tpl +17 -0
- package/scaffold/pt-br/agent-instructions.md +7 -5
- package/scaffold/pt-br/commands/dw-analyze-project.md +22 -0
- package/scaffold/pt-br/commands/dw-autopilot.md +161 -278
- package/scaffold/pt-br/commands/dw-bugfix.md +3 -2
- package/scaffold/pt-br/commands/dw-functional-doc.md +11 -3
- package/scaffold/pt-br/commands/dw-generate-pr.md +2 -2
- package/scaffold/pt-br/commands/dw-goal.md +136 -0
- package/scaffold/pt-br/commands/dw-help.md +9 -7
- package/scaffold/pt-br/commands/dw-plan.md +9 -3
- package/scaffold/pt-br/commands/dw-qa.md +1 -1
- package/scaffold/pt-br/commands/dw-redesign-ui.md +2 -2
- package/scaffold/pt-br/commands/dw-review.md +7 -5
- package/scaffold/pt-br/commands/dw-secure-audit.md +72 -15
- package/scaffold/pt-br/templates/constitution-template.md +8 -3
- package/scaffold/pt-br/templates/functional-doc/playwright.flow.mjs.tpl +17 -0
- package/scaffold/scripts/cdp-relay/Cargo.toml +16 -0
- package/scaffold/scripts/cdp-relay/src/main.rs +49 -0
- package/scaffold/scripts/functional-doc/generate-dossier.mjs +7 -9
- package/scaffold/scripts/functional-doc/run-playwright-flow.mjs +192 -183
- package/scaffold/scripts/lib/capture-screenshots.mjs +133 -0
- package/scaffold/scripts/lib/resolve-browser.mjs +405 -0
- package/scaffold/scripts/lib/ui-slop-detect.mjs +102 -0
- package/scaffold/skills/dw-testing-discipline/references/playwright-recipes.md +50 -0
- package/scaffold/skills/dw-ui-discipline/SKILL.md +5 -0
- package/scaffold/skills/dw-ui-discipline/references/color-oklch.md +60 -0
- package/scaffold/skills/dw-ui-discipline/references/motion.md +52 -0
- package/scaffold/skills/dw-ui-discipline/references/responsive.md +52 -0
- package/scaffold/skills/dw-ui-discipline/references/type-scale.md +48 -0
- package/scaffold/skills/dw-ui-discipline/references/ux-writing.md +52 -0
- package/scaffold/skills/security-review/SKILL.md +19 -0
- package/scaffold/skills/security-review/references/sast.md +67 -0
- package/scaffold/skills/security-review/references/secrets.md +46 -0
- package/scaffold/en/templates/functional-doc/playwright.spec.ts.tpl +0 -19
- package/scaffold/pt-br/templates/functional-doc/playwright.spec.ts.tpl +0 -19
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Responsive — mobile-first, container queries, fluid space
|
|
2
|
+
|
|
3
|
+
> Patterns adapted from [impeccable](https://github.com/pbakaus/impeccable) (Apache-2.0, derived from
|
|
4
|
+
> Anthropic's frontend-design skill). Read when a surface must work across devices.
|
|
5
|
+
|
|
6
|
+
## Mobile-first
|
|
7
|
+
|
|
8
|
+
Author the small-screen layout first, then add complexity at larger widths with `min-width` queries.
|
|
9
|
+
Mobile-first CSS is additive (you enhance up), which produces simpler, smaller rules than desktop-first
|
|
10
|
+
(`max-width`) overrides. `/dw-redesign-ui` requires every proposal to describe mobile AND desktop.
|
|
11
|
+
|
|
12
|
+
## Breakpoints
|
|
13
|
+
|
|
14
|
+
Base decisions on content, not device names. Reasonable defaults:
|
|
15
|
+
`640` (sm) · `768` (md) · `1024` (lg) · `1280` (xl). Add a breakpoint when the layout *breaks*, not at a
|
|
16
|
+
fixed phone width.
|
|
17
|
+
|
|
18
|
+
## Container queries > viewport queries for components
|
|
19
|
+
|
|
20
|
+
A card that appears in a sidebar and in a main column should respond to *its container*, not the viewport.
|
|
21
|
+
Reusable components are far more robust with container queries:
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
.card-wrap { container-type: inline-size; }
|
|
25
|
+
@container (min-width: 28rem) {
|
|
26
|
+
.card { grid-template-columns: auto 1fr; }
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Fluid space and type
|
|
31
|
+
|
|
32
|
+
Use `clamp()` to interpolate spacing/type between breakpoints instead of hard jumps:
|
|
33
|
+
|
|
34
|
+
```css
|
|
35
|
+
--gap: clamp(1rem, 0.5rem + 2vw, 2.5rem);
|
|
36
|
+
h1 { font-size: clamp(1.75rem, 1.2rem + 2.5vw, 3rem); }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Keep body text fixed (≥16px); fluid body harms readability.
|
|
40
|
+
|
|
41
|
+
## Touch & input
|
|
42
|
+
|
|
43
|
+
- Touch targets ≥ 24×24 CSS px (≥ 44×44 recommended on mobile). Spacing between targets matters as much
|
|
44
|
+
as size.
|
|
45
|
+
- Don't hide primary actions behind hover — hover doesn't exist on touch. Provide a tap-visible path.
|
|
46
|
+
- Respect safe-area insets on mobile (`env(safe-area-inset-*)`) for notches/home indicators.
|
|
47
|
+
|
|
48
|
+
## Layout reflow
|
|
49
|
+
|
|
50
|
+
State explicitly how elements reorganize between breakpoints: stack vs. side-by-side, what collapses into
|
|
51
|
+
a menu, what hides (and whether hidden content is still reachable). "Hidden on mobile with no alternative"
|
|
52
|
+
is a bug, not a layout decision.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Typography — modular scale, pairing, measure
|
|
2
|
+
|
|
3
|
+
> Patterns adapted from [impeccable](https://github.com/pbakaus/impeccable) (Apache-2.0, derived from
|
|
4
|
+
> Anthropic's frontend-design skill). Read when choosing fonts or fixing hierarchy.
|
|
5
|
+
|
|
6
|
+
## Modular scale
|
|
7
|
+
|
|
8
|
+
Pick a base size (16px body) and a ratio, then derive every step from it — don't hand-pick arbitrary
|
|
9
|
+
sizes. Common ratios: 1.2 (minor third, dense UI), 1.25 (major third, balanced), 1.333 (perfect fourth,
|
|
10
|
+
editorial/marketing).
|
|
11
|
+
|
|
12
|
+
Example at base 16 / ratio 1.25:
|
|
13
|
+
`12 · 14 · 16 · 20 · 25 · 31 · 39 · 49` (px). Map to roles: caption 12–14, body 16, h4 20, h3 25, h2 31,
|
|
14
|
+
h1 39–49. **Soft hierarchy** (headings barely larger than body) is a visual-slop pattern — make the jump
|
|
15
|
+
visible.
|
|
16
|
+
|
|
17
|
+
## Fluid type
|
|
18
|
+
|
|
19
|
+
For headings that should scale with viewport, use `clamp()` instead of breakpoint steps:
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
h1 { font-size: clamp(1.75rem, 1.2rem + 2.5vw, 3rem); }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Keep body text fixed (≥16px) — fluid body harms readability and zoom.
|
|
26
|
+
|
|
27
|
+
## Pairing
|
|
28
|
+
|
|
29
|
+
- One typeface, multiple weights, is the safest path — pairs fail more often than they succeed.
|
|
30
|
+
- If pairing: contrast roles clearly (e.g., a distinctive display face for headings + a neutral grotesque
|
|
31
|
+
for body). Don't pair two similar sans fonts.
|
|
32
|
+
- Avoid the overused defaults that signal "no thought": Inter-everywhere, system-ui only, Montserrat
|
|
33
|
+
headings, Lobster/Pacifico for "personality". A deliberate grotesque or a good serif body reads better.
|
|
34
|
+
|
|
35
|
+
## Weight, line-height, measure
|
|
36
|
+
|
|
37
|
+
- **Weight:** body 400–450; don't set body below 400 (thin fonts fail in bright light — see the scene
|
|
38
|
+
question). Headings 600–700. Avoid 300 for anything users must read.
|
|
39
|
+
- **Line-height:** body ~1.5–1.6; headings tighter ~1.1–1.25; the larger the text, the tighter.
|
|
40
|
+
- **Measure (line length):** 45–75 characters for body. Cap with `max-width: 65ch`. Over ~80ch the eye
|
|
41
|
+
loses the next line — the detector flags long lines.
|
|
42
|
+
|
|
43
|
+
## Letter-spacing & numerics
|
|
44
|
+
|
|
45
|
+
- Tighten large headings slightly (`letter-spacing: -0.01em` to `-0.02em`); leave body alone.
|
|
46
|
+
- All-caps labels need positive tracking (`0.05em`).
|
|
47
|
+
- Use tabular figures (`font-variant-numeric: tabular-nums`) for tables, timers, prices so digits don't
|
|
48
|
+
jitter.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# UX writing — labels, errors, empty states
|
|
2
|
+
|
|
3
|
+
> Patterns adapted from [impeccable](https://github.com/pbakaus/impeccable) (Apache-2.0, derived from
|
|
4
|
+
> Anthropic's frontend-design skill). Read when writing any user-facing copy in UI.
|
|
5
|
+
|
|
6
|
+
## Principles
|
|
7
|
+
|
|
8
|
+
- **Specific over generic.** Copy should be self-explanatory without a manual.
|
|
9
|
+
- **Verb-led for actions.** Tell the user what happens.
|
|
10
|
+
- **User's language, not the system's.** "Couldn't save your changes", not "Error 500".
|
|
11
|
+
- **Front-load.** Put the meaningful word first ("Delete project", not "Are you sure you want to…").
|
|
12
|
+
|
|
13
|
+
## Button & link labels
|
|
14
|
+
|
|
15
|
+
Verb-less CTAs ("Get Started", "Learn More", "Submit", "OK", "Click Here") are a visual-slop pattern —
|
|
16
|
+
they make the user guess the outcome. Name the action and, when useful, the object:
|
|
17
|
+
|
|
18
|
+
- ✅ "Create invoice" · "Send reset link" · "Delete 3 files" · "Save and continue"
|
|
19
|
+
- ❌ "Submit" · "OK" · "Continue" (alone) · "Get Started"
|
|
20
|
+
|
|
21
|
+
Destructive actions say what they destroy and are visually distinct (not the same color as primary).
|
|
22
|
+
|
|
23
|
+
## Error messages
|
|
24
|
+
|
|
25
|
+
A good error answers: what happened, why, and what to do next.
|
|
26
|
+
|
|
27
|
+
- ❌ "Invalid input." / "Something went wrong."
|
|
28
|
+
- ✅ "That email is already registered. Try signing in instead."
|
|
29
|
+
- ✅ "Card declined by your bank. Use a different card or contact your bank."
|
|
30
|
+
|
|
31
|
+
Attach errors to the field that caused them, announce them to screen readers (see accessibility-floor.md),
|
|
32
|
+
and never blame the user ("you entered it wrong" → "Enter a date in the future").
|
|
33
|
+
|
|
34
|
+
## Empty states
|
|
35
|
+
|
|
36
|
+
A silent "No items found." centered on a blank page is a visual-slop pattern. An empty state should:
|
|
37
|
+
1. Explain why it's empty (new vs. filtered-out vs. error).
|
|
38
|
+
2. Give the next action (a primary button to create the first item, or "Clear filters").
|
|
39
|
+
3. Optionally set expectations ("Invoices you create will appear here.").
|
|
40
|
+
|
|
41
|
+
Distinguish **first-run empty** (onboarding tone, call to create) from **no-results empty** (offer to
|
|
42
|
+
adjust the search/filter) from **error empty** (explain + retry).
|
|
43
|
+
|
|
44
|
+
## Microcopy details
|
|
45
|
+
|
|
46
|
+
- Loading: say what's loading ("Loading invoices…") rather than a bare spinner for long ops.
|
|
47
|
+
- Success: confirm the outcome and, if relevant, where the result went — don't stack a toast for every
|
|
48
|
+
trivial event (toast-everywhere is slop).
|
|
49
|
+
- Numbers & dates: format for the locale; use relative time ("2 hours ago") where recency matters, exact
|
|
50
|
+
timestamps where precision matters.
|
|
51
|
+
- Sentence case for UI labels and buttons reads friendlier than Title Case in most product UIs; be
|
|
52
|
+
consistent either way.
|
|
@@ -37,6 +37,25 @@ Before flagging any issue, you MUST research the codebase to understand:
|
|
|
37
37
|
| **MEDIUM** | Vulnerable pattern, input source unclear | **Note** as "Needs verification" |
|
|
38
38
|
| **LOW** | Theoretical, best practice, defense-in-depth | **Do not report** |
|
|
39
39
|
|
|
40
|
+
## Automated scanners + false-positive validation (fp-check)
|
|
41
|
+
|
|
42
|
+
The Security Gate (`/dw-secure-audit`) pairs this human-style review with deterministic tools:
|
|
43
|
+
- **SAST** — Semgrep, diff-focused on the generated code. See `references/sast.md`.
|
|
44
|
+
- **Secrets** — gitleaks (dedicated) + Trivy. See `references/secrets.md`. Any secret = REJECTED.
|
|
45
|
+
|
|
46
|
+
Tool findings are **not** auto-trusted to block. Apply the SAME reachability discipline to them before a
|
|
47
|
+
finding blocks the gate (the **fp-check** step):
|
|
48
|
+
|
|
49
|
+
1. **Reachable?** Trace the flagged sink back — is it on a path attacker-controlled input can reach?
|
|
50
|
+
2. **Controlled?** Is the input actually attacker-controlled, or a constant / server-controlled value
|
|
51
|
+
(see the table below) / framework-mitigated?
|
|
52
|
+
3. **Verdict:** If both hold → keep as blocking at its tier. If provably unreachable or
|
|
53
|
+
trusted-input → **downgrade to advisory** and write the one-line justification in the findings file.
|
|
54
|
+
Never silently drop a tool finding — log every downgrade so the pattern stays auditable.
|
|
55
|
+
|
|
56
|
+
Exception: **secrets do not get an fp-check downgrade** — a real-looking credential is removed and
|
|
57
|
+
rotated, not argued away (only committed `.gitleaks.toml` allowlist entries for known fixtures apply).
|
|
58
|
+
|
|
40
59
|
## Do Not Flag
|
|
41
60
|
|
|
42
61
|
### General Rules
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# SAST with Semgrep — semantic analysis of generated code
|
|
2
|
+
|
|
3
|
+
Static review by reading is necessary but misses patterns at scale. Semgrep adds deterministic,
|
|
4
|
+
semantic SAST. The Security Gate (`/dw-secure-audit`) runs it; this reference is the HOW.
|
|
5
|
+
|
|
6
|
+
> Tool: [Semgrep](https://semgrep.dev) (LGPL-2.1, OSS engine). Wrapped natively — no rule content is
|
|
7
|
+
> copied. Rulesets are pulled by name from the Semgrep registry (cached after first run).
|
|
8
|
+
|
|
9
|
+
## Default invocation (diff-focused — the generated code)
|
|
10
|
+
|
|
11
|
+
The gate's primary job is the code just written, so scope Semgrep to the diff against the PR base:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
semgrep scan \
|
|
15
|
+
--config p/security-audit --config p/owasp-top-ten --config p/secrets \
|
|
16
|
+
--baseline-commit "$(git merge-base HEAD origin/main)" \
|
|
17
|
+
--json --output .dw/secure-audit/semgrep.json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- `--baseline-commit` makes Semgrep report only findings **introduced** by the diff — no noise from
|
|
21
|
+
pre-existing code. Use the merge-base with the target branch (fall back to the branch point).
|
|
22
|
+
- Pinned rulesets keep runs reproducible: `p/security-audit`, `p/owasp-top-ten`, `p/secrets`. Add
|
|
23
|
+
language packs as detected (`p/javascript`, `p/python`, `p/csharp`, `p/rust`, `p/golang`).
|
|
24
|
+
|
|
25
|
+
### Full-tree mode (`--full`)
|
|
26
|
+
|
|
27
|
+
For a periodic deep pass (not per-PR), drop `--baseline-commit` to scan the whole tree. Slower; use
|
|
28
|
+
when auditing an inherited codebase or on a schedule.
|
|
29
|
+
|
|
30
|
+
## Severity mapping → gate tiers
|
|
31
|
+
|
|
32
|
+
Semgrep severities map to the Security Gate tiers (Rigoroso):
|
|
33
|
+
|
|
34
|
+
| Semgrep `severity` | Gate tier | Block? |
|
|
35
|
+
|--------------------|-----------|--------|
|
|
36
|
+
| `ERROR` | HIGH (or CRITICAL if CWE is RCE/authn-bypass/SQLi) | **YES** |
|
|
37
|
+
| `WARNING` | MEDIUM | Advisory |
|
|
38
|
+
| `INFO` | LOW | Advisory |
|
|
39
|
+
|
|
40
|
+
Read each finding's `extra.metadata` (`cwe`, `owasp`, `confidence`) to escalate ERROR→CRITICAL when the
|
|
41
|
+
CWE is in the high-impact set (CWE-89 SQLi, CWE-78 OS command, CWE-94 code injection, CWE-502
|
|
42
|
+
deserialization, CWE-287 authn, CWE-918 SSRF).
|
|
43
|
+
|
|
44
|
+
## Parsing the JSON
|
|
45
|
+
|
|
46
|
+
Findings live under `results[]`: `check_id`, `path`, `start.line`, `extra.severity`,
|
|
47
|
+
`extra.message`, `extra.metadata`. Write a human report to `.dw/secure-audit/sast-findings.md`
|
|
48
|
+
grouped by tier, each finding citing `path:line` and the rule id. Errors under `errors[]` (e.g.,
|
|
49
|
+
ruleset fetch failure offline) → note "SAST partial" in the summary, do not crash.
|
|
50
|
+
|
|
51
|
+
## False-positive validation (before blocking)
|
|
52
|
+
|
|
53
|
+
A blocking SAST finding must survive reachability validation (see the fp-check discipline in
|
|
54
|
+
`SKILL.md`): confirm the flagged sink is reached by attacker-controlled input. If the pattern is
|
|
55
|
+
provably unreachable or the input is fully trusted/constant, **downgrade to advisory** and record the
|
|
56
|
+
one-line justification in `sast-findings.md`. Never silently drop — always log the downgrade.
|
|
57
|
+
|
|
58
|
+
## Tool absent
|
|
59
|
+
|
|
60
|
+
If `semgrep` is not installed, the gate skips this layer, records "SAST: skipped (semgrep not
|
|
61
|
+
installed)" in `audit-summary.md`, and points to `npx @brunosps00/dev-workflow install-deps`. The
|
|
62
|
+
gate does not fail merely because a scanner is missing — but the missing coverage is visible.
|
|
63
|
+
|
|
64
|
+
## CodeQL (optional, advisory)
|
|
65
|
+
|
|
66
|
+
CodeQL is deeper but requires a build + database and is too slow for a per-PR gate. Treat it as an
|
|
67
|
+
opt-in periodic scan, not part of the default Security Gate path.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Secret scanning with gitleaks
|
|
2
|
+
|
|
3
|
+
Hardcoded secrets are the highest-severity, lowest-tolerance finding: **any hit blocks the Security
|
|
4
|
+
Gate, with no ADR exception**. Trivy catches some; gitleaks is the dedicated, diff-aware scanner.
|
|
5
|
+
|
|
6
|
+
> Tool: [gitleaks](https://github.com/gitleaks/gitleaks) (MIT, OSS). Wrapped natively.
|
|
7
|
+
|
|
8
|
+
## Diff-focused invocation (the generated code)
|
|
9
|
+
|
|
10
|
+
Scan what the diff introduced, so a pre-existing (already-rotated/allowlisted) secret doesn't block a
|
|
11
|
+
new PR, while any newly added secret does:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Uncommitted/staged changes (pre-commit style):
|
|
15
|
+
gitleaks protect --staged --redact --report-format json --report-path .dw/secure-audit/gitleaks.json
|
|
16
|
+
|
|
17
|
+
# Commits on this branch vs base (PR style):
|
|
18
|
+
gitleaks detect --redact --log-opts "$(git merge-base HEAD origin/main)..HEAD" \
|
|
19
|
+
--report-format json --report-path .dw/secure-audit/gitleaks.json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`--redact` keeps the actual secret value out of the report/logs. A full-tree scan
|
|
23
|
+
(`gitleaks detect` with no `--log-opts`) is the periodic deep pass.
|
|
24
|
+
|
|
25
|
+
## Verdict
|
|
26
|
+
|
|
27
|
+
- **≥1 finding → REJECTED.** No exception, no ADR. A leaked credential is rotated, not justified.
|
|
28
|
+
- Write `.dw/secure-audit/secret-findings.md`: rule id, `file:line`, commit, and the redacted match.
|
|
29
|
+
The remediation is always: remove from code + history, rotate the credential, move to a secret store.
|
|
30
|
+
|
|
31
|
+
## Allowlisting (test fixtures / examples only)
|
|
32
|
+
|
|
33
|
+
Legitimate non-secrets (obvious placeholders, test fixtures) are allowlisted in a committed
|
|
34
|
+
`.gitleaks.toml` (regexes/paths), reviewed like code — not by skipping the scan. A real-looking
|
|
35
|
+
secret in a fixture should still be a fake (e.g., `AKIAIOSFODNN7EXAMPLE`), never a live one.
|
|
36
|
+
|
|
37
|
+
## Relationship to Trivy
|
|
38
|
+
|
|
39
|
+
Trivy's secret scan stays (defense in depth, covers files gitleaks' git-history mode may miss).
|
|
40
|
+
gitleaks is authoritative for the diff. Dedupe by `file:line` in the report so one leak isn't
|
|
41
|
+
double-counted across tools.
|
|
42
|
+
|
|
43
|
+
## Tool absent
|
|
44
|
+
|
|
45
|
+
If `gitleaks` is not installed, the gate falls back to Trivy secrets only and records "dedicated
|
|
46
|
+
secret scan: skipped (gitleaks not installed)" in the summary, pointing to `install-deps`.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { test, expect } from "@playwright/test";
|
|
2
|
-
|
|
3
|
-
const BASE_URL = process.env.BASE_URL ?? "{{baseUrl}}";
|
|
4
|
-
|
|
5
|
-
test("{{testTitle}}", async ({ page }) => {
|
|
6
|
-
const evidence = [] as string[];
|
|
7
|
-
|
|
8
|
-
await test.step("Open target route", async () => {
|
|
9
|
-
await page.goto(`${BASE_URL}{{routePath}}`);
|
|
10
|
-
await expect(page).toHaveURL(new RegExp("{{routeRegex}}"));
|
|
11
|
-
evidence.push("navigation");
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
{{testSteps}}
|
|
15
|
-
|
|
16
|
-
await test.step("Record final context", async () => {
|
|
17
|
-
expect(evidence.length).toBeGreaterThan(0);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { test, expect } from "@playwright/test";
|
|
2
|
-
|
|
3
|
-
const BASE_URL = process.env.BASE_URL ?? "{{baseUrl}}";
|
|
4
|
-
|
|
5
|
-
test("{{testTitle}}", async ({ page }) => {
|
|
6
|
-
const evidence = [] as string[];
|
|
7
|
-
|
|
8
|
-
await test.step("Abrir rota alvo", async () => {
|
|
9
|
-
await page.goto(`${BASE_URL}{{routePath}}`);
|
|
10
|
-
await expect(page).toHaveURL(new RegExp("{{routeRegex}}"));
|
|
11
|
-
evidence.push("navigation");
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
{{testSteps}}
|
|
15
|
-
|
|
16
|
-
await test.step("Registrar contexto final", async () => {
|
|
17
|
-
expect(evidence.length).toBeGreaterThan(0);
|
|
18
|
-
});
|
|
19
|
-
});
|