@torus-engineering/tas-kit 1.10.0 → 1.12.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/.tas/README.md +70 -70
- package/{.claude → .tas/_platform/claude-code}/settings.json +0 -12
- package/{.claude → .tas/_platform}/hooks/code-quality.js +1 -1
- package/{.claude → .tas/_platform}/hooks/session-end.js +20 -25
- package/.tas/commands/ado-create.md +28 -0
- package/.tas/commands/ado-delete.md +22 -0
- package/.tas/commands/ado-get.md +20 -0
- package/.tas/commands/ado-status.md +18 -0
- package/.tas/commands/ado-update.md +27 -0
- package/.tas/commands/tas-adr.md +33 -0
- package/.tas/commands/tas-apitest-plan.md +173 -0
- package/.tas/commands/tas-apitest.md +143 -0
- package/.tas/commands/tas-brainstorm.md +19 -0
- package/.tas/commands/tas-bug.md +113 -0
- package/.tas/commands/tas-design.md +37 -0
- package/.tas/commands/tas-dev.md +125 -0
- package/{.claude → .tas}/commands/tas-e2e-mobile.md +155 -155
- package/{.claude → .tas}/commands/tas-e2e-web.md +163 -163
- package/.tas/commands/tas-e2e.md +102 -0
- package/.tas/commands/tas-epic.md +35 -0
- package/.tas/commands/tas-feature.md +47 -0
- package/.tas/commands/tas-fix.md +51 -0
- package/.tas/commands/tas-functest-mobile.md +144 -0
- package/{.claude → .tas}/commands/tas-functest-web.md +192 -192
- package/.tas/commands/tas-functest.md +76 -0
- package/.tas/commands/tas-init.md +17 -0
- package/.tas/commands/tas-plan.md +198 -0
- package/.tas/commands/tas-prd.md +37 -0
- package/.tas/commands/tas-review.md +113 -0
- package/.tas/commands/tas-sad.md +43 -0
- package/.tas/commands/tas-security.md +87 -0
- package/.tas/commands/tas-spec.md +50 -0
- package/.tas/commands/tas-status.md +16 -0
- package/.tas/commands/tas-story.md +91 -0
- package/.tas/platforms.json +5 -0
- package/.tas/project-status-example.yaml +17 -17
- package/.tas/rules/ado-integration.md +65 -0
- package/{.claude/skills/api-design/SKILL.md → .tas/rules/common/api-design.md} +517 -530
- package/{.claude → .tas}/rules/common/code-review.md +30 -6
- package/.tas/rules/common/post-implementation-review.md +51 -0
- package/{.claude → .tas}/rules/common/project-status.md +80 -80
- package/.tas/rules/common/stack-detection.md +29 -0
- package/.tas/rules/common/story-done.md +30 -0
- package/.tas/rules/common/tdd.md +89 -0
- package/{.claude → .tas}/rules/common/testing.md +3 -8
- package/.tas/rules/common/token-logging.md +36 -0
- package/{.claude → .tas}/rules/csharp/api-testing.md +20 -20
- package/{.claude → .tas}/rules/csharp/coding-style.md +0 -2
- package/{.claude → .tas}/rules/csharp/security.md +10 -0
- package/{.claude → .tas}/rules/python/coding-style.md +0 -2
- package/{.claude → .tas}/rules/typescript/coding-style.md +0 -2
- package/.tas/rules/typescript/patterns.md +142 -0
- package/.tas/rules/typescript/security.md +88 -0
- package/{.claude → .tas}/rules/typescript/testing.md +0 -4
- package/{.claude → .tas}/rules/web/coding-style.md +0 -2
- package/.tas/tas-example.yaml +10 -11
- package/.tas/templates/ADR.md +47 -47
- package/.tas/templates/AGENTS.md +37 -0
- package/.tas/templates/API-Test-Spec.md +3 -3
- package/.tas/templates/Bug.md +67 -67
- package/.tas/templates/Design-Spec.md +36 -36
- package/.tas/templates/E2E-Execution-Report.md +1 -1
- package/.tas/templates/Epic.md +46 -46
- package/.tas/templates/Feature.md +10 -10
- package/.tas/templates/Func-Test-Spec.md +3 -3
- package/.tas/templates/SAD.md +106 -106
- package/.tas/templates/Security-Report.md +27 -27
- package/.tas/templates/Story.md +9 -9
- package/.tas/tools/tas-ado-readme.md +68 -68
- package/.tas/tools/tas-ado.py +621 -621
- package/README.md +78 -78
- package/bin/cli.js +91 -73
- package/lib/adapters/antigravity.js +137 -0
- package/lib/adapters/claude-code.js +35 -0
- package/lib/adapters/codex.js +163 -0
- package/lib/adapters/cursor.js +80 -0
- package/lib/adapters/index.js +20 -0
- package/lib/adapters/utils.js +81 -0
- package/lib/deleted-files.json +99 -0
- package/lib/install.js +403 -327
- package/package.json +4 -3
- package/.claude/agents/code-reviewer.md +0 -41
- package/.claude/agents/e2e-runner.md +0 -61
- package/.claude/agents/planner.md +0 -82
- package/.claude/agents/tdd-guide.md +0 -84
- package/.claude/commands/ado-create.md +0 -27
- package/.claude/commands/ado-delete.md +0 -21
- package/.claude/commands/ado-get.md +0 -20
- package/.claude/commands/ado-status.md +0 -18
- package/.claude/commands/ado-update.md +0 -26
- package/.claude/commands/tas-adr.md +0 -33
- package/.claude/commands/tas-apitest-plan.md +0 -173
- package/.claude/commands/tas-apitest.md +0 -143
- package/.claude/commands/tas-brainstorm.md +0 -19
- package/.claude/commands/tas-bug.md +0 -113
- package/.claude/commands/tas-design.md +0 -37
- package/.claude/commands/tas-dev.md +0 -128
- package/.claude/commands/tas-e2e.md +0 -102
- package/.claude/commands/tas-epic.md +0 -35
- package/.claude/commands/tas-feature.md +0 -47
- package/.claude/commands/tas-fix.md +0 -51
- package/.claude/commands/tas-functest-mobile.md +0 -144
- package/.claude/commands/tas-functest.md +0 -76
- package/.claude/commands/tas-init.md +0 -17
- package/.claude/commands/tas-plan.md +0 -200
- package/.claude/commands/tas-prd.md +0 -37
- package/.claude/commands/tas-review.md +0 -111
- package/.claude/commands/tas-sad.md +0 -43
- package/.claude/commands/tas-security.md +0 -87
- package/.claude/commands/tas-spec.md +0 -50
- package/.claude/commands/tas-status.md +0 -16
- package/.claude/commands/tas-story.md +0 -91
- package/.claude/commands/tas-verify.md +0 -51
- package/.claude/rules/common/post-review-agent.md +0 -49
- package/.claude/rules/common/stack-detection.md +0 -29
- package/.claude/rules/common/token-logging.md +0 -27
- package/.claude/rules/typescript/patterns.md +0 -62
- package/.claude/rules/typescript/security.md +0 -28
- package/.claude/settings.local.json +0 -38
- package/.claude/skills/ado-integration/SKILL.md +0 -75
- package/.claude/skills/ai-regression-testing/SKILL.md +0 -364
- package/.claude/skills/architecture-decision-records/SKILL.md +0 -184
- package/.claude/skills/benchmark/SKILL.md +0 -98
- package/.claude/skills/browser-qa/SKILL.md +0 -92
- package/.claude/skills/canary-watch/SKILL.md +0 -104
- package/.claude/skills/js-backend-patterns/SKILL.md +0 -603
- package/.claude/skills/tas-conventions/SKILL.md +0 -65
- package/.claude/skills/tas-implementation-complete/SKILL.md +0 -99
- package/.claude/skills/tas-tdd/SKILL.md +0 -123
- package/.claude/skills/token-logger/SKILL.md +0 -19
- package/.tas/checklists/code-review.md +0 -29
- package/.tas/checklists/security.md +0 -21
- package/.tas/checklists/story-done.md +0 -23
- package/CLAUDE-Example.md +0 -61
- /package/{.claude → .tas}/agents/architect.md +0 -0
- /package/{.claude → .tas}/agents/aws-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/build-resolver.md +0 -0
- /package/{.claude → .tas}/agents/code-explorer.md +0 -0
- /package/{.claude → .tas}/agents/csharp-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/database-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/doc-updater.md +0 -0
- /package/{.claude → .tas}/agents/python-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/security-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/typescript-reviewer.md +0 -0
- /package/{.claude → .tas}/rules/.gitkeep +0 -0
- /package/{.claude → .tas}/rules/common/hooks.md +0 -0
- /package/{.claude → .tas}/rules/common/patterns.md +0 -0
- /package/{.claude → .tas}/rules/common/security.md +0 -0
- /package/{.claude → .tas}/rules/csharp/hooks.md +0 -0
- /package/{.claude → .tas}/rules/csharp/patterns.md +0 -0
- /package/{.claude → .tas}/rules/csharp/testing.md +0 -0
- /package/{.claude → .tas}/rules/python/hooks.md +0 -0
- /package/{.claude → .tas}/rules/python/patterns.md +0 -0
- /package/{.claude → .tas}/rules/python/security.md +0 -0
- /package/{.claude → .tas}/rules/python/testing.md +0 -0
- /package/{.claude → .tas}/rules/typescript/hooks.md +0 -0
- /package/{.claude → .tas}/rules/web/design-quality.md +0 -0
- /package/{.claude → .tas}/rules/web/hooks.md +0 -0
- /package/{.claude → .tas}/rules/web/patterns.md +0 -0
- /package/{.claude → .tas}/rules/web/performance.md +0 -0
- /package/{.claude → .tas}/rules/web/security.md +0 -0
- /package/{.claude → .tas}/rules/web/testing.md +0 -0
|
@@ -1,192 +1,192 @@
|
|
|
1
|
-
# /tas-functest-web $ARGUMENTS
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Generate
|
|
5
|
-
|
|
6
|
-
##
|
|
7
|
-
-
|
|
8
|
-
- Scripts
|
|
9
|
-
- Reusable helpers
|
|
10
|
-
-
|
|
11
|
-
- Cross-viewport testing (mobile, tablet, desktop)
|
|
12
|
-
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
###
|
|
16
|
-
1. $ARGUMENTS
|
|
17
|
-
2.
|
|
18
|
-
3.
|
|
19
|
-
|
|
20
|
-
###
|
|
21
|
-
1.
|
|
22
|
-
> "Web app
|
|
23
|
-
>
|
|
24
|
-
2.
|
|
25
|
-
```
|
|
26
|
-
docs/epics/{epic-dir}/{feature-dir}/Func-Test-*.md
|
|
27
|
-
```
|
|
28
|
-
3.
|
|
29
|
-
> "
|
|
30
|
-
4.
|
|
31
|
-
5.
|
|
32
|
-
|
|
33
|
-
###
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
###
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
**File output**: `apps/web/e2e/features/{epic-slug}/{feature-slug}/{story-slug}.func.spec.ts`
|
|
42
|
-
|
|
43
|
-
**Structure**:
|
|
44
|
-
```typescript
|
|
45
|
-
/**
|
|
46
|
-
* Functional Tests: {Story Name}
|
|
47
|
-
* Story: {Story_ID}
|
|
48
|
-
* Feature: {Feature_ID}
|
|
49
|
-
* Epic: {Epic_ID}
|
|
50
|
-
*
|
|
51
|
-
* Generated by /tas-functest-web
|
|
52
|
-
* Spec: docs/epics/{epic-dir}/{feature-dir}/Func-Test-{story-slug}.md
|
|
53
|
-
*/
|
|
54
|
-
|
|
55
|
-
import { test, expect } from '@playwright/test';
|
|
56
|
-
import { loadTestData, getCredentials } from '../../../helpers/data-loader';
|
|
57
|
-
|
|
58
|
-
const testData = loadTestData();
|
|
59
|
-
|
|
60
|
-
test.describe('{Feature Name} - {Story Name}', () => {
|
|
61
|
-
test.beforeEach(async ({ page }) => {
|
|
62
|
-
await page.goto('/target-page');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// AC Reference: AC-1
|
|
66
|
-
test.describe('{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_001_H', () => {
|
|
67
|
-
test('should {description from spec}', async ({ page }) => {
|
|
68
|
-
// Given: {precondition}
|
|
69
|
-
// When: {action}
|
|
70
|
-
await page.getByTestId('element-id').click();
|
|
71
|
-
// Then: {expected}
|
|
72
|
-
await expect(page.getByTestId('result')).toBeVisible();
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// Viewport testing for responsive features
|
|
77
|
-
test.describe('{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_001_H - Viewports', () => {
|
|
78
|
-
const viewports = [
|
|
79
|
-
{ width: 375, height: 812, name: 'mobile' },
|
|
80
|
-
{ width: 768, height: 1024, name: 'tablet' },
|
|
81
|
-
{ width: 1280, height: 720, name: 'desktop' },
|
|
82
|
-
];
|
|
83
|
-
|
|
84
|
-
for (const vp of viewports) {
|
|
85
|
-
test(`should work on ${vp.name} (${vp.width}x${vp.height})`, async ({ page }) => {
|
|
86
|
-
await page.setViewportSize({ width: vp.width, height: vp.height });
|
|
87
|
-
// Test responsive behavior
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
###
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
import { Page, expect } from '@playwright/test';
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Reusable helpers
|
|
101
|
-
*
|
|
102
|
-
*/
|
|
103
|
-
|
|
104
|
-
export async function {featureSpecificHelper}(page: Page) {
|
|
105
|
-
// Helper logic extracted from functional tests
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
###
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
type TestEnv = 'dev' | 'staging' | 'prod';
|
|
113
|
-
|
|
114
|
-
export function loadTestData(env?: TestEnv) {
|
|
115
|
-
const targetEnv = env || (process.env.TEST_ENV as TestEnv) || 'dev';
|
|
116
|
-
return require(`../data/test-data.${targetEnv}.json`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export function getCredentials(userType = 'default') {
|
|
120
|
-
const data = loadTestData();
|
|
121
|
-
const user = data.users[userType] || data.users.default;
|
|
122
|
-
return {
|
|
123
|
-
email: user.email,
|
|
124
|
-
password: process.env.TEST_USER_PASSWORD || '',
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
###
|
|
130
|
-
|
|
131
|
-
```json
|
|
132
|
-
"functest:web:{feature-slug}": "npx playwright test e2e/features/{epic-slug}/{feature-slug}"
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
###
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
export * from './helpers';
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## File Structure Output
|
|
142
|
-
```
|
|
143
|
-
apps/web/e2e/features/
|
|
144
|
-
└── {epic-slug}/
|
|
145
|
-
└── {feature-slug}/
|
|
146
|
-
├── {story-1-slug}.func.spec.ts
|
|
147
|
-
├── {story-2-slug}.func.spec.ts
|
|
148
|
-
├── helpers.ts
|
|
149
|
-
└── index.ts
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Selector Strategy (Playwright)
|
|
153
|
-
- **
|
|
154
|
-
- **Text content**: `page.getByText('Welcome')`
|
|
155
|
-
- **Role**: `page.getByRole('button', { name: 'Submit' })`
|
|
156
|
-
- **Label**: `page.getByLabel('Email')`
|
|
157
|
-
-
|
|
158
|
-
|
|
159
|
-
## Cross-Browser Testing
|
|
160
|
-
- Chromium (
|
|
161
|
-
- Firefox (
|
|
162
|
-
- WebKit (
|
|
163
|
-
- Config
|
|
164
|
-
|
|
165
|
-
## Test Data Convention
|
|
166
|
-
- **Hardcoded values**:
|
|
167
|
-
- **Credentials**: `getCredentials()` → password
|
|
168
|
-
- **Environment data**: `loadTestData()` →
|
|
169
|
-
- **
|
|
170
|
-
|
|
171
|
-
##
|
|
172
|
-
```bash
|
|
173
|
-
#
|
|
174
|
-
yarn functest:web:{feature-slug}
|
|
175
|
-
|
|
176
|
-
#
|
|
177
|
-
npx playwright test e2e/features/{epic}/{feature}/{story}
|
|
178
|
-
|
|
179
|
-
#
|
|
180
|
-
npx playwright test --project=firefox e2e/features/{epic}/{feature}
|
|
181
|
-
|
|
182
|
-
#
|
|
183
|
-
npx playwright test --ui e2e/features/{epic}/{feature}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
##
|
|
187
|
-
- Script
|
|
188
|
-
-
|
|
189
|
-
- Helpers
|
|
190
|
-
-
|
|
191
|
-
-
|
|
192
|
-
-
|
|
1
|
+
# /tas-functest-web $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Role: SE / QA
|
|
4
|
+
Generate all Playwright automation test scripts for a web Feature.
|
|
5
|
+
|
|
6
|
+
## IMPORTANT - Layer 2: Web Functional Test Scripts
|
|
7
|
+
- Create Playwright test scripts from Func-Test-Spec (markdown)
|
|
8
|
+
- Scripts located in `apps/web/e2e/features/`
|
|
9
|
+
- Reusable helpers exported for Layer 3 (E2E) reuse
|
|
10
|
+
- Hardcoded data in tests, credentials from .env
|
|
11
|
+
- Cross-viewport testing (mobile, tablet, desktop)
|
|
12
|
+
|
|
13
|
+
## Actions
|
|
14
|
+
|
|
15
|
+
### Step 1: Identify Feature
|
|
16
|
+
1. $ARGUMENTS is Feature ID or file path
|
|
17
|
+
2. If not provided: scan `docs/epics/**/Feature-*.md` for features with status In Progress
|
|
18
|
+
3. Read Feature file to get Epic/Feature numbers and list of Stories
|
|
19
|
+
|
|
20
|
+
### Step 2: Check Prerequisites
|
|
21
|
+
1. Check `apps/web/` exists. If not → report:
|
|
22
|
+
> "Web app doesn't exist in this project. If project only has mobile, use /tas-functest-mobile."
|
|
23
|
+
> STOP, DO NOT create file.
|
|
24
|
+
2. Find all `Func-Test-*.md` files in Feature directory:
|
|
25
|
+
```
|
|
26
|
+
docs/epics/{epic-dir}/{feature-dir}/Func-Test-*.md
|
|
27
|
+
```
|
|
28
|
+
3. If no Func-Test-Spec exists → report:
|
|
29
|
+
> "No Func-Test-Spec for this Feature yet. Run /tas-functest {story-ID} first."
|
|
30
|
+
4. Read `apps/web/playwright.config.ts` (if exists) to understand current config
|
|
31
|
+
5. Read `apps/web/e2e/helpers/` (if exists) to understand patterns
|
|
32
|
+
|
|
33
|
+
### Step 3: Aggregate FT Test Cases
|
|
34
|
+
- From all Func-Test-Spec files, aggregate list of FT test cases
|
|
35
|
+
- Group by Story
|
|
36
|
+
- Get test data requirements from each spec
|
|
37
|
+
|
|
38
|
+
### Step 4: Generate Test Scripts
|
|
39
|
+
For EACH Story with Func-Test-Spec:
|
|
40
|
+
|
|
41
|
+
**File output**: `apps/web/e2e/features/{epic-slug}/{feature-slug}/{story-slug}.func.spec.ts`
|
|
42
|
+
|
|
43
|
+
**Structure**:
|
|
44
|
+
```typescript
|
|
45
|
+
/**
|
|
46
|
+
* Functional Tests: {Story Name}
|
|
47
|
+
* Story: {Story_ID}
|
|
48
|
+
* Feature: {Feature_ID}
|
|
49
|
+
* Epic: {Epic_ID}
|
|
50
|
+
*
|
|
51
|
+
* Generated by /tas-functest-web
|
|
52
|
+
* Spec: docs/epics/{epic-dir}/{feature-dir}/Func-Test-{story-slug}.md
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
import { test, expect } from '@playwright/test';
|
|
56
|
+
import { loadTestData, getCredentials } from '../../../helpers/data-loader';
|
|
57
|
+
|
|
58
|
+
const testData = loadTestData();
|
|
59
|
+
|
|
60
|
+
test.describe('{Feature Name} - {Story Name}', () => {
|
|
61
|
+
test.beforeEach(async ({ page }) => {
|
|
62
|
+
await page.goto('/target-page');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// AC Reference: AC-1
|
|
66
|
+
test.describe('{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_001_H', () => {
|
|
67
|
+
test('should {description from spec}', async ({ page }) => {
|
|
68
|
+
// Given: {precondition}
|
|
69
|
+
// When: {action}
|
|
70
|
+
await page.getByTestId('element-id').click();
|
|
71
|
+
// Then: {expected}
|
|
72
|
+
await expect(page.getByTestId('result')).toBeVisible();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Viewport testing for responsive features
|
|
77
|
+
test.describe('{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_001_H - Viewports', () => {
|
|
78
|
+
const viewports = [
|
|
79
|
+
{ width: 375, height: 812, name: 'mobile' },
|
|
80
|
+
{ width: 768, height: 1024, name: 'tablet' },
|
|
81
|
+
{ width: 1280, height: 720, name: 'desktop' },
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
for (const vp of viewports) {
|
|
85
|
+
test(`should work on ${vp.name} (${vp.width}x${vp.height})`, async ({ page }) => {
|
|
86
|
+
await page.setViewportSize({ width: vp.width, height: vp.height });
|
|
87
|
+
// Test responsive behavior
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Step 5: Generate Feature Helpers
|
|
95
|
+
Create file `apps/web/e2e/features/{epic-slug}/{feature-slug}/helpers.ts`:
|
|
96
|
+
```typescript
|
|
97
|
+
import { Page, expect } from '@playwright/test';
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Reusable helpers for {Feature Name}
|
|
101
|
+
* Exported for Layer 3 E2E scripts reuse
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
export async function {featureSpecificHelper}(page: Page) {
|
|
105
|
+
// Helper logic extracted from functional tests
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Step 6: Generate/Update Data Loader (if not exists)
|
|
110
|
+
If `apps/web/e2e/helpers/data-loader.ts` doesn't exist, create:
|
|
111
|
+
```typescript
|
|
112
|
+
type TestEnv = 'dev' | 'staging' | 'prod';
|
|
113
|
+
|
|
114
|
+
export function loadTestData(env?: TestEnv) {
|
|
115
|
+
const targetEnv = env || (process.env.TEST_ENV as TestEnv) || 'dev';
|
|
116
|
+
return require(`../data/test-data.${targetEnv}.json`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function getCredentials(userType = 'default') {
|
|
120
|
+
const data = loadTestData();
|
|
121
|
+
const user = data.users[userType] || data.users.default;
|
|
122
|
+
return {
|
|
123
|
+
email: user.email,
|
|
124
|
+
password: process.env.TEST_USER_PASSWORD || '',
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Step 7: Update package.json Script
|
|
130
|
+
Add or update script in `apps/web/package.json`:
|
|
131
|
+
```json
|
|
132
|
+
"functest:web:{feature-slug}": "npx playwright test e2e/features/{epic-slug}/{feature-slug}"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Step 8: Generate Index
|
|
136
|
+
Create `apps/web/e2e/features/{epic-slug}/{feature-slug}/index.ts`:
|
|
137
|
+
```typescript
|
|
138
|
+
export * from './helpers';
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## File Structure Output
|
|
142
|
+
```
|
|
143
|
+
apps/web/e2e/features/
|
|
144
|
+
└── {epic-slug}/
|
|
145
|
+
└── {feature-slug}/
|
|
146
|
+
├── {story-1-slug}.func.spec.ts
|
|
147
|
+
├── {story-2-slug}.func.spec.ts
|
|
148
|
+
├── helpers.ts
|
|
149
|
+
└── index.ts
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Selector Strategy (Playwright)
|
|
153
|
+
- **Priority**: `data-testid` → `page.getByTestId('login-submit')`
|
|
154
|
+
- **Text content**: `page.getByText('Welcome')`
|
|
155
|
+
- **Role**: `page.getByRole('button', { name: 'Submit' })`
|
|
156
|
+
- **Label**: `page.getByLabel('Email')`
|
|
157
|
+
- DO NOT use traditional CSS selectors (`.class`, `#id`) unless required
|
|
158
|
+
|
|
159
|
+
## Cross-Browser Testing
|
|
160
|
+
- Chromium (required)
|
|
161
|
+
- Firefox (required)
|
|
162
|
+
- WebKit (required)
|
|
163
|
+
- Config in `playwright.config.ts` projects section
|
|
164
|
+
|
|
165
|
+
## Test Data Convention
|
|
166
|
+
- **Hardcoded values**: Directly in test
|
|
167
|
+
- **Credentials**: `getCredentials()` → password from process.env
|
|
168
|
+
- **Environment data**: `loadTestData()` → from test-data.{env}.json
|
|
169
|
+
- **NEVER** hardcode passwords/tokens
|
|
170
|
+
|
|
171
|
+
## Run Tests
|
|
172
|
+
```bash
|
|
173
|
+
# Run all func tests for feature
|
|
174
|
+
yarn functest:web:{feature-slug}
|
|
175
|
+
|
|
176
|
+
# Run only one story
|
|
177
|
+
npx playwright test e2e/features/{epic}/{feature}/{story}
|
|
178
|
+
|
|
179
|
+
# Run with specific browser
|
|
180
|
+
npx playwright test --project=firefox e2e/features/{epic}/{feature}
|
|
181
|
+
|
|
182
|
+
# Run with debug UI
|
|
183
|
+
npx playwright test --ui e2e/features/{epic}/{feature}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Principles
|
|
187
|
+
- Script MUST be runnable directly from CLI
|
|
188
|
+
- Each describe block uses full FT ID
|
|
189
|
+
- Helpers MUST export for Layer 3 reuse
|
|
190
|
+
- DO NOT import from Layer 3 (flows/)
|
|
191
|
+
- If apps/web/ doesn't exist → graceful error, DO NOT create
|
|
192
|
+
- Tests must work on all viewports (mobile, tablet, desktop)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# /tas-functest $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Role: SE / QA
|
|
4
|
+
Generate Functional Test Specification from a User Story, linking test cases to Acceptance Criteria (AC).
|
|
5
|
+
|
|
6
|
+
## IMPORTANT - Layer 2: Functional Testing
|
|
7
|
+
- Functional tests (FT) sit between Unit tests (Layer 1) and E2E tests (Layer 3)
|
|
8
|
+
- FT tests individual function/story in isolation, DOESN'T test linked flows between multiple features
|
|
9
|
+
- Each FT case MUST reference AC-ID for traceability
|
|
10
|
+
|
|
11
|
+
## Actions
|
|
12
|
+
|
|
13
|
+
### Step 1: Identify Story
|
|
14
|
+
1. $ARGUMENTS is Story ID or file path
|
|
15
|
+
2. If no $ARGUMENTS: scan `docs/epics/**/Story-*.md` for stories with status In Progress or Committed
|
|
16
|
+
3. Read Story file to get:
|
|
17
|
+
- All Acceptance Criteria (AC-1, AC-2, ...)
|
|
18
|
+
- Epic/Feature/Story numbers (from frontmatter or file path)
|
|
19
|
+
- Platform context (mobile/web/backend)
|
|
20
|
+
4. Read `root/tas.yaml` to get project code (e.g., "AL")
|
|
21
|
+
|
|
22
|
+
### Step 2: Auto-detect Platform
|
|
23
|
+
From Story context, determine platform:
|
|
24
|
+
- **Mobile**: Keywords "screen", "navigation", "React Native", "Detox"; paths `apps/mobile/src/features/*`
|
|
25
|
+
- **Web**: Keywords "browser", "page", "Playwright", "React"; paths `apps/web/*`
|
|
26
|
+
- **Backend**: Keywords "API endpoint", "service", "controller"; paths `src/Torus.*`, `tests/`
|
|
27
|
+
- If cannot determine: ask user
|
|
28
|
+
|
|
29
|
+
### Step 3: Generate FT Test Cases
|
|
30
|
+
Read template from `.tas/templates/Func-Test-Spec.md`
|
|
31
|
+
|
|
32
|
+
Naming format:
|
|
33
|
+
```
|
|
34
|
+
{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_{NNN}_{MODIFIER}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For each AC, generate:
|
|
38
|
+
- **REQUIRED**: 1 Happy path test (H)
|
|
39
|
+
- **SHOULD HAVE**: 1 Negative test (N) if error scenarios exist
|
|
40
|
+
- **OPTIONAL**: 1 Edge case test (E) if boundary conditions exist
|
|
41
|
+
|
|
42
|
+
Each test case MUST have AC-ID column in mapping table.
|
|
43
|
+
|
|
44
|
+
### Step 4: Generate Test Data Requirements
|
|
45
|
+
- Identify data needed for each test case
|
|
46
|
+
- Hardcoded data: write directly in scenario
|
|
47
|
+
- Credentials: only reference `process.env.TEST_USER_PASSWORD`, DO NOT hardcode
|
|
48
|
+
- Environment-specific data: reference `test-data.{env}.json`
|
|
49
|
+
|
|
50
|
+
### Step 5: Output File
|
|
51
|
+
Save file at:
|
|
52
|
+
```
|
|
53
|
+
docs/epics/{epic-dir}/{feature-dir}/Func-Test-{story-slug}.md
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Step 6: Prompting
|
|
57
|
+
After generating, ask user:
|
|
58
|
+
- "Any edge cases to add?"
|
|
59
|
+
- "Any negative test scenarios missed?"
|
|
60
|
+
- "Any test cases to mark as P0 Critical?"
|
|
61
|
+
- "What additional test data and fixtures needed?"
|
|
62
|
+
|
|
63
|
+
## Traceability Feature
|
|
64
|
+
- Each FT case links AC-ID in mapping column
|
|
65
|
+
- When AC changes: grep AC-ID in Func-Test-*.md to know which FTs need update
|
|
66
|
+
- In test script, each describe block has comment `// AC Reference: AC-{N}`
|
|
67
|
+
|
|
68
|
+
## Status Flow
|
|
69
|
+
Draft → Ready → Implemented → Verified
|
|
70
|
+
|
|
71
|
+
## Principles
|
|
72
|
+
- DO NOT create test code, only create specification (markdown)
|
|
73
|
+
- Test code created by `/tas-functest-mobile` or `/tas-functest-web`
|
|
74
|
+
- Func-Test-Spec is input for Layer 2 script generation
|
|
75
|
+
- Each AC must have at least 1 FT case
|
|
76
|
+
- FT uses type code `FT`, NOT `E2E` or `UT`
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# /tas-init
|
|
2
|
+
|
|
3
|
+
Initialize TAS kit for the current project.
|
|
4
|
+
|
|
5
|
+
## Actions
|
|
6
|
+
1. Need context from root/tas.yaml. If not exists, copy from .tas/tas-example.yaml to root and ask user to fill required information.
|
|
7
|
+
2. Create directory structure: .tas/templates/, docs/, docs/adr/, docs/epics/, docs/bugs/
|
|
8
|
+
3. Create root/project-status.yaml file with initial state (artifacts, epics, adrs all empty).
|
|
9
|
+
4. Copy default templates to .tas/templates/ if not exist.
|
|
10
|
+
5. If project type is brownfield and codebase_scan_on_init = true:
|
|
11
|
+
- Scan existing codebase
|
|
12
|
+
- Create docs/codebase-overview.md summarizing current architecture
|
|
13
|
+
6. Display status: project type, team roles, enabled workflow phases.
|
|
14
|
+
|
|
15
|
+
## Notes
|
|
16
|
+
- DO NOT recreate files if already exist
|
|
17
|
+
- Ask for confirmation before executing
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# /tas-plan $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Role: SE - Software Engineer
|
|
4
|
+
Bridge between business (Story) and technical (code).
|
|
5
|
+
Analyze Story, create technical plan, break tasks — before implementing.
|
|
6
|
+
|
|
7
|
+
**Required output:** Technical Plan written to Story file + `plan_status: completed`.
|
|
8
|
+
|
|
9
|
+
## Always / Ask / Never
|
|
10
|
+
|
|
11
|
+
| | Action |
|
|
12
|
+
|---|---|
|
|
13
|
+
| **Always** | Read Story file before doing anything |
|
|
14
|
+
| **Always** | Wait for user to approve plan before writing to Story |
|
|
15
|
+
| **Always** | Write Technical Plan to Story file after approval |
|
|
16
|
+
| **Ask** | When need to reference SAD/ADR — confirm with user before reading |
|
|
17
|
+
| **Ask** | When Story scope > 8 hours — suggest splitting Story |
|
|
18
|
+
| **Never** | Start implementing in this command |
|
|
19
|
+
| **Never** | Read SAD/ADR without asking user first |
|
|
20
|
+
| **Never** | Write plan to Story without approval |
|
|
21
|
+
|
|
22
|
+
## Actions
|
|
23
|
+
|
|
24
|
+
### Step 1 — Identify Story
|
|
25
|
+
|
|
26
|
+
`$ARGUMENTS` can be: Story ID (`Story-005`), file path, or Story description.
|
|
27
|
+
|
|
28
|
+
- If Story ID: find file via glob `docs/epics/**/*-Story-{ID}-*.md`
|
|
29
|
+
- If file path: read directly
|
|
30
|
+
- If description: ask user for specific Story ID/file
|
|
31
|
+
- Read Story file
|
|
32
|
+
|
|
33
|
+
**Check re-plan:** If `plan_status: completed` → ask user:
|
|
34
|
+
> "This Story already has a Technical Plan. Do you want to re-plan?"
|
|
35
|
+
If user confirms → continue. If not → stop.
|
|
36
|
+
|
|
37
|
+
### Step 2 — Parallel Context Gathering
|
|
38
|
+
|
|
39
|
+
Launch 2 agents SIMULTANEOUSLY:
|
|
40
|
+
|
|
41
|
+
**Agent 1 — `code-explorer`** (always run):
|
|
42
|
+
> Survey codebase related to Story: "{Story title + AC summary}".
|
|
43
|
+
> Find: entry points, files likely to change, existing patterns, dependencies.
|
|
44
|
+
> Read max 10 most relevant files.
|
|
45
|
+
> Return: concise map — what exists, what needs to change, potential conflicts.
|
|
46
|
+
|
|
47
|
+
**Agent 2 — `architect`** (only run if Story shows architectural changes:
|
|
48
|
+
new service/module, data flow changes, external system integration,
|
|
49
|
+
database schema changes, new design pattern):
|
|
50
|
+
> Evaluate architectural implications of Story: "{Story title}".
|
|
51
|
+
> Read `docs/sad.md` (if exists) and files in `docs/adr/`.
|
|
52
|
+
> Read `.tas/rules/common/patterns.md`.
|
|
53
|
+
> Return: which ADRs relate, patterns to follow, architectural risks, constraints.
|
|
54
|
+
|
|
55
|
+
Wait for ALL agents to finish, synthesize findings.
|
|
56
|
+
|
|
57
|
+
### Step 3 — Ask about SAD/ADR (if still unclear)
|
|
58
|
+
|
|
59
|
+
After seeing agent findings, if need to reference specific SAD or ADR:
|
|
60
|
+
> "I need to read [SAD / ADR-XXX] to clarify [reason]. OK?"
|
|
61
|
+
|
|
62
|
+
Only read after user confirms.
|
|
63
|
+
|
|
64
|
+
### Step 4 — API Design (if Story involves backend API)
|
|
65
|
+
|
|
66
|
+
**If Story shows API design** (new endpoint, API contract change, exposing service):
|
|
67
|
+
Read `.tas/rules/common/api-design.md` for REST API conventions, then design API Spec before planning:
|
|
68
|
+
- URL structure, HTTP methods, status codes
|
|
69
|
+
- Request/response payload shape
|
|
70
|
+
- Pagination, filtering if needed
|
|
71
|
+
- Error response format
|
|
72
|
+
|
|
73
|
+
Attach API Spec to **Technical Plan → API Contract** section in Story.
|
|
74
|
+
If Story not API-related → skip this step.
|
|
75
|
+
|
|
76
|
+
### Step 5 — Technical Analysis
|
|
77
|
+
|
|
78
|
+
Based on Story + agent findings, list clearly:
|
|
79
|
+
|
|
80
|
+
**Files to change:**
|
|
81
|
+
| File | What change | Why |
|
|
82
|
+
|
|
83
|
+
**Files to create** (if any):
|
|
84
|
+
| File | Purpose |
|
|
85
|
+
|
|
86
|
+
**Database changes** (if any): migration, schema changes, seed data
|
|
87
|
+
|
|
88
|
+
**Config/Infrastructure changes** (if any): env vars, feature flags, new dependencies
|
|
89
|
+
|
|
90
|
+
**Need to update SAD?** Yes/No + brief reason
|
|
91
|
+
|
|
92
|
+
**Need new ADR?** Yes/No + brief reason
|
|
93
|
+
|
|
94
|
+
### Step 6 — Propose approach
|
|
95
|
+
|
|
96
|
+
If multiple feasible approaches, list 2-3 options:
|
|
97
|
+
```
|
|
98
|
+
Option A: [short description]
|
|
99
|
+
+ [pro]
|
|
100
|
+
- [con]
|
|
101
|
+
|
|
102
|
+
Option B: [short description]
|
|
103
|
+
+ [pro]
|
|
104
|
+
- [con]
|
|
105
|
+
```
|
|
106
|
+
Recommend best option and reason. If only 1 approach → present directly.
|
|
107
|
+
|
|
108
|
+
### Step 7 — Break Tasks
|
|
109
|
+
|
|
110
|
+
Break down into implementation-order tasks. Each task ~1-2 hours:
|
|
111
|
+
```
|
|
112
|
+
- [ ] Task 1: [specific action — which file, what change]
|
|
113
|
+
- [ ] Task 2: [specific action]
|
|
114
|
+
- [ ] Task 3: Write unit tests for [AC-1, AC-2...]
|
|
115
|
+
- [ ] Task 4: [if needed] Create ADR / update SAD
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
If total estimate > 8 hours → suggest splitting Story before continuing.
|
|
119
|
+
|
|
120
|
+
### Step 8 — Wait for approval
|
|
121
|
+
|
|
122
|
+
**STOP.** Display entire plan and ask:
|
|
123
|
+
> "Does the Technical Plan above look OK? Any adjustments?"
|
|
124
|
+
|
|
125
|
+
- If user approves → Step 9
|
|
126
|
+
- If user has feedback → update plan, ask again
|
|
127
|
+
- DO NOT write anything to Story before approval
|
|
128
|
+
|
|
129
|
+
### Step 9 — Write Technical Plan to Story
|
|
130
|
+
|
|
131
|
+
After approval, update Story file:
|
|
132
|
+
|
|
133
|
+
**1. Add section `## Technical Plan`** to Story (replace comment placeholder):
|
|
134
|
+
|
|
135
|
+
```markdown
|
|
136
|
+
## Technical Plan
|
|
137
|
+
> **Plan by:** {SE name} | **Date:** {current date}
|
|
138
|
+
|
|
139
|
+
### Approach
|
|
140
|
+
{Brief description of chosen approach and reason}
|
|
141
|
+
|
|
142
|
+
### Files to Change
|
|
143
|
+
| File | Change | Reason |
|
|
144
|
+
|------|--------|--------|
|
|
145
|
+
|
|
146
|
+
### Files to Create
|
|
147
|
+
| File | Purpose |
|
|
148
|
+
|------|---------|
|
|
149
|
+
|
|
150
|
+
### Database Changes
|
|
151
|
+
{If none: "None"}
|
|
152
|
+
|
|
153
|
+
### Config Changes
|
|
154
|
+
{If none: "None"}
|
|
155
|
+
|
|
156
|
+
### Architecture Notes
|
|
157
|
+
- SAD update needed: Yes/No
|
|
158
|
+
- New ADR needed: Yes/No — {title if Yes}
|
|
159
|
+
|
|
160
|
+
### Tasks
|
|
161
|
+
- [ ] Task 1: ...
|
|
162
|
+
- [ ] Task 2: ...
|
|
163
|
+
- [ ] Task 3: Write unit tests
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**2. Update frontmatter:**
|
|
167
|
+
- `plan_status: completed`
|
|
168
|
+
- `plan_date: {current datetime}`
|
|
169
|
+
|
|
170
|
+
**3. Update `project-status.yaml`:**
|
|
171
|
+
- `last_updated: {current date}`
|
|
172
|
+
- `epics.{EPIC_ID}.features.{FEATURE_ID}.stories.{STORY_ID}.plan_status: completed`
|
|
173
|
+
|
|
174
|
+
**4. If ADR needed:** run `/tas-adr "{Decision title}"` immediately after writing plan.
|
|
175
|
+
|
|
176
|
+
### Step 10 — Notify next step
|
|
177
|
+
> "Technical Plan written to Story. SE can start implementing with `/tas-dev {Story-ID}`."
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Quick Mode (require_plan: false in tas.yaml)
|
|
182
|
+
|
|
183
|
+
For: solo dev, prototype, spike, urgent hotfix.
|
|
184
|
+
|
|
185
|
+
- `/tas-dev` will NOT require running `/tas-plan` first
|
|
186
|
+
- `/tas-plan` can still be run voluntarily when Story is complex
|
|
187
|
+
- Trade-off: higher speed, lower traceability
|
|
188
|
+
|
|
189
|
+
## Principles
|
|
190
|
+
- Technical Plan lives in Story file — no separate plan file
|
|
191
|
+
- Each task ~1-2 hours; whole Story ~4-8 hours
|
|
192
|
+
- If estimate > 8 hours → split Story
|
|
193
|
+
- If task affects architecture → suggest ADR
|
|
194
|
+
- Keep plan concise, actionable — don't write essays
|
|
195
|
+
|
|
196
|
+
## Final Step — Token Log
|
|
197
|
+
|
|
198
|
+
Follow `.tas/rules/common/token-logging.md`: write AI Usage Log to working Story file.
|