@sun-asterisk/sungen 2.0.0 → 2.0.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.
Files changed (31) hide show
  1. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  2. package/dist/generators/test-generator/code-generator.js +10 -0
  3. package/dist/generators/test-generator/code-generator.js.map +1 -1
  4. package/dist/generators/test-generator/step-mapper.d.ts +4 -0
  5. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  6. package/dist/generators/test-generator/step-mapper.js +8 -0
  7. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  8. package/dist/orchestrator/project-initializer.d.ts +4 -0
  9. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  10. package/dist/orchestrator/project-initializer.js +11 -410
  11. package/dist/orchestrator/project-initializer.js.map +1 -1
  12. package/dist/orchestrator/templates/ai-rules.md +189 -0
  13. package/dist/orchestrator/templates/gitignore +16 -0
  14. package/dist/orchestrator/templates/playwright.config.d.ts +10 -0
  15. package/dist/orchestrator/templates/playwright.config.d.ts.map +1 -0
  16. package/dist/orchestrator/templates/playwright.config.js +77 -0
  17. package/dist/orchestrator/templates/playwright.config.js.map +1 -0
  18. package/dist/orchestrator/templates/playwright.config.ts +80 -0
  19. package/dist/orchestrator/templates/readme.md +197 -0
  20. package/docs/gherkin standards/gherkin-core-standard.md +377 -0
  21. package/docs/gherkin standards/gherkin-core-standard.vi.md +303 -0
  22. package/docs/gherkin-dictionary.md +1071 -0
  23. package/docs/makeauth.md +225 -0
  24. package/package.json +3 -2
  25. package/src/generators/test-generator/code-generator.ts +11 -0
  26. package/src/generators/test-generator/step-mapper.ts +9 -0
  27. package/src/orchestrator/project-initializer.ts +12 -410
  28. package/src/orchestrator/templates/ai-rules.md +189 -0
  29. package/src/orchestrator/templates/gitignore +16 -0
  30. package/src/orchestrator/templates/playwright.config.ts +80 -0
  31. package/src/orchestrator/templates/readme.md +197 -0
@@ -236,124 +236,19 @@ export class ProjectInitializer {
236
236
  }
237
237
  }
238
238
 
239
+ /**
240
+ * Read a template file from the templates directory
241
+ */
242
+ private readTemplate(filename: string): string {
243
+ const templatePath = path.join(__dirname, 'templates', filename);
244
+ return fs.readFileSync(templatePath, 'utf-8');
245
+ }
246
+
239
247
  /**
240
248
  * Get AI rules content (shared between Copilot and Claude)
241
249
  */
