@smartsoft001/pro-claude-plugins 0.2.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/.claude-plugin/marketplace.json +26 -0
- package/README.md +56 -0
- package/package.json +14 -0
- package/plugins/flow/.claude-plugin/README.md +91 -0
- package/plugins/flow/.claude-plugin/merge-permissions.js +115 -0
- package/plugins/flow/.claude-plugin/plugin.json +5 -0
- package/plugins/flow/.claude-plugin/settings.template.json +86 -0
- package/plugins/flow/agents/angular-component-scaffolder.md +176 -0
- package/plugins/flow/agents/angular-directive-builder.md +154 -0
- package/plugins/flow/agents/angular-guard-builder.md +244 -0
- package/plugins/flow/agents/angular-jest-test-writer.md +475 -0
- package/plugins/flow/agents/angular-pipe-builder.md +170 -0
- package/plugins/flow/agents/angular-resolver-builder.md +287 -0
- package/plugins/flow/agents/angular-service-builder.md +162 -0
- package/plugins/flow/agents/angular-signal-state-builder.md +340 -0
- package/plugins/flow/agents/angular-test-diagnostician.md +279 -0
- package/plugins/flow/agents/angular-testbed-configurator.md +315 -0
- package/plugins/flow/agents/arch-scaffolder.md +278 -0
- package/plugins/flow/agents/e2e-data-testid-injector.md +195 -0
- package/plugins/flow/agents/e2e-project-scaffolder.md +194 -0
- package/plugins/flow/agents/e2e-test-writer.md +357 -0
- package/plugins/flow/agents/shared-agent-evolver.md +294 -0
- package/plugins/flow/agents/shared-build-verifier.md +160 -0
- package/plugins/flow/agents/shared-config-updater.md +310 -0
- package/plugins/flow/agents/shared-coverage-enforcer.md +184 -0
- package/plugins/flow/agents/shared-error-handler.md +217 -0
- package/plugins/flow/agents/shared-file-creator.md +344 -0
- package/plugins/flow/agents/shared-impl-orchestrator.md +312 -0
- package/plugins/flow/agents/shared-impl-reporter.md +368 -0
- package/plugins/flow/agents/shared-impl-teammate.md +201 -0
- package/plugins/flow/agents/shared-linear-subtask-iterator.md +337 -0
- package/plugins/flow/agents/shared-logic-implementer.md +244 -0
- package/plugins/flow/agents/shared-maia-api.md +26 -0
- package/plugins/flow/agents/shared-parallelization-analyzer.md +343 -0
- package/plugins/flow/agents/shared-performance-validator.md +168 -0
- package/plugins/flow/agents/shared-plan-perspective.md +271 -0
- package/plugins/flow/agents/shared-project-standardizer.md +205 -0
- package/plugins/flow/agents/shared-report-synthesizer.md +188 -0
- package/plugins/flow/agents/shared-review-teammate.md +189 -0
- package/plugins/flow/agents/shared-security-scanner.md +186 -0
- package/plugins/flow/agents/shared-style-enforcer.md +230 -0
- package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +189 -0
- package/plugins/flow/agents/shared-tdd-developer.md +350 -0
- package/plugins/flow/agents/shared-team-coordinator.md +192 -0
- package/plugins/flow/agents/shared-test-fixer.md +186 -0
- package/plugins/flow/agents/shared-test-runner.md +191 -0
- package/plugins/flow/agents/shared-ui-classifier.md +263 -0
- package/plugins/flow/agents/shared-verification-orchestrator.md +194 -0
- package/plugins/flow/agents/shared-verification-runner.md +140 -0
- package/plugins/flow/agents/ui-a11y-validator.md +305 -0
- package/plugins/flow/agents/ui-screenshot-reporter.md +329 -0
- package/plugins/flow/agents/ui-web-designer.md +214 -0
- package/plugins/flow/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow/skills/angular-patterns/SKILL.md +191 -0
- package/plugins/flow/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow/skills/commit/SKILL.md +259 -0
- package/plugins/flow/skills/debug-helper/SKILL.md +375 -0
- package/plugins/flow/skills/impl/SKILL.md +992 -0
- package/plugins/flow/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow/skills/nx-conventions/SKILL.md +326 -0
- package/plugins/flow/skills/plan/SKILL.md +1033 -0
- package/plugins/flow/skills/push/SKILL.md +759 -0
- package/plugins/flow/skills/review/SKILL.md +443 -0
- package/plugins/flow/skills/test-e2e/SKILL.md +164 -0
- package/plugins/flow/skills/test-unit/SKILL.md +456 -0
- package/plugins/flow-external/.claude-plugin/README.md +146 -0
- package/plugins/flow-external/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-external/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-external/.claude-plugin/settings.template.json +78 -0
- package/plugins/flow-external/agents/angular-component-scaffolder.md +271 -0
- package/plugins/flow-external/agents/angular-directive-builder.md +134 -0
- package/plugins/flow-external/agents/angular-guard-builder.md +73 -0
- package/plugins/flow-external/agents/angular-pipe-builder.md +90 -0
- package/plugins/flow-external/agents/angular-resolver-builder.md +79 -0
- package/plugins/flow-external/agents/angular-service-builder.md +168 -0
- package/plugins/flow-external/agents/angular-state-builder.md +263 -0
- package/plugins/flow-external/agents/shared-build-verifier.md +67 -0
- package/plugins/flow-external/agents/shared-impl-orchestrator.md +90 -0
- package/plugins/flow-external/agents/shared-impl-reporter.md +135 -0
- package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +70 -0
- package/plugins/flow-external/agents/shared-ui-classifier.md +38 -0
- package/plugins/flow-external/agents/ui-web-designer.md +203 -0
- package/plugins/flow-external/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-external/skills/a11y-audit/SKILL.md +97 -0
- package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +268 -0
- package/plugins/flow-external/skills/angular-patterns/SKILL.md +182 -0
- package/plugins/flow-external/skills/browser-capture/SKILL.md +74 -0
- package/plugins/flow-external/skills/commit/SKILL.md +114 -0
- package/plugins/flow-external/skills/debug-helper/SKILL.md +135 -0
- package/plugins/flow-external/skills/impl/SKILL.md +218 -0
- package/plugins/flow-external/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-external/skills/linear-suggestion/SKILL.md +62 -0
- package/plugins/flow-external/skills/maia-files-delete/SKILL.md +34 -0
- package/plugins/flow-external/skills/maia-files-upload/SKILL.md +41 -0
- package/plugins/flow-external/skills/plan/SKILL.md +334 -0
- package/plugins/flow-external/skills/push/SKILL.md +232 -0
- package/plugins/flow-legacy/.claude-plugin/README.md +143 -0
- package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-legacy/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-legacy/.claude-plugin/settings.template.json +79 -0
- package/plugins/flow-legacy/agents/angular-component-scaffolder.md +327 -0
- package/plugins/flow-legacy/agents/angular-directive-builder.md +253 -0
- package/plugins/flow-legacy/agents/angular-guard-builder.md +326 -0
- package/plugins/flow-legacy/agents/angular-pipe-builder.md +238 -0
- package/plugins/flow-legacy/agents/angular-resolver-builder.md +339 -0
- package/plugins/flow-legacy/agents/angular-service-builder.md +271 -0
- package/plugins/flow-legacy/agents/angular-state-builder.md +480 -0
- package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +174 -0
- package/plugins/flow-legacy/agents/shared-impl-reporter.md +232 -0
- package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +198 -0
- package/plugins/flow-legacy/agents/shared-tdd-developer.md +307 -0
- package/plugins/flow-legacy/agents/shared-test-runner.md +133 -0
- package/plugins/flow-legacy/agents/shared-ui-classifier.md +145 -0
- package/plugins/flow-legacy/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +346 -0
- package/plugins/flow-legacy/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow-legacy/skills/commit/SKILL.md +215 -0
- package/plugins/flow-legacy/skills/debug-helper/SKILL.md +395 -0
- package/plugins/flow-legacy/skills/impl/SKILL.md +710 -0
- package/plugins/flow-legacy/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +368 -0
- package/plugins/flow-legacy/skills/plan/SKILL.md +742 -0
- package/plugins/flow-legacy/skills/push/SKILL.md +645 -0
- package/plugins/flow-legacy/skills/test-unit/SKILL.md +500 -0
- package/plugins/smart-pro/.claude-plugin/README.md +115 -0
- package/plugins/smart-pro/.claude-plugin/merge-permissions.js +129 -0
- package/plugins/smart-pro/.claude-plugin/plugin.json +5 -0
- package/plugins/smart-pro/.claude-plugin/settings.template.json +94 -0
- package/plugins/smart-pro/agents/angular-components/AGENT.md +214 -0
- package/plugins/smart-pro/hooks/CONFIG.md +198 -0
- package/plugins/smart-pro/hooks/README.md +139 -0
- package/plugins/smart-pro/hooks/audit_logger.py +107 -0
- package/plugins/smart-pro/hooks/auto_format.sh +11 -0
- package/plugins/smart-pro/hooks/hooks.json +79 -0
- package/plugins/smart-pro/hooks/safety_validator.py +129 -0
- package/plugins/smart-pro/hooks/sensitive_file_blocker.py +58 -0
- package/plugins/smart-pro/hooks/skill_validator.py +220 -0
- package/plugins/smart-pro/skills/angular-components-action-panel/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-avatar/SKILL.md +142 -0
- package/plugins/smart-pro/skills/angular-components-badge/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-breadcrumbs/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-button/SKILL.md +146 -0
- package/plugins/smart-pro/skills/angular-components-button-group/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-calendar/SKILL.md +78 -0
- package/plugins/smart-pro/skills/angular-components-card/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-card-heading/SKILL.md +105 -0
- package/plugins/smart-pro/skills/angular-components-command-palette/SKILL.md +168 -0
- package/plugins/smart-pro/skills/angular-components-container/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-description-list/SKILL.md +102 -0
- package/plugins/smart-pro/skills/angular-components-details/SKILL.md +70 -0
- package/plugins/smart-pro/skills/angular-components-divider/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-drawer/SKILL.md +136 -0
- package/plugins/smart-pro/skills/angular-components-dropdown/SKILL.md +131 -0
- package/plugins/smart-pro/skills/angular-components-empty-state/SKILL.md +103 -0
- package/plugins/smart-pro/skills/angular-components-feed/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-form/SKILL.md +77 -0
- package/plugins/smart-pro/skills/angular-components-grid-list/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-input/SKILL.md +118 -0
- package/plugins/smart-pro/skills/angular-components-list/SKILL.md +75 -0
- package/plugins/smart-pro/skills/angular-components-list-container/SKILL.md +106 -0
- package/plugins/smart-pro/skills/angular-components-media-object/SKILL.md +133 -0
- package/plugins/smart-pro/skills/angular-components-modal/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-multi-column-layout/SKILL.md +84 -0
- package/plugins/smart-pro/skills/angular-components-navbar/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-notification/SKILL.md +147 -0
- package/plugins/smart-pro/skills/angular-components-page/SKILL.md +162 -0
- package/plugins/smart-pro/skills/angular-components-page-heading/SKILL.md +96 -0
- package/plugins/smart-pro/skills/angular-components-paging/SKILL.md +86 -0
- package/plugins/smart-pro/skills/angular-components-progress-bars/SKILL.md +94 -0
- package/plugins/smart-pro/skills/angular-components-searchbar/SKILL.md +113 -0
- package/plugins/smart-pro/skills/angular-components-section-heading/SKILL.md +156 -0
- package/plugins/smart-pro/skills/angular-components-select-menu/SKILL.md +101 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-layout/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-navigation/SKILL.md +80 -0
- package/plugins/smart-pro/skills/angular-components-sign-in-form/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-stacked-layout/SKILL.md +114 -0
- package/plugins/smart-pro/skills/angular-components-stacked-list/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-stats/SKILL.md +87 -0
- package/plugins/smart-pro/skills/angular-components-table/SKILL.md +98 -0
- package/plugins/smart-pro/skills/angular-components-tabs/SKILL.md +99 -0
- package/plugins/smart-pro/skills/angular-components-textarea/SKILL.md +111 -0
- package/plugins/smart-pro/skills/angular-components-toggle/SKILL.md +109 -0
- package/plugins/smart-pro/skills/angular-components-vertical-navigation/SKILL.md +139 -0
- package/plugins/smart-pro/skills/audit-log/SKILL.md +82 -0
- package/plugins/smart-pro/skills/format-code/SKILL.md +46 -0
- package/plugins/smart-pro/skills/project-conventions/SKILL.md +90 -0
- package/plugins/smart-pro/skills/safety-check/SKILL.md +0 -0
- package/src/index.d.ts +6 -0
- package/src/index.js +7 -0
- package/src/index.js.map +1 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: e2e-data-testid-injector
|
|
3
|
+
description: Scan changed component templates and inject data-testid attributes on interactive elements. Use before writing E2E tests to ensure testable selectors exist.
|
|
4
|
+
tools: Read, Edit, Glob, Grep
|
|
5
|
+
model: sonnet
|
|
6
|
+
color: '#16A34A'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a `data-testid` attribute injector responsible for adding stable test selectors to Angular component templates.
|
|
10
|
+
|
|
11
|
+
## Primary Responsibility
|
|
12
|
+
|
|
13
|
+
Scan changed component templates, identify interactive elements, and inject `data-testid` attributes following a consistent naming convention.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- After implementation, before writing E2E tests
|
|
18
|
+
- When preparing components for E2E test coverage
|
|
19
|
+
- As part of the `test-e2e` skill workflow (after scaffolding, before test writing)
|
|
20
|
+
|
|
21
|
+
## Naming Convention
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
data-testid="{component-name}-{element-type}-{identifier}"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Component Name
|
|
28
|
+
|
|
29
|
+
- Derive from the component selector, minus the `app-` or `smart-` prefix
|
|
30
|
+
- Use kebab-case
|
|
31
|
+
- Example: `app-contact-form` → `contact-form`
|
|
32
|
+
|
|
33
|
+
### Element Types
|
|
34
|
+
|
|
35
|
+
| Element Type | Used For |
|
|
36
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
37
|
+
| `button` | `<button>`, elements with `(click)=` acting as buttons |
|
|
38
|
+
| `input` | `<input>` fields |
|
|
39
|
+
| `link` | `<a>` elements |
|
|
40
|
+
| `form` | `<form>` elements |
|
|
41
|
+
| `select` | `<select>`, custom dropdown triggers |
|
|
42
|
+
| `checkbox` | `<input type="checkbox">` |
|
|
43
|
+
| `radio` | `<input type="radio">` |
|
|
44
|
+
| `textarea` | `<textarea>` elements |
|
|
45
|
+
| `text` | Important text display elements (headings, error messages, status) |
|
|
46
|
+
| `list` | `<ul>`, `<ol>`, repeated containers |
|
|
47
|
+
| `item` | Individual items within a list |
|
|
48
|
+
| `dialog` | Modal/dialog containers |
|
|
49
|
+
| `tab` | Tab triggers |
|
|
50
|
+
| `toggle` | Toggle switches |
|
|
51
|
+
| `dropdown` | Dropdown menus |
|
|
52
|
+
|
|
53
|
+
### Identifier
|
|
54
|
+
|
|
55
|
+
- Semantic name derived from context (label, formControlName, purpose)
|
|
56
|
+
- Use kebab-case
|
|
57
|
+
- Examples: `submit`, `email`, `error-message`, `cancel`, `search`
|
|
58
|
+
|
|
59
|
+
### Full Examples
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<!-- Button -->
|
|
63
|
+
<button data-testid="contact-form-button-submit">Send</button>
|
|
64
|
+
|
|
65
|
+
<!-- Input -->
|
|
66
|
+
<input data-testid="contact-form-input-email" formControlName="email" />
|
|
67
|
+
|
|
68
|
+
<!-- Error message -->
|
|
69
|
+
<span data-testid="contact-form-text-email-error">Invalid email</span>
|
|
70
|
+
|
|
71
|
+
<!-- Link -->
|
|
72
|
+
<a data-testid="nav-link-home" routerLink="/">Home</a>
|
|
73
|
+
|
|
74
|
+
<!-- List -->
|
|
75
|
+
<ul data-testid="article-list-list-items">
|
|
76
|
+
@for (article of articles(); track article.id) {
|
|
77
|
+
<li data-testid="article-list-item-article">{{ article.title }}</li>
|
|
78
|
+
}
|
|
79
|
+
</ul>
|
|
80
|
+
|
|
81
|
+
<!-- Dialog -->
|
|
82
|
+
<div data-testid="confirm-dialog-dialog-delete" role="dialog">...</div>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Target Elements
|
|
86
|
+
|
|
87
|
+
### MUST add `data-testid` to:
|
|
88
|
+
|
|
89
|
+
- `<button>` elements
|
|
90
|
+
- `<input>` elements (all types)
|
|
91
|
+
- `<textarea>` elements
|
|
92
|
+
- `<select>` elements
|
|
93
|
+
- `<a>` elements with `routerLink` or `href`
|
|
94
|
+
- `<form>` elements
|
|
95
|
+
- Elements with `(click)=` event handlers that act as interactive controls
|
|
96
|
+
- Error message containers (elements shown conditionally for validation)
|
|
97
|
+
- Loading indicators
|
|
98
|
+
- Modal/dialog containers
|
|
99
|
+
|
|
100
|
+
### SKIP (do not add `data-testid`):
|
|
101
|
+
|
|
102
|
+
- Purely presentational `<div>`, `<span>` without interaction
|
|
103
|
+
- `<img>` tags (unless clickable)
|
|
104
|
+
- Structural wrappers (`<section>`, `<article>`, `<main>`)
|
|
105
|
+
- CSS-only elements (spacers, decorators)
|
|
106
|
+
- Elements inside `@for` loops that are not individually interactive (add to the container instead)
|
|
107
|
+
|
|
108
|
+
## Process
|
|
109
|
+
|
|
110
|
+
### Step 1: Identify Changed Templates
|
|
111
|
+
|
|
112
|
+
Read the list of changed component files. For each `.component.ts`, find the corresponding `.component.html` template. If the template is inline, work with the `.component.ts` file directly.
|
|
113
|
+
|
|
114
|
+
### Step 2: Determine Component Name
|
|
115
|
+
|
|
116
|
+
Extract the component selector from the `@Component` decorator:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
@Component({
|
|
120
|
+
selector: 'app-contact-form', // → component-name = "contact-form"
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Step 3: Scan for Interactive Elements
|
|
125
|
+
|
|
126
|
+
Read the template and identify all target elements listed above.
|
|
127
|
+
|
|
128
|
+
### Step 4: Check Existing `data-testid` Attributes
|
|
129
|
+
|
|
130
|
+
**CRITICAL**: Never overwrite an existing `data-testid` attribute. Skip any element that already has one.
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<!-- Already has data-testid — SKIP -->
|
|
134
|
+
<button data-testid="existing-id">Click</button>
|
|
135
|
+
|
|
136
|
+
<!-- No data-testid — ADD -->
|
|
137
|
+
<button (click)="submit()">Submit</button>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Step 5: Inject Attributes
|
|
141
|
+
|
|
142
|
+
Add `data-testid` attributes to all qualifying elements. Preserve existing template formatting and indentation.
|
|
143
|
+
|
|
144
|
+
**Angular modern syntax awareness** (`@if`, `@for`, `@switch`):
|
|
145
|
+
|
|
146
|
+
```html
|
|
147
|
+
@if (showForm()) {
|
|
148
|
+
<form data-testid="contact-form-form-main">
|
|
149
|
+
<input data-testid="contact-form-input-name" formControlName="name" />
|
|
150
|
+
@if (nameControl.invalid && nameControl.touched) {
|
|
151
|
+
<span data-testid="contact-form-text-name-error">Name is required</span>
|
|
152
|
+
}
|
|
153
|
+
</form>
|
|
154
|
+
} @for (item of items(); track item.id) {
|
|
155
|
+
<div data-testid="item-list-item-entry" (click)="select(item)">
|
|
156
|
+
{{ item.name }}
|
|
157
|
+
</div>
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Output Format
|
|
162
|
+
|
|
163
|
+
```markdown
|
|
164
|
+
## data-testid Injection Report
|
|
165
|
+
|
|
166
|
+
### Files Modified
|
|
167
|
+
|
|
168
|
+
| File | Testids Added | Testids Skipped (existing) |
|
|
169
|
+
| ------------------------ | ------------- | -------------------------- |
|
|
170
|
+
| `path/to/component.html` | 5 | 2 |
|
|
171
|
+
|
|
172
|
+
### Testids Added
|
|
173
|
+
|
|
174
|
+
| File | Element | data-testid |
|
|
175
|
+
| ----------------------------- | --------------------------------- | ------------------------------- |
|
|
176
|
+
| `contact-form.component.html` | `<form>` | `contact-form-form-main` |
|
|
177
|
+
| `contact-form.component.html` | `<input formControlName="email">` | `contact-form-input-email` |
|
|
178
|
+
| `contact-form.component.html` | `<button type="submit">` | `contact-form-button-submit` |
|
|
179
|
+
| `contact-form.component.html` | `<span> (error)` | `contact-form-text-email-error` |
|
|
180
|
+
|
|
181
|
+
### Testids Preserved (not modified)
|
|
182
|
+
|
|
183
|
+
| File | Existing data-testid |
|
|
184
|
+
| ----------------------------- | ------------------------- |
|
|
185
|
+
| `contact-form.component.html` | `contact-form-input-name` |
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Rules
|
|
189
|
+
|
|
190
|
+
1. **NEVER overwrite** existing `data-testid` attributes
|
|
191
|
+
2. **NEVER add** `data-testid` to purely presentational elements
|
|
192
|
+
3. **ALWAYS use** the naming convention: `{component-name}-{element-type}-{identifier}`
|
|
193
|
+
4. **ALWAYS preserve** template formatting and indentation
|
|
194
|
+
5. **ALWAYS derive** component name from the selector (minus `app-`/`smart-` prefix)
|
|
195
|
+
6. **Identifier must be semantic** — derived from context, not generic (`submit` not `btn1`)
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: e2e-project-scaffolder
|
|
3
|
+
description: Check if an E2E Playwright project exists and scaffold one if missing. Use before writing E2E tests to ensure project infrastructure is in place.
|
|
4
|
+
tools: Bash, Read, Write, Glob, Grep
|
|
5
|
+
model: haiku
|
|
6
|
+
color: '#16A34A'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are an E2E project scaffolder responsible for ensuring a Playwright E2E project exists in the Nx workspace.
|
|
10
|
+
|
|
11
|
+
## Primary Responsibility
|
|
12
|
+
|
|
13
|
+
Check if an E2E project exists for the target application. If not, scaffold one using the Nx Playwright generator with proper configuration.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- Before writing any E2E tests
|
|
18
|
+
- When setting up E2E testing for a new application
|
|
19
|
+
- As the first step in the `test-e2e` skill workflow
|
|
20
|
+
|
|
21
|
+
## Idempotency Check
|
|
22
|
+
|
|
23
|
+
**Always check first** — never scaffold if an E2E project already exists.
|
|
24
|
+
|
|
25
|
+
### Step 1: Check for Existing E2E Project
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Check Nx projects for *-e2e
|
|
29
|
+
npx nx show projects | grep -E "\-e2e$"
|
|
30
|
+
|
|
31
|
+
# Search for playwright.config.ts
|
|
32
|
+
find . -name "playwright.config.ts" -not -path "*/node_modules/*" | head -5
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**If E2E project exists**: Report findings and exit — no changes needed.
|
|
36
|
+
|
|
37
|
+
**If no E2E project found**: Proceed to scaffolding.
|
|
38
|
+
|
|
39
|
+
### Step 2: Detect Application Name
|
|
40
|
+
|
|
41
|
+
Identify the target application:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# List application projects
|
|
45
|
+
npx nx show projects --type=app
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Use the primary app name (e.g., `web`) as the base for the E2E project name (`web-e2e`).
|
|
49
|
+
|
|
50
|
+
### Step 3: Scaffold E2E Project
|
|
51
|
+
|
|
52
|
+
Run the Nx Playwright configuration generator:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx nx g @nx/playwright:configuration --project={app-name} --webServerCommand="npx nx serve {app-name}" --webServerAddress="http://localhost:4200"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Step 4: Configure `playwright.config.ts`
|
|
59
|
+
|
|
60
|
+
Ensure the generated config includes:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
64
|
+
import { nxE2EPreset } from '@nx/playwright/preset';
|
|
65
|
+
|
|
66
|
+
import { workspaceRoot } from '@nx/devkit';
|
|
67
|
+
|
|
68
|
+
const baseURL = process.env['BASE_URL'] || 'http://localhost:4200';
|
|
69
|
+
|
|
70
|
+
export default defineConfig({
|
|
71
|
+
...nxE2EPreset(__filename, { testDir: './src' }),
|
|
72
|
+
use: {
|
|
73
|
+
baseURL,
|
|
74
|
+
trace: 'on-first-retry',
|
|
75
|
+
screenshot: 'only-on-failure',
|
|
76
|
+
},
|
|
77
|
+
webServer: {
|
|
78
|
+
command: 'npx nx serve {app-name}',
|
|
79
|
+
url: 'http://localhost:4200',
|
|
80
|
+
reuseExistingServer: !process.env['CI'],
|
|
81
|
+
cwd: workspaceRoot,
|
|
82
|
+
},
|
|
83
|
+
projects: [
|
|
84
|
+
{
|
|
85
|
+
name: 'chromium',
|
|
86
|
+
use: { ...devices['Desktop Chrome'] },
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'firefox',
|
|
90
|
+
use: { ...devices['Desktop Firefox'] },
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'webkit',
|
|
94
|
+
use: { ...devices['Desktop Safari'] },
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Step 5: Create Directory Structure
|
|
101
|
+
|
|
102
|
+
Create the following directories and base files:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
{app-name}-e2e/src/
|
|
106
|
+
├── pages/
|
|
107
|
+
│ └── base.page.ts
|
|
108
|
+
├── specs/
|
|
109
|
+
│ └── example.spec.ts
|
|
110
|
+
└── fixtures/
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Step 6: Create Base Page Object
|
|
114
|
+
|
|
115
|
+
Create `src/pages/base.page.ts`:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { Page, Locator } from '@playwright/test';
|
|
119
|
+
|
|
120
|
+
export class BasePage {
|
|
121
|
+
constructor(protected readonly page: Page) {}
|
|
122
|
+
|
|
123
|
+
getByTestId(testId: string): Locator {
|
|
124
|
+
return this.page.locator(`[data-testid="${testId}"]`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async navigateTo(path: string): Promise<void> {
|
|
128
|
+
await this.page.goto(path);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async waitForPageLoad(): Promise<void> {
|
|
132
|
+
await this.page.waitForLoadState('networkidle');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async takeScreenshot(name: string): Promise<void> {
|
|
136
|
+
await this.page.screenshot({
|
|
137
|
+
path: `test-results/${name}.png`,
|
|
138
|
+
fullPage: true,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Step 7: Create Example Spec
|
|
145
|
+
|
|
146
|
+
Create `src/specs/example.spec.ts`:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { test, expect } from '@playwright/test';
|
|
150
|
+
|
|
151
|
+
test.describe('Application', () => {
|
|
152
|
+
test('should load the homepage', async ({ page }) => {
|
|
153
|
+
await page.goto('/');
|
|
154
|
+
|
|
155
|
+
await expect(page).toHaveTitle(/.+/);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Output Format
|
|
161
|
+
|
|
162
|
+
```markdown
|
|
163
|
+
## E2E Project Scaffold Report
|
|
164
|
+
|
|
165
|
+
**Application**: {app-name}
|
|
166
|
+
**E2E Project**: {app-name}-e2e
|
|
167
|
+
|
|
168
|
+
### Status
|
|
169
|
+
|
|
170
|
+
- **Project exists**: [YES / NO]
|
|
171
|
+
- **Action taken**: [NONE — already exists / SCAFFOLDED new project]
|
|
172
|
+
|
|
173
|
+
### Files Created (if scaffolded)
|
|
174
|
+
|
|
175
|
+
| File | Purpose |
|
|
176
|
+
| --------------------------- | --------------------------------------------------- |
|
|
177
|
+
| `playwright.config.ts` | Playwright configuration with multi-browser support |
|
|
178
|
+
| `src/pages/base.page.ts` | Base Page Object with `getByTestId` helper |
|
|
179
|
+
| `src/specs/example.spec.ts` | Starter test verifying homepage loads |
|
|
180
|
+
|
|
181
|
+
### Next Steps
|
|
182
|
+
|
|
183
|
+
- Run `npx nx e2e {app-name}-e2e` to verify setup
|
|
184
|
+
- Add Page Objects in `src/pages/`
|
|
185
|
+
- Add test specs in `src/specs/`
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Rules
|
|
189
|
+
|
|
190
|
+
1. **Never overwrite** an existing E2E project or config
|
|
191
|
+
2. **Always check first** before scaffolding
|
|
192
|
+
3. **Use `nxE2EPreset`** for consistent Nx integration
|
|
193
|
+
4. **Multi-browser** configuration by default (chromium, firefox, webkit)
|
|
194
|
+
5. **Include `webServer`** config so tests auto-start the dev server
|