@torus-engineering/tas-kit 1.9.0 → 1.11.1
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/commands/ado-create.md +17 -17
- package/.claude/commands/ado-delete.md +11 -11
- package/.claude/commands/ado-get.md +12 -12
- package/.claude/commands/ado-status.md +12 -12
- package/.claude/commands/ado-update.md +15 -15
- package/.claude/commands/tas-adr.md +33 -33
- package/.claude/commands/tas-apitest-plan.md +173 -173
- package/.claude/commands/tas-apitest.md +143 -143
- package/.claude/commands/tas-brainstorm.md +14 -14
- package/.claude/commands/tas-bug.md +113 -113
- package/.claude/commands/tas-design.md +37 -37
- package/.claude/commands/tas-dev.md +128 -128
- package/.claude/commands/tas-e2e-mobile.md +155 -155
- package/.claude/commands/tas-e2e-web.md +163 -163
- package/.claude/commands/tas-e2e.md +102 -102
- package/.claude/commands/tas-epic.md +35 -35
- package/.claude/commands/tas-feature.md +47 -47
- package/.claude/commands/tas-fix.md +51 -51
- package/.claude/commands/tas-functest-mobile.md +144 -144
- package/.claude/commands/tas-functest-web.md +192 -192
- package/.claude/commands/tas-functest.md +76 -76
- package/.claude/commands/tas-init.md +14 -14
- package/.claude/commands/tas-plan.md +198 -200
- package/.claude/commands/tas-prd.md +37 -37
- package/.claude/commands/tas-review.md +111 -111
- package/.claude/commands/tas-sad.md +43 -43
- package/.claude/commands/tas-security.md +87 -81
- package/.claude/commands/tas-spec.md +20 -20
- package/.claude/commands/tas-status.md +13 -13
- package/.claude/commands/tas-story.md +91 -91
- package/.claude/commands/tas-verify.md +51 -51
- package/.claude/rules/common/post-review-agent.md +49 -49
- package/.claude/rules/common/project-status.md +14 -14
- package/.claude/rules/common/stack-detection.md +6 -6
- package/.claude/rules/common/token-logging.md +27 -27
- package/.claude/rules/csharp/api-testing.md +171 -171
- package/.claude/skills/ado-integration/SKILL.md +36 -36
- package/.claude/skills/tas-conventions/SKILL.md +32 -32
- package/.claude/skills/tas-implementation-complete/SKILL.md +100 -99
- package/.claude/skills/tas-tdd/SKILL.md +123 -123
- package/.claude/skills/token-logger/SKILL.md +19 -19
- package/.tas/README.md +266 -1520
- package/.tas/checklists/code-review.md +13 -13
- package/.tas/checklists/security.md +3 -3
- package/.tas/checklists/story-done.md +11 -11
- package/.tas/hooks/README.md +138 -0
- package/.tas/hooks/pre-commit +26 -0
- package/.tas/hooks/security-scan.js +599 -0
- package/.tas/project-status-example.yaml +3 -3
- package/.tas/tas-example.yaml +25 -8
- package/.tas/templates/ADR.md +16 -16
- package/.tas/templates/API-Test-Spec.md +3 -3
- package/.tas/templates/Bug.md +12 -12
- package/.tas/templates/Design-Spec.md +8 -8
- package/.tas/templates/E2E-Execution-Report.md +1 -1
- package/.tas/templates/Epic.md +1 -1
- 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 +3 -3
- package/.tas/templates/Story.md +9 -9
- package/.tas/tools/tas-ado-readme.md +169 -169
- package/.tas/tools/tas-ado.py +1 -1
- package/CLAUDE-Example.md +37 -58
- package/README.md +294 -42
- package/bin/cli.js +24 -7
- package/lib/install.js +161 -47
- package/package.json +1 -1
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
# /tas-feature $ARGUMENTS
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
## Prerequisite
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
1.
|
|
11
|
-
2.
|
|
12
|
-
3.
|
|
13
|
-
|
|
14
|
-
###
|
|
15
|
-
4.
|
|
16
|
-
5.
|
|
17
|
-
6.
|
|
18
|
-
7.
|
|
19
|
-
8.
|
|
20
|
-
a. **Integration Test Cases**:
|
|
21
|
-
- "
|
|
22
|
-
- "
|
|
23
|
-
- "
|
|
24
|
-
|
|
25
|
-
b. **E2E / Acceptance Test Cases**:
|
|
26
|
-
- "
|
|
27
|
-
- "
|
|
28
|
-
- "
|
|
29
|
-
|
|
30
|
-
9.
|
|
31
|
-
|
|
32
|
-
###
|
|
33
|
-
4.
|
|
34
|
-
5.
|
|
35
|
-
6.
|
|
36
|
-
7.
|
|
37
|
-
8.
|
|
38
|
-
|
|
39
|
-
##
|
|
40
|
-
- Feature
|
|
41
|
-
- Feature
|
|
42
|
-
- Integration Test Cases
|
|
43
|
-
- E2E Test Cases
|
|
44
|
-
|
|
45
|
-
##
|
|
46
|
-
|
|
47
|
-
Invoke skill `token-logger`:
|
|
1
|
+
# /tas-feature $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Role: PE - Product Engineer
|
|
4
|
+
Create or update Feature document, including Integration Test and E2E/Acceptance Test design.
|
|
5
|
+
|
|
6
|
+
## Prerequisite
|
|
7
|
+
- At least one Epic must exist in docs/epics/
|
|
8
|
+
|
|
9
|
+
## Actions
|
|
10
|
+
1. Need context from root/tas.yaml
|
|
11
|
+
2. Need context from .tas/templates/Feature.md
|
|
12
|
+
3. Determine mode based on $ARGUMENTS:
|
|
13
|
+
|
|
14
|
+
### CREATE mode ($ARGUMENTS is new Feature description, or no $ARGUMENTS):
|
|
15
|
+
4. Read project.code from root/tas.yaml. List existing Epics, ask user which Epic this Feature belongs to.
|
|
16
|
+
5. Scan selected Epic directory to determine Feature sequence number.
|
|
17
|
+
6. Create directory docs/epics/{code}-Epic-{NNN}-{slug}/{code}-Feature-{NNN}-{slug}/
|
|
18
|
+
7. Create file {code}-Feature-{NNN}-{slug}.md in that directory
|
|
19
|
+
8. After PE fills description and acceptance criteria, AUTOMATICALLY switch to test design:
|
|
20
|
+
a. **Integration Test Cases**: Ask PE:
|
|
21
|
+
- "Which services/modules does this Feature interact with?"
|
|
22
|
+
- "What linked flows between stories need testing?"
|
|
23
|
+
- "Any data flows needing end-to-end verification within this feature?"
|
|
24
|
+
Write to Integration Test Cases section.
|
|
25
|
+
b. **E2E / Acceptance Test Cases**: Ask PE:
|
|
26
|
+
- "What's the main user scenario to verify this feature on Staging?"
|
|
27
|
+
- "Any scenarios needing real or near-real data testing?"
|
|
28
|
+
- "Which acceptance criteria need manual PE verification?"
|
|
29
|
+
Write to E2E Test Cases section. This is the checklist PE uses in Phase 2 when running /tas-verify.
|
|
30
|
+
9. Update `project-status.yaml` per `.claude/rules/common/project-status.md` — add entry to `epics.{EPIC_ID}.features`.
|
|
31
|
+
|
|
32
|
+
### UPDATE mode ($ARGUMENTS is Feature ID, e.g., "Feature-003"):
|
|
33
|
+
4. Find Feature file in docs/epics/ tree (using glob)
|
|
34
|
+
5. Need context from current Feature file
|
|
35
|
+
6. Ask user what needs changing (add story, update AC, add test cases, change status...)
|
|
36
|
+
7. Update file, add changelog
|
|
37
|
+
8. Update `project-status.yaml` per `.claude/rules/common/project-status.md` — update `epics.{EPIC_ID}.features.{FEATURE_ID}.status`.
|
|
38
|
+
|
|
39
|
+
## Principles
|
|
40
|
+
- Feature is a specific function that can be demoed
|
|
41
|
+
- Feature MUST have clear, testable acceptance criteria
|
|
42
|
+
- Integration Test Cases MUST cover linked flows between stories
|
|
43
|
+
- E2E Test Cases MUST be sufficient for PE to verify feature on Staging in Phase 2
|
|
44
|
+
|
|
45
|
+
## Final Step — Token Log
|
|
46
|
+
|
|
47
|
+
Invoke skill `token-logger`: write AI Usage Log to working Feature file.
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
# /tas-fix $ARGUMENTS
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Quick fix
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Stack Detection
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
### 1.
|
|
14
|
-
$ARGUMENTS
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
### 2. Diagnose (
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
### 3. Fix
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- `.claude/rules/common/security.md` —
|
|
29
|
-
- `.claude/rules/common/testing.md` —
|
|
30
|
-
- `.claude/rules/[lang_rules]/coding-style.md` —
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
a.
|
|
34
|
-
b.
|
|
35
|
-
c. Fix code
|
|
36
|
-
d.
|
|
37
|
-
e.
|
|
38
|
-
|
|
39
|
-
### 4. Wrap up
|
|
40
|
-
- Output commit message: `fix: <
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
##
|
|
44
|
-
-
|
|
45
|
-
- Fix
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
##
|
|
50
|
-
|
|
51
|
-
Invoke skill `token-logger`:
|
|
1
|
+
# /tas-fix $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Role: SE - Software Engineer
|
|
4
|
+
Quick fix for small bugs or obvious errors — no ticket needed, no full lifecycle.
|
|
5
|
+
Use when: solo dev, quick hotfix, bug found during development.
|
|
6
|
+
Differs from /tas-bug: no Bug file created, no status tracking, no deploy flow.
|
|
7
|
+
|
|
8
|
+
## Stack Detection
|
|
9
|
+
Read `.claude/rules/common/stack-detection.md`.
|
|
10
|
+
|
|
11
|
+
## Actions
|
|
12
|
+
|
|
13
|
+
### 1. Understand bug
|
|
14
|
+
$ARGUMENTS is error description, error message, or file:line_number.
|
|
15
|
+
- If error message/stack trace provided: parse immediately, identify error file and line
|
|
16
|
+
- If only description: ask exactly 1 clarifying question (reproduce steps or expected vs actual)
|
|
17
|
+
- DO NOT ask more than 1 question
|
|
18
|
+
|
|
19
|
+
### 2. Diagnose (max 3 files read)
|
|
20
|
+
- Read error file and directly related files
|
|
21
|
+
- Identify root cause in 1-2 short sentences
|
|
22
|
+
- DO NOT read entire project, DO NOT scan folder structure
|
|
23
|
+
- If need to read more files beyond first 3: ask user confirmation
|
|
24
|
+
|
|
25
|
+
### 3. Fix with regression test
|
|
26
|
+
|
|
27
|
+
Before fixing, read relevant rules:
|
|
28
|
+
- `.claude/rules/common/security.md` — check if fix creates security risks
|
|
29
|
+
- `.claude/rules/common/testing.md` — regression test writing patterns
|
|
30
|
+
- `.claude/rules/[lang_rules]/coding-style.md` — current stack conventions (if identifiable)
|
|
31
|
+
|
|
32
|
+
Then:
|
|
33
|
+
a. Write 1 minimal test case reproducing bug (if project has test framework)
|
|
34
|
+
b. Confirm test FAILS
|
|
35
|
+
c. Fix code at root cause
|
|
36
|
+
d. Confirm test PASSES
|
|
37
|
+
e. Quick run of test suite if available (to check regression)
|
|
38
|
+
|
|
39
|
+
### 4. Wrap up
|
|
40
|
+
- Output commit message: `fix: <short description>`
|
|
41
|
+
- Remind: "If this bug may recur or affects production, consider using /tas-bug for full tracking."
|
|
42
|
+
|
|
43
|
+
## Principles
|
|
44
|
+
- Total files read ≤ 3 unless permitted
|
|
45
|
+
- Fix at root cause, DO NOT patch symptom
|
|
46
|
+
- If fix leads to architecture change → stop, suggest using /tas-bug + /tas-adr
|
|
47
|
+
- If bug is in production with high severity → stop, suggest using /tas-bug with severity Critical/High
|
|
48
|
+
|
|
49
|
+
## Final Step — Token Log
|
|
50
|
+
|
|
51
|
+
Invoke skill `token-logger`: write AI Usage Log to related Story or Bug file (if any).
|
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
# /tas-functest-mobile $ARGUMENTS
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Generate
|
|
5
|
-
|
|
6
|
-
##
|
|
7
|
-
-
|
|
8
|
-
- Scripts
|
|
9
|
-
- Reusable helpers
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
###
|
|
15
|
-
1. $ARGUMENTS
|
|
16
|
-
2.
|
|
17
|
-
3.
|
|
18
|
-
|
|
19
|
-
###
|
|
20
|
-
1.
|
|
21
|
-
> "Mobile app
|
|
22
|
-
2.
|
|
23
|
-
```
|
|
24
|
-
docs/epics/{epic-dir}/{feature-dir}/Func-Test-*.md
|
|
25
|
-
```
|
|
26
|
-
3.
|
|
27
|
-
> "
|
|
28
|
-
4.
|
|
29
|
-
5.
|
|
30
|
-
|
|
31
|
-
###
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
###
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
**File output**: `apps/mobile/e2e/features/{epic-slug}/{feature-slug}/{story-slug}.func.e2e.ts`
|
|
40
|
-
|
|
41
|
-
**Structure**:
|
|
42
|
-
```typescript
|
|
43
|
-
/**
|
|
44
|
-
* Functional Tests: {Story Name}
|
|
45
|
-
* Story: {Story_ID}
|
|
46
|
-
* Feature: {Feature_ID}
|
|
47
|
-
* Epic: {Epic_ID}
|
|
48
|
-
*
|
|
49
|
-
* Generated by /tas-functest-mobile
|
|
50
|
-
* Spec: docs/epics/{epic-dir}/{feature-dir}/Func-Test-{story-slug}.md
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
import { device, element, expect, by, waitFor } from 'detox';
|
|
54
|
-
import { TEST_IDS } from '../../../test-ids';
|
|
55
|
-
import { loadTestData, getCredentials } from '../../../helpers/data-loader';
|
|
56
|
-
import { login, navigateTo } from '../../../helpers/test-utils';
|
|
57
|
-
|
|
58
|
-
const testData = loadTestData();
|
|
59
|
-
|
|
60
|
-
describe('{Feature Name} - {Story Name}', () => {
|
|
61
|
-
beforeAll(async () => {
|
|
62
|
-
await device.launchApp({ newInstance: true });
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
beforeEach(async () => {
|
|
66
|
-
await device.reloadReactNative();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// AC Reference: AC-1
|
|
70
|
-
describe('{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_001_H', () => {
|
|
71
|
-
it('should {description from spec}', async () => {
|
|
72
|
-
// Given: {precondition}
|
|
73
|
-
// When: {action}
|
|
74
|
-
// Then: {expected}
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
###
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
###
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
/**
|
|
89
|
-
* Reusable helpers
|
|
90
|
-
*
|
|
91
|
-
*/
|
|
92
|
-
|
|
93
|
-
export async function {featureSpecificHelper}() {
|
|
94
|
-
// Helper logic extracted from functional tests
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
###
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
"functest:mobile:{feature-slug}": "detox test --configuration ios.sim.debug --testPathPattern='e2e/features/{epic-slug}/{feature-slug}'"
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
###
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
export * from './helpers';
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## File Structure Output
|
|
111
|
-
```
|
|
112
|
-
apps/mobile/e2e/features/
|
|
113
|
-
└── {epic-slug}/
|
|
114
|
-
└── {feature-slug}/
|
|
115
|
-
├── {story-1-slug}.func.e2e.ts
|
|
116
|
-
├── {story-2-slug}.func.e2e.ts
|
|
117
|
-
├── helpers.ts
|
|
118
|
-
└── index.ts
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Test Data Convention
|
|
122
|
-
- **Hardcoded values**:
|
|
123
|
-
- **Credentials**: `const creds = getCredentials();` → password
|
|
124
|
-
- **Environment data**: `const testData = loadTestData();` →
|
|
125
|
-
- **
|
|
126
|
-
|
|
127
|
-
##
|
|
128
|
-
```bash
|
|
129
|
-
#
|
|
130
|
-
yarn functest:mobile:{feature-slug}
|
|
131
|
-
|
|
132
|
-
#
|
|
133
|
-
npx detox test --configuration ios.sim.debug --testPathPattern='e2e/features/{epic}/{feature}/{story}'
|
|
134
|
-
|
|
135
|
-
#
|
|
136
|
-
npx detox test --configuration android.emu.debug --testPathPattern='e2e/features/{epic}/{feature}'
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
##
|
|
140
|
-
- Script
|
|
141
|
-
-
|
|
142
|
-
- Helpers
|
|
143
|
-
-
|
|
144
|
-
-
|
|
1
|
+
# /tas-functest-mobile $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Role: SE / QA
|
|
4
|
+
Generate all Detox automation test scripts for a mobile Feature.
|
|
5
|
+
|
|
6
|
+
## IMPORTANT - Layer 2: Mobile Functional Test Scripts
|
|
7
|
+
- Create Detox test scripts from Func-Test-Spec (markdown)
|
|
8
|
+
- Scripts located in `apps/mobile/e2e/features/`
|
|
9
|
+
- Reusable helpers exported for Layer 3 (E2E) reuse
|
|
10
|
+
- Hardcoded data in tests, credentials from .env
|
|
11
|
+
|
|
12
|
+
## Actions
|
|
13
|
+
|
|
14
|
+
### Step 1: Identify Feature
|
|
15
|
+
1. $ARGUMENTS is Feature ID or file path
|
|
16
|
+
2. If not provided: scan `docs/epics/**/Feature-*.md` for features with status In Progress
|
|
17
|
+
3. Read Feature file to get Epic/Feature numbers and list of Stories
|
|
18
|
+
|
|
19
|
+
### Step 2: Check Prerequisites
|
|
20
|
+
1. Check `apps/mobile/` exists. If not → error:
|
|
21
|
+
> "Mobile app doesn't exist in this project. Please create apps/mobile/ first."
|
|
22
|
+
2. Find all `Func-Test-*.md` files in Feature directory:
|
|
23
|
+
```
|
|
24
|
+
docs/epics/{epic-dir}/{feature-dir}/Func-Test-*.md
|
|
25
|
+
```
|
|
26
|
+
3. If no Func-Test-Spec exists → error:
|
|
27
|
+
> "No Func-Test-Spec for this Feature yet. Run /tas-functest {story-ID} first."
|
|
28
|
+
4. Read `apps/mobile/e2e/test-ids.ts` to know existing testIDs
|
|
29
|
+
5. Read `apps/mobile/e2e/helpers/data-loader.ts` and `test-utils.ts` to understand patterns
|
|
30
|
+
|
|
31
|
+
### Step 3: Aggregate FT Test Cases
|
|
32
|
+
- From all Func-Test-Spec files, aggregate list of FT test cases
|
|
33
|
+
- Group by Story
|
|
34
|
+
- Get test data requirements from each spec
|
|
35
|
+
|
|
36
|
+
### Step 4: Generate Test Scripts
|
|
37
|
+
For EACH Story with Func-Test-Spec:
|
|
38
|
+
|
|
39
|
+
**File output**: `apps/mobile/e2e/features/{epic-slug}/{feature-slug}/{story-slug}.func.e2e.ts`
|
|
40
|
+
|
|
41
|
+
**Structure**:
|
|
42
|
+
```typescript
|
|
43
|
+
/**
|
|
44
|
+
* Functional Tests: {Story Name}
|
|
45
|
+
* Story: {Story_ID}
|
|
46
|
+
* Feature: {Feature_ID}
|
|
47
|
+
* Epic: {Epic_ID}
|
|
48
|
+
*
|
|
49
|
+
* Generated by /tas-functest-mobile
|
|
50
|
+
* Spec: docs/epics/{epic-dir}/{feature-dir}/Func-Test-{story-slug}.md
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
import { device, element, expect, by, waitFor } from 'detox';
|
|
54
|
+
import { TEST_IDS } from '../../../test-ids';
|
|
55
|
+
import { loadTestData, getCredentials } from '../../../helpers/data-loader';
|
|
56
|
+
import { login, navigateTo } from '../../../helpers/test-utils';
|
|
57
|
+
|
|
58
|
+
const testData = loadTestData();
|
|
59
|
+
|
|
60
|
+
describe('{Feature Name} - {Story Name}', () => {
|
|
61
|
+
beforeAll(async () => {
|
|
62
|
+
await device.launchApp({ newInstance: true });
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
beforeEach(async () => {
|
|
66
|
+
await device.reloadReactNative();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// AC Reference: AC-1
|
|
70
|
+
describe('{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_001_H', () => {
|
|
71
|
+
it('should {description from spec}', async () => {
|
|
72
|
+
// Given: {precondition}
|
|
73
|
+
// When: {action}
|
|
74
|
+
// Then: {expected}
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Step 5: Update test-ids.ts (if needed)
|
|
81
|
+
- If test cases need testID not in test-ids.ts
|
|
82
|
+
- Add new testID per current naming convention
|
|
83
|
+
- Keep structure: nested object with dot notation
|
|
84
|
+
|
|
85
|
+
### Step 6: Generate Feature Helpers
|
|
86
|
+
Create file `apps/mobile/e2e/features/{epic-slug}/{feature-slug}/helpers.ts`:
|
|
87
|
+
```typescript
|
|
88
|
+
/**
|
|
89
|
+
* Reusable helpers for {Feature Name}
|
|
90
|
+
* Exported for Layer 3 E2E scripts reuse
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
export async function {featureSpecificHelper}() {
|
|
94
|
+
// Helper logic extracted from functional tests
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Step 7: Update package.json Script
|
|
99
|
+
Add or update script in `apps/mobile/package.json`:
|
|
100
|
+
```json
|
|
101
|
+
"functest:mobile:{feature-slug}": "detox test --configuration ios.sim.debug --testPathPattern='e2e/features/{epic-slug}/{feature-slug}'"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Step 8: Generate Index
|
|
105
|
+
Create `apps/mobile/e2e/features/{epic-slug}/{feature-slug}/index.ts`:
|
|
106
|
+
```typescript
|
|
107
|
+
export * from './helpers';
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## File Structure Output
|
|
111
|
+
```
|
|
112
|
+
apps/mobile/e2e/features/
|
|
113
|
+
└── {epic-slug}/
|
|
114
|
+
└── {feature-slug}/
|
|
115
|
+
├── {story-1-slug}.func.e2e.ts
|
|
116
|
+
├── {story-2-slug}.func.e2e.ts
|
|
117
|
+
├── helpers.ts
|
|
118
|
+
└── index.ts
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Test Data Convention
|
|
122
|
+
- **Hardcoded values**: Directly in test (e.g., "invalid@email", "short")
|
|
123
|
+
- **Credentials**: `const creds = getCredentials();` → password from process.env
|
|
124
|
+
- **Environment data**: `const testData = loadTestData();` → read from test-data.{env}.json
|
|
125
|
+
- **NEVER** hardcode passwords/tokens in test files
|
|
126
|
+
|
|
127
|
+
## Run Tests
|
|
128
|
+
```bash
|
|
129
|
+
# Run all func tests for feature
|
|
130
|
+
yarn functest:mobile:{feature-slug}
|
|
131
|
+
|
|
132
|
+
# Run only one story
|
|
133
|
+
npx detox test --configuration ios.sim.debug --testPathPattern='e2e/features/{epic}/{feature}/{story}'
|
|
134
|
+
|
|
135
|
+
# Run with Android
|
|
136
|
+
npx detox test --configuration android.emu.debug --testPathPattern='e2e/features/{epic}/{feature}'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Principles
|
|
140
|
+
- Script MUST be runnable directly from CLI, WITHOUT Claude window
|
|
141
|
+
- Each describe block uses full FT ID for grep-ability
|
|
142
|
+
- Helpers MUST export for Layer 3 reuse
|
|
143
|
+
- DO NOT import from Layer 3 (flows/), only export UP to Layer 3
|
|
144
|
+
- If apps/mobile/ doesn't exist → graceful error, DO NOT create
|