242
250
  private getAIRulesContent(): string {
243
- return `# Sungen AI Rules
244
-
245
- You assist with generating E2E test files for the sungen framework.
246
- sungen compiles Gherkin features + selector YAML + test data → Playwright tests.
247
-
248
- ## File Structure
249
-
250
- Each screen lives under \`qa/screens/<name>/\`:
251
- \`\`\`
252
- qa/screens/<name>/
253
- ├── features/ # .feature files (Gherkin)
254
- │ ├── <name>.feature
255
- │ └── <name>-<topic>.feature
256
- ├── selectors/ # Element locator mappings
257
- │ └── <name>.yaml
258
- └── test-data/ # Test data values
259
- └── <name>.yaml
260
- \`\`\`
261
-
262
- ## Gherkin Syntax
263
-
264
- Standard pattern: \`User <action> [<Target>] <type> with {{<Value>}}\`
265
-
266
- \`[Element]\` → selector reference (mapped in selectors YAML)
267
- \`{{variable}}\` → test data reference (mapped in test-data YAML)
268
-
269
- ### Pattern Shapes
270
-
271
- 1. \`User click [Submit] button\` — simple action
272
- 2. \`User fill [Email] field with {{email}}\` — action with data
273
- 3. \`User see [Submit] button is disabled\` — state assertion
274
- 4. \`User see [Panel] dialog with {{title}} is hidden\` — data + state
275
- 5. \`User drag [Card] to [Column]\` — two targets
276
- 6. \`User press Escape key\` — global keyboard
277
- 7. \`User press Enter on [Search] field\` — key on target
278
- 8. \`User wait for 3 seconds\` — timeout
279
- 9. \`User wait for [Modal] dialog is hidden\` — wait for state
280
- 10. \`User scroll to [Footer] section\` — scroll
281
- 11. \`User switch to [Payment] frame\` — iframe
282
- 12. \`User see [Avatar] image has {{url}}\` — attribute check
283
- 13. \`User see [Table] table row 1 [Name] cell with {{name}}\` — table by index
284
- 14. \`User see [Table] table row with {{filter}} has [Col] with {{val}}\` — table by filter
285
- 15. \`User click [Edit] in [Table] table row with {{name}}\` — action in table
286
- 16. \`User is on [login] page\` — navigation
287
- 17. \`User see [Message] text contains {{partial}}\` — text assertion
288
-
289
- ### States: hidden, visible, disabled, enabled, checked, unchecked, focused, empty
290
-
291
- ### Tags:
292
- - \`@auth:role\` — Playwright storage state for auth
293
- - \`@steps:name\` — Define reusable step group
294
- - \`@extend:name\` — Inherit steps from another scenario
295
- - \`@manual\` — Skip scenario in generation
296
-
297
- ## Selector YAML Schema
298
-
299
- \`\`\`yaml
300
- element.key:
301
- type: 'testid'|'role'|'text'|'label'|'placeholder'|'locator'|'page'|'upload'|'frame'
302
- value: 'button' # role name, testid, CSS selector, etc.
303
- name: 'Submit' # accessible name
304
- nth: 0 # element index
305
-
306
- # Disambiguation
307
- exact: true # exact name match (avoid substring collisions)
308
- scope: 'desktop navigation' # parent landmark to scope within
309
- match: 'exact' # for getByText exact matching
310
-
311
- # Complex elements
312
- variant: 'native'|'custom' # dropdown: <select> vs div-based
313
- trigger: 'Upload Photo' # button that triggers hidden file input
314
- frame: '#iframe-id' # iframe selector
315
- contenteditable: true # rich text editor
316
-
317
- # Table columns (for table type)
318
- columns:
319
- name: { index: 0, header: 'Name' }
320
- status: { index: 2, header: 'Status' }
321
- \`\`\`
322
-
323
- ### Locator priority: data-testid > role+name > label > text > CSS
324
-
325
- ## How to Generate from a URL
326
-
327
- 1. Navigate to URL with Playwright MCP
328
- 2. Take accessibility snapshot
329
- 3. For each interactive element, create selector entry
330
- 4. Prefer data-testid > role+name > text > CSS
331
- 5. Set \`exact: true\` when name is substring of another element
332
- 6. Set \`scope\` when element duplicated in header/footer
333
- 7. Generate Gherkin scenarios covering the page
334
- 8. Fill test-data with actual values from page
335
-
336
- ## How to Fix Failing Tests
337
-
338
- | Error | Fix in selectors.yaml |
339
- |---|---|
340
- | strict mode: resolved to N elements | Add \`exact: true\` or \`scope\` |
341
- | element(s) not found | Fix \`name\`, \`type\`, or \`value\` |
342
- | getByText matched too many | Add \`match: 'exact'\` |
343
-
344
- ## Commands
345
-
346
- \`\`\`bash
347
- sungen add --screen <name> --path <url-path> # Create screen
348
- sungen generate --screen <name> # Compile to .spec.ts
349
- sungen generate --all # Compile all screens
350
- sungen makeauth <role> # Capture auth state
351
- \`\`\`
352
-
353
- ## Design Doc
354
-
355
- See \`docs/gherkin-dictionary.md\` for the complete grammar, all 17 patterns, and compiler rules.
356
- `;
251
+ return this.readTemplate('ai-rules.md');
357
252
  }
358
253
 
359
254
  /**
@@ -379,313 +274,20 @@ See \`docs/gherkin-dictionary.md\` for the complete grammar, all 17 patterns, an
379
274
  * Get Playwright configuration template
380
275
  */
381
276
  private getPlaywrightConfigTemplate(): string {
382
- return `import { defineConfig, devices } from '@playwright/test';
383
-
384
- /**
385
- * Read environment variables from file.
386
- * https://github.com/motdotla/dotenv
387
- */
388
- // import dotenv from 'dotenv';
389
- // import path from 'path';
390
- // dotenv.config({ path: path.resolve(__dirname, '.env') });
391
-
392
- /**
393
- * See https://playwright.dev/docs/test-configuration.
394
- */
395
- export default defineConfig({
396
- testDir: './specs/generated',
397
- /* Run tests in files in parallel */
398
- fullyParallel: true,
399
- /* Fail the build on CI if you accidentally left test.only in the source code. */
400
- forbidOnly: !!process.env.CI,
401
- /* Retry on CI only */
402
- retries: process.env.CI ? 2 : 0,
403
- /* Opt out of parallel tests on CI. */
404
- workers: process.env.CI ? 1 : undefined,
405
- /* Reporter to use. See https://playwright.dev/docs/test-reporters */
406
- reporter: 'html',
407
- /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
408
- use: {
409
- /* Base URL to use in actions like \`await page.goto('')\`. */
410
- baseURL: 'https://example.com',
411
-
412
- /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
413
- trace: 'on-first-retry',
414
- },
415
-
416
- /* Configure projects for major browsers */
417
- projects: [
418
- {
419
- name: 'chromium',
420
- use: { ...devices['Desktop Chrome'] },
421
- },
422
-
423
- /*
424
- // {
425
- // name: 'firefox',
426
- // use: { ...devices['Desktop Firefox'] },
427
- // },
428
-
429
- // {
430
- // name: 'webkit',
431
- // use: { ...devices['Desktop Safari'] },
432
- // },
433
-
434
- /* Test against mobile viewports.
435
- // {
436
- // name: 'Mobile Chrome',
437
- // use: { ...devices['Pixel 5'] },
438
- // },
439
- // {
440
- // name: 'Mobile Safari',
441
- // use: { ...devices['iPhone 12'] },
442
- // },
443
-
444
- /* Test against branded browsers. */
445
- // {
446
- // name: 'Microsoft Edge',
447
- // use: { ...devices['Desktop Edge'], channel: 'msedge' },
448
- // },
449
- // {
450
- // name: 'Google Chrome',
451
- // use: { ...devices['Desktop Chrome'], channel: 'chrome' },
452
- // },
453
- ],
454
-
455
- /* Run your local dev server before starting the tests */
456
- // webServer: {
457
- // command: 'npm run start',
458
- // url: 'http://localhost:3000',
459
- // reuseExistingServer: !process.env.CI,
460
- // },
461
- });
462
- `;
277
+ return this.readTemplate('playwright.config.ts');
463
278
  }
464
279
 
465
280
  /**
466
281
  * Get .gitignore template
467
282
  */
468
283
  private getGitignoreTemplate(): string {
469
- return `# Dependencies
470
- node_modules/
471
-
472
- # Build output
473
- dist/
474
- build/
475
-
476
- # Environment variables
477
- .env
478
- .env.local
479
-
480
- # IDE
481
- .vscode/
482
- .idea/
483
- *.swp
484
- *.swo
485
- `;
284
+ return this.readTemplate('gitignore');
486
285
  }
487
286
 
488
287
  /**
489
288
  * Get README template
490
289
  */
491
290
  private getReadmeTemplate(): string {
492
- return `# Sungen Test Automation
493
-
494
- This project uses [Sungen v2](https://github.com/sun-asterisk/sungen) — a deterministic E2E test compiler.
495
-
496
- ## How it works
497
-
498
- \`\`\`
499
- AI (Copilot/Claude + MCP Playwright) → visits URL → generates files
500
- sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
501
- \`\`\`
502
-
503
- ## Directory Structure
504
-
505
- \`\`\`
506
- ├── qa/screens/<name>/
507
- │ ├── features/ # .feature files (Gherkin)
508
- │ ├── selectors/ # Element locator YAML mappings
509
- │ └── test-data/ # Test data YAML values
510
- ├── specs/
511
- │ ├── generated/ # Auto-generated Playwright tests
512
- │ └── .auth/ # Auth storage states
513
- ├── docs/
514
- │ └── gherkin-dictionary.md # Full grammar & compiler rules
515
- ├── .github/
516
- │ └── copilot-instructions.md # AI rules for GitHub Copilot
517
- └── CLAUDE.md # AI rules for Claude Code
518
- \`\`\`
519
-
520
- ## Workflow
521
-
522
- ### 1. Add a screen
523
-
524
- \`\`\`bash
525
- sungen add --screen login --path /login
526
- # Add more features to an existing screen:
527
- sungen add --screen login --feature forgot-password
528
- \`\`\`
529
-
530
- ### 2. Set up auth (if needed)
531
-
532
- \`\`\`bash
533
- sungen makeauth admin
534
- # Opens browser → login manually → saves specs/.auth/admin.json
535
- \`\`\`
536
-
537
- ### 3. Generate Gherkin + selectors with AI
538
-
539
- Use your AI assistant (GitHub Copilot or Claude Code) to:
540
- 1. Navigate to the page URL via MCP Playwright
541
- 2. Take an accessibility snapshot
542
- 3. Generate \`.feature\` + \`selectors.yaml\` + \`test-data.yaml\`
543
-
544
- The AI rules in \`.github/copilot-instructions.md\` and \`CLAUDE.md\` teach the AI
545
- how to write correct Gherkin syntax and selector YAML for sungen.
546
-
547
- ### 4. Compile to Playwright tests
548
-
549
- \`\`\`bash
550
- sungen generate --screen login
551
- # or for all screens:
552
- sungen generate --all
553
- \`\`\`
554
-
555
- ### 5. Run tests
556
-
557
- \`\`\`bash
558
- npx playwright test
559
- npx playwright test --ui # interactive mode
560
- \`\`\`
561
-
562
- ### 6. Fix failures (AI Verify loop)
563
-
564
- When tests fail, use AI to read the error → fix \`selectors.yaml\` → recompile → re-run.
565
-
566
- | Error | Fix in selectors.yaml |
567
- |---|---|
568
- | strict mode: resolved to N elements | Add \`exact: true\` or \`scope\` or \`nth\` |
569
- | element(s) not found | Fix \`name\`, \`type\`, or \`value\` |
570
- | getByText matched too many | Add \`match: 'exact'\` or \`nth\` |
571
-
572
- ---
573
-
574
- ## Gherkin Guide
575
-
576
- ### Syntax
577
-
578
- \`\`\`
579
- User <action> [<Target>] <type> with {{<Value>}}
580
- \`\`\`
581
-
582
- - \`[Target]\` → selector reference → lookup in \`selectors/*.yaml\`
583
- - \`{{Value}}\` → test data reference → lookup in \`test-data/*.yaml\`
584
- - \`<type>\` → element type: button, link, field, heading, text, etc.
585
-
586
- ### Pattern Shapes (17 total)
587
-
588
- #### Actions
589
-
590
- | Pattern | Example |
591
- |---|---|
592
- | Simple click | \`User click [Submit] button\` |
593
- | Click with data | \`User click [Teammate] button with {{name}}\` |
594
- | Fill field | \`User fill [Email] field with {{email}}\` |
595
- | Check/Uncheck | \`User check [Remember me] checkbox\` |
596
- | Select dropdown | \`User select [Country] dropdown with {{country}}\` |
597
- | Upload file | \`User upload [Avatar] file with {{path}}\` |
598
- | Double click | \`User double click [Cell] element\` |
599
- | Hover | \`User hover [Info] icon\` |
600
- | Clear | \`User clear [Search] field\` |
601
-
602
- #### Keyboard
603
-
604
- | Pattern | Example |
605
- |---|---|
606
- | Global key | \`User press Escape key\` |
607
- | Key on element | \`User press Enter on [Search] field\` |
608
-
609
- #### Navigation
610
-
611
- | Pattern | Example |
612
- |---|---|
613
- | Open page | \`User is on [login] page\` |
614
- | See page (URL) | \`User see [dashboard] page\` |
615
-
616
- #### Wait
617
-
618
- | Pattern | Example |
619
- |---|---|
620
- | Wait timeout | \`User wait for 3 seconds\` |
621
- | Wait element | \`User wait for [Modal] dialog\` |
622
- | Wait hidden | \`User wait for [Loading] spinner is hidden\` |
623
- | Wait with data | \`User wait for [Dialog] dialog with {{title}}\` |
624
-
625
- #### Assertions
626
-
627
- | Pattern | Example |
628
- |---|---|
629
- | See element | \`User see [Welcome] heading\` |
630
- | See with value | \`User see [Title] heading with {{title}}\` |
631
- | State check | \`User see [Submit] button is disabled\` |
632
- | State + data | \`User see [Panel] dialog with {{title}} is hidden\` |
633
- | Text contains | \`User see [Message] text contains {{partial}}\` |
634
-
635
- States: \`hidden\`, \`visible\`, \`disabled\`, \`enabled\`, \`checked\`, \`unchecked\`, \`focused\`, \`empty\`
636
-
637
- #### Table
638
-
639
- | Pattern | Example |
640
- |---|---|
641
- | Row exists | \`User see [Users] table has row with {{name}}\` |
642
- | No row | \`User see [Users] table has no row with {{name}}\` |
643
- | Row count | \`User see [Users] table has {{count}} rows\` |
644
- | Column exists | \`User see [Users] table has [Email] column\` |
645
- | Cell by filter | \`User see [Users] table row with {{name}} has [Status] with {{status}}\` |
646
- | Cell by index | \`User see [Users] table row 1 [Name] cell with {{name}}\` |
647
- | Action in row | \`User click [Edit] in [Users] table row with {{name}}\` |
648
- | Empty table | \`User see [Users] table is empty\` |
649
-
650
- #### Scope
651
-
652
- | Pattern | Example |
653
- |---|---|
654
- | Scroll | \`User scroll to [Footer] section\` |
655
- | Frame enter | \`User switch to [Payment] frame\` |
656
- | Frame exit | \`User switch to [main] frame\` |
657
-
658
- ### Tags
659
-
660
- | Tag | Purpose |
661
- |---|---|
662
- | \`@auth:role\` | Use Playwright storage state for auth |
663
- | \`@steps:name\` | Define reusable step group |
664
- | \`@extend:name\` | Inherit steps from another scenario |
665
- | \`@manual\` | Skip scenario in generation |
666
-
667
- ### Selector YAML
668
-
669
- \`\`\`yaml
670
- submit.button:
671
- type: 'role' # testid, role, text, label, placeholder, locator, page
672
- value: 'button' # role name, testid value, CSS selector, etc.
673
- name: 'Submit' # accessible name
674
- nth: 0 # element index (0=first, 1=.nth(0), 2=.nth(1))
675
- exact: true # exact name match (avoid "Submit" matching "Submit Form")
676
- scope: 'desktop navigation' # scope to parent landmark
677
- match: 'exact' # exact text match for getByText
678
- \`\`\`
679
-
680
- Locator priority: \`data-testid\` > \`role+name\` > \`label\` > \`text\` > \`CSS\`
681
-
682
- ---
683
-
684
- ## Documentation
685
-
686
- - [Gherkin Dictionary](docs/gherkin-dictionary.md) — full grammar, all 17 patterns, compiler rules
687
- - [Sungen GitHub](https://github.com/sun-asterisk/sungen)
688
- - [Playwright Documentation](https://playwright.dev)
689
- `;
291
+ return this.readTemplate('readme.md');
690
292
  }
691
293
  }
@@ -0,0 +1,189 @@
1
+ # Sungen AI Rules
2
+
3
+ You generate 3 files for sungen — a Gherkin compiler that produces Playwright tests.
4
+ **You do NOT write Playwright code.** You only write `.feature`, `selectors.yaml`, and `test-data.yaml`.
5
+
6
+ ## Complete Example
7
+
8
+ Given a login page, here are the 3 files you generate:
9
+
10
+ **qa/screens/login/features/login.feature**
11
+ ```gherkin
12
+ @auth:admin
13
+ Feature: Login Screen
14
+
15
+ Scenario: Successful login
16
+ Given User is on [login] page
17
+ When User fill [Email] field with {{email}}
18
+ And User fill [Password] field with {{password}}
19
+ And User click [Submit] button
20
+ Then User see [Welcome] heading with {{welcome_text}}
21
+ And User see [Dashboard] link is visible
22
+ ```
23
+
24
+ **qa/screens/login/selectors/login.yaml**
25
+ ```yaml
26
+ login:
27
+ type: 'page'
28
+ value: '/login'
29
+
30
+ email:
31
+ type: 'placeholder'
32
+ value: 'Enter your email'
33
+
34
+ password:
35
+ type: 'placeholder'
36
+ value: 'Enter your password'
37
+
38
+ submit:
39
+ type: 'role'
40
+ value: 'button'
41
+ name: 'Submit'
42
+
43
+ welcome:
44
+ type: 'role'
45
+ value: 'heading'
46
+ name: 'Welcome'
47
+
48
+ dashboard:
49
+ type: 'role'
50
+ value: 'link'
51
+ name: 'Dashboard'
52
+ ```
53
+
54
+ **qa/screens/login/test-data/login.yaml**
55
+ ```yaml
56
+ email: 'admin@example.com'
57
+ password: 'password123'
58
+ welcome_text: 'Welcome back'
59
+ ```
60
+
61
+ ## Key Rules
62
+
63
+ ### YAML key format (CRITICAL)
64
+
65
+ YAML keys = Gherkin `[Reference]` converted to: **lowercase, spaces→dots, no special chars**.
66
+
67
+ | Gherkin | YAML Key |
68
+ |---|---|
69
+ | `[Submit]` | `submit:` |
70
+ | `[Search Content]` | `search.content:` |
71
+ | `[Kudos Detail Modal]` | `kudos.detail.modal:` |
72
+ | `[Page 2]` | `page.2:` |
73
+
74
+ **NEVER use spaces in YAML keys.**
75
+
76
+ ### Gherkin patterns (all 17)
77
+
78
+ ```
79
+ User click [Target] button # click
80
+ User fill [Target] field with {{value}} # fill
81
+ User check [Target] checkbox # check/uncheck
82
+ User select [Target] dropdown with {{value}} # select
83
+ User upload [Target] file with {{filename}} # upload
84
+ User double click [Target] element # double click
85
+ User hover [Target] icon # hover
86
+ User clear [Target] field # clear
87
+ User press Escape key # global key
88
+ User press Enter on [Target] field # key on element
89
+ User is on [target] page # navigate (Given)
90
+ User see [target] page # URL assertion (Then)
91
+ User wait for 3 seconds # wait timeout
92
+ User wait for [Target] dialog is hidden # wait state
93
+ User scroll to [Target] section # scroll
94
+ User switch to [Target] frame # iframe
95
+ User see [Target] heading with {{value}} # visible assertion
96
+ User see [Target] button is disabled # state assertion
97
+ User see [Target] text contains {{partial}} # text contains
98
+ User see [Table] table has row with {{filter}} # table row
99
+ User see [Table] table row with {{f}} has [Col] with {{v}} # table cell
100
+ User click [Edit] in [Table] table row with {{name}} # action in row
101
+ ```
102
+
103
+ States: `hidden`, `visible`, `disabled`, `enabled`, `checked`, `unchecked`, `focused`, `empty`
104
+
105
+ ### Selector types
106
+
107
+ | type | value | name | when to use |
108
+ |---|---|---|---|
109
+ | `role` | `button`, `heading`, `link`, etc. | accessible name | **preferred** for interactive elements |
110
+ | `testid` | `data-testid` value | — | when `data-testid` exists |
111
+ | `placeholder` | placeholder text | — | input fields |
112
+ | `label` | label text | — | labeled inputs |
113
+ | `text` | — | — | static text content |
114
+ | `locator` | CSS selector | — | **last resort** |
115
+ | `page` | relative URL path | — | navigation targets |
116
+ | `upload` | — | — | file upload inputs |
117
+ | `frame` | iframe selector | — | iframe targets |
118
+
119
+ Priority: `testid` > `role+name` > `placeholder` > `label` > `text` > `locator`
120
+
121
+ ### Tags
122
+
123
+ | Tag | Effect |
124
+ |---|---|
125
+ | `@auth:role` | Adds `test.use({ storageState: 'specs/.auth/role.json' })` |
126
+ | `@steps:name` | Define reusable step group |
127
+ | `@extend:name` | Inherit steps from another scenario |
128
+ | `@manual` | Skip in generation |
129
+
130
+ ### Selector options
131
+
132
+ ```yaml
133
+ element.key:
134
+ type: 'role'
135
+ value: 'button'
136
+ name: 'Submit' # accessible name
137
+ nth: 0 # element index (0=first)
138
+ exact: true # exact name match (avoid substring collisions)
139
+ scope: 'navigation' # parent landmark scope
140
+ match: 'exact' # exact text match for getByText
141
+ variant: 'native' # dropdown: 'native' (<select>) or 'custom' (div-based)
142
+ frame: '#iframe-id' # iframe scope
143
+ contenteditable: true # rich text editor
144
+ columns: # table columns
145
+ name: { index: 0, header: 'Name' }
146
+ ```
147
+
148
+ ### Navigation and baseURL
149
+
150
+ Page selectors use **relative paths only**. Playwright prepends `baseURL` from `playwright.config.ts`.
151
+
152
+ ```yaml
153
+ login:
154
+ type: 'page'
155
+ value: '/login' # NOT https://example.com/login
156
+ ```
157
+
158
+ ### Auth
159
+
160
+ - `@auth:admin` on Feature or Scenario → compiler adds `test.use({ storageState: 'specs/.auth/admin.json' })`
161
+ - Auth JSON created by: `sungen makeauth admin` (opens browser for manual login)
162
+ - **Login pages**: no `@auth` tag needed
163
+ - **Authenticated pages**: always add `@auth:role`
164
+
165
+ ## Using Playwright MCP to explore pages
166
+
167
+ When exploring a page to generate test files:
168
+ 1. Read `playwright.config.ts` for `baseURL`
169
+ 2. Use `browser_navigate` to open `baseURL + /path`
170
+ 3. Use `browser_snapshot` to see all elements
171
+ 4. Generate the 3 files from the snapshot
172
+
173
+ **NEVER use `browser_run_code`.** It fails with `require is not defined`.
174
+ Only use: `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_fill_form`, `browser_evaluate`.
175
+
176
+ To browse authenticated pages via MCP:
177
+ 1. Read `specs/.auth/role.json` with your file read tool
178
+ 2. `browser_navigate` to the page
179
+ 3. `browser_evaluate` to inject localStorage and cookies from the JSON
180
+ 4. `browser_navigate` again to reload with auth
181
+
182
+ ## Commands
183
+
184
+ ```bash
185
+ sungen add --screen <name> --path <url-path> # Create screen
186
+ sungen generate --screen <name> # Compile to .spec.ts
187
+ sungen generate --all # Compile all
188
+ sungen makeauth <role> # Capture auth state
189
+ ```
@@ -0,0 +1,16 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Build output
5
+ dist/
6
+ build/
7
+
8
+ # Environment variables
9
+ .env
10
+ .env.local
11
+
12
+ # IDE
13
+ .vscode/
14
+ .idea/
15
+ *.swp
16
+ *.swo