@sun-asterisk/sungen 2.0.0 → 2.0.2
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/dist/cli/index.js +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +2 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +2 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +2 -2
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +10 -0
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +4 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +8 -0
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +4 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +11 -410
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/templates/ai-rules.md +189 -0
- package/dist/orchestrator/templates/gitignore +16 -0
- package/dist/orchestrator/templates/playwright.config.d.ts +10 -0
- package/dist/orchestrator/templates/playwright.config.d.ts.map +1 -0
- package/dist/orchestrator/templates/playwright.config.js +77 -0
- package/dist/orchestrator/templates/playwright.config.js.map +1 -0
- package/dist/orchestrator/templates/playwright.config.ts +80 -0
- package/dist/orchestrator/templates/readme.md +197 -0
- package/docs/gherkin standards/gherkin-core-standard.md +377 -0
- package/docs/gherkin standards/gherkin-core-standard.vi.md +303 -0
- package/docs/gherkin-dictionary.md +1071 -0
- package/docs/makeauth.md +225 -0
- package/package.json +3 -2
- package/src/cli/index.ts +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +2 -2
- package/src/generators/test-generator/code-generator.ts +11 -0
- package/src/generators/test-generator/step-mapper.ts +9 -0
- package/src/orchestrator/project-initializer.ts +12 -410
- package/src/orchestrator/templates/ai-rules.md +189 -0
- package/src/orchestrator/templates/gitignore +16 -0
- package/src/orchestrator/templates/playwright.config.ts +80 -0
- package/src/orchestrator/templates/readme.md +197 -0
package/docs/makeauth.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# sungen makeauth
|
|
2
|
+
|
|
3
|
+
Generate authentication state for E2E tests with SSO (Single Sign-On) support.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `makeauth` command opens a browser window for manual login (including SSO providers like Google, Facebook, GitHub, etc.) and saves the authentication state to a JSON file. This storage state can then be used in Playwright tests to skip the login process.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
sungen makeauth <name> [options]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Arguments
|
|
16
|
+
|
|
17
|
+
| Argument | Description |
|
|
18
|
+
|----------|-------------|
|
|
19
|
+
| `name` | Name for the auth state (e.g., `admin`, `user`, `guest`) |
|
|
20
|
+
|
|
21
|
+
### Options
|
|
22
|
+
|
|
23
|
+
| Option | Description | Default |
|
|
24
|
+
|--------|-------------|---------|
|
|
25
|
+
| `-u, --url <url>` | Base URL of the application | Auto-detect from `playwright.config.ts` |
|
|
26
|
+
| `-p, --path <path>` | Login page path | `/login` |
|
|
27
|
+
| `-o, --output <dir>` | Output directory for auth files | `specs/.auth` |
|
|
28
|
+
| `-t, --timeout <ms>` | Overall timeout for login process | `180000` (3 minutes) |
|
|
29
|
+
| `--nav-timeout <ms>` | Navigation timeout (page load) | `180000` (3 minutes) |
|
|
30
|
+
| `--stability-wait <ms>` | URL stability wait before confirming login | `5000` (5 seconds) |
|
|
31
|
+
| `--headless` | Run browser in headless mode | `false` |
|
|
32
|
+
| `--verify` | Verify existing auth state is still valid | - |
|
|
33
|
+
| `--list` | List all existing auth states | - |
|
|
34
|
+
| `--export` | Export auth state as base64 (for CI) | - |
|
|
35
|
+
|
|
36
|
+
### Timeout Configuration
|
|
37
|
+
|
|
38
|
+
| Config | Default | Description |
|
|
39
|
+
|--------|---------|-------------|
|
|
40
|
+
| `timeout` | 180000 (3 min) | Overall timeout for the entire login process |
|
|
41
|
+
| `nav-timeout` | 180000 (3 min) | Timeout for page navigation (page.goto) |
|
|
42
|
+
| `stability-wait` | 5000 (5 sec) | Time URL must remain stable before confirming successful login |
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
### Create auth state
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Basic usage - auto-detect URL from playwright.config.ts
|
|
50
|
+
sungen makeauth admin
|
|
51
|
+
|
|
52
|
+
# Specify URL explicitly
|
|
53
|
+
sungen makeauth admin --url https://myapp.com
|
|
54
|
+
|
|
55
|
+
# Custom login path
|
|
56
|
+
sungen makeauth admin --url https://myapp.com --path /auth/signin
|
|
57
|
+
|
|
58
|
+
# Longer timeout for slow SSO providers
|
|
59
|
+
sungen makeauth admin --timeout 300000
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Manage auth states
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# List all auth states
|
|
66
|
+
sungen makeauth admin --list
|
|
67
|
+
|
|
68
|
+
# Verify auth state is still valid
|
|
69
|
+
sungen makeauth admin --verify
|
|
70
|
+
|
|
71
|
+
# Export for CI (base64)
|
|
72
|
+
sungen makeauth admin --export
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## URL Detection Priority
|
|
76
|
+
|
|
77
|
+
The command automatically detects the base URL in this order:
|
|
78
|
+
|
|
79
|
+
1. `--url` flag (if provided)
|
|
80
|
+
2. `playwright.config.ts` - reads `baseURL` from the config
|
|
81
|
+
3. `APP_BASE_URL` environment variable
|
|
82
|
+
4. Default: `http://localhost:3000`
|
|
83
|
+
|
|
84
|
+
## Supported SSO Providers
|
|
85
|
+
|
|
86
|
+
The tool automatically detects and displays the SSO provider being used:
|
|
87
|
+
|
|
88
|
+
| Provider | Detection |
|
|
89
|
+
|----------|-----------|
|
|
90
|
+
| Google | accounts.google.com |
|
|
91
|
+
| Facebook | facebook.com |
|
|
92
|
+
| GitHub | github.com |
|
|
93
|
+
| Microsoft/Azure AD | login.microsoftonline.com |
|
|
94
|
+
| Apple | appleid.apple.com |
|
|
95
|
+
| X (Twitter) | twitter.com, x.com |
|
|
96
|
+
| LinkedIn | linkedin.com |
|
|
97
|
+
| Okta | *.okta.com |
|
|
98
|
+
| Auth0 | *.auth0.com |
|
|
99
|
+
| GitLab | gitlab.com |
|
|
100
|
+
| Atlassian | atlassian.com, bitbucket.org |
|
|
101
|
+
| Slack | slack.com |
|
|
102
|
+
| Discord | discord.com |
|
|
103
|
+
| Amazon Cognito | amazoncognito.com |
|
|
104
|
+
| Yahoo | yahoo.com |
|
|
105
|
+
|
|
106
|
+
Any other SSO provider will show the domain name.
|
|
107
|
+
|
|
108
|
+
## How It Works
|
|
109
|
+
|
|
110
|
+
1. **Open Browser**: Launches Chromium browser and navigates to login page
|
|
111
|
+
2. **Wait for SSO**: Detects when user clicks SSO button (redirect to external domain)
|
|
112
|
+
3. **Wait for Callback**: Monitors for redirect back to application
|
|
113
|
+
4. **Save State**: Stores cookies, localStorage, and sessionStorage to JSON file
|
|
114
|
+
5. **Auto-close**: Browser closes automatically after successful login
|
|
115
|
+
|
|
116
|
+
You can also press **ENTER** at any time to manually save the current state.
|
|
117
|
+
|
|
118
|
+
## Output
|
|
119
|
+
|
|
120
|
+
Auth states are saved to `specs/.auth/<name>.json`:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
specs/
|
|
124
|
+
.auth/
|
|
125
|
+
admin.json
|
|
126
|
+
user.json
|
|
127
|
+
guest.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Using in Playwright Tests
|
|
131
|
+
|
|
132
|
+
### Method 1: Global Setup (Recommended)
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// playwright.config.ts
|
|
136
|
+
import { defineConfig } from '@playwright/test';
|
|
137
|
+
|
|
138
|
+
export default defineConfig({
|
|
139
|
+
projects: [
|
|
140
|
+
{
|
|
141
|
+
name: 'authenticated',
|
|
142
|
+
use: {
|
|
143
|
+
storageState: 'specs/.auth/admin.json',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Method 2: Per-test Setup
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// my-test.spec.ts
|
|
154
|
+
import { test } from '@playwright/test';
|
|
155
|
+
|
|
156
|
+
test.use({ storageState: 'specs/.auth/admin.json' });
|
|
157
|
+
|
|
158
|
+
test('authenticated test', async ({ page }) => {
|
|
159
|
+
await page.goto('/dashboard');
|
|
160
|
+
// Already logged in!
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Method 3: Multiple Roles
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// playwright.config.ts
|
|
168
|
+
export default defineConfig({
|
|
169
|
+
projects: [
|
|
170
|
+
{
|
|
171
|
+
name: 'admin',
|
|
172
|
+
use: { storageState: 'specs/.auth/admin.json' },
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'user',
|
|
176
|
+
use: { storageState: 'specs/.auth/user.json' },
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## CI/CD Integration
|
|
183
|
+
|
|
184
|
+
### Option 1: Pre-generated Auth State
|
|
185
|
+
|
|
186
|
+
1. Generate auth state locally:
|
|
187
|
+
```bash
|
|
188
|
+
sungen makeauth admin
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
2. Export as base64:
|
|
192
|
+
```bash
|
|
193
|
+
sungen makeauth admin --export
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
3. Save to CI secret (e.g., `AUTH_STATE_ADMIN`)
|
|
197
|
+
|
|
198
|
+
4. In CI, decode and save:
|
|
199
|
+
```bash
|
|
200
|
+
echo "$AUTH_STATE_ADMIN" | base64 -d > specs/.auth/admin.json
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Option 2: Service Account
|
|
204
|
+
|
|
205
|
+
For automated CI without SSO:
|
|
206
|
+
1. Create a service account with username/password login
|
|
207
|
+
2. Use Playwright's built-in auth setup
|
|
208
|
+
|
|
209
|
+
## Troubleshooting
|
|
210
|
+
|
|
211
|
+
### Browser closes immediately
|
|
212
|
+
- Make sure to click the SSO button before the browser closes
|
|
213
|
+
- The tool waits for you to leave the base URL domain
|
|
214
|
+
|
|
215
|
+
### Auth state expired
|
|
216
|
+
- Run `sungen makeauth admin --verify` to check
|
|
217
|
+
- Regenerate with `sungen makeauth admin`
|
|
218
|
+
|
|
219
|
+
### Wrong URL detected
|
|
220
|
+
- Check your `playwright.config.ts` has correct `baseURL`
|
|
221
|
+
- Or specify explicitly: `--url https://your-app.com`
|
|
222
|
+
|
|
223
|
+
### Timeout error
|
|
224
|
+
- Increase timeout: `--timeout 300000` (5 minutes)
|
|
225
|
+
- Or press ENTER to save manually at any time
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sungen",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc && npm run copy-templates",
|
|
12
|
-
"copy-templates": "mkdir -p dist/generators/test-generator/adapters/playwright/templates/steps && mkdir -p dist/generators/test-generator/templates && cp -r src/generators/test-generator/adapters/playwright/templates/*.hbs dist/generators/test-generator/adapters/playwright/templates/ 2>/dev/null || true && cp -r src/generators/test-generator/adapters/playwright/templates/steps dist/generators/test-generator/adapters/playwright/templates/ && cp src/generators/test-generator/templates/*.hbs dist/generators/test-generator/templates/ 2>/dev/null || true",
|
|
12
|
+
"copy-templates": "mkdir -p dist/generators/test-generator/adapters/playwright/templates/steps && mkdir -p dist/generators/test-generator/templates && mkdir -p dist/orchestrator/templates && cp -r src/generators/test-generator/adapters/playwright/templates/*.hbs dist/generators/test-generator/adapters/playwright/templates/ 2>/dev/null || true && cp -r src/generators/test-generator/adapters/playwright/templates/steps dist/generators/test-generator/adapters/playwright/templates/ && cp src/generators/test-generator/templates/*.hbs dist/generators/test-generator/templates/ 2>/dev/null || true && cp -r src/orchestrator/templates/* dist/orchestrator/templates/",
|
|
13
13
|
"dev": "tsx src/cli/index.ts",
|
|
14
14
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
15
15
|
"prepublishOnly": "npm run build"
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"dist",
|
|
68
68
|
"bin",
|
|
69
69
|
"src",
|
|
70
|
+
"docs",
|
|
70
71
|
"README.md",
|
|
71
72
|
"LICENSE"
|
|
72
73
|
]
|
package/src/cli/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const tableRow = {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' });
|
|
2
|
-
await tableRow.getByRole('button', { name: '{{escapeQuotes elementName}}' }).{{action}}();
|
|
1
|
+
{ const tableRow = {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' });
|
|
2
|
+
await tableRow.getByRole('button', { name: '{{escapeQuotes elementName}}' }).{{action}}(); }
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
await page.waitForLoadState('networkidle');
|
|
2
|
-
const tableRow = {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' });
|
|
3
|
-
await expect(tableRow.getByRole('cell').filter({ hasText: '{{escapeQuotes cellValue}}' })).toBeVisible();
|
|
2
|
+
{ const tableRow = {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' });
|
|
3
|
+
await expect(tableRow.getByRole('cell').filter({ hasText: '{{escapeQuotes cellValue}}' })).toBeVisible(); }
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
await page.waitForLoadState('networkidle');
|
|
2
|
-
const tableRow = {{> locator}}.getByRole('row').nth({{rowIndex}});
|
|
3
|
-
await expect(tableRow.getByRole('cell').filter({ hasText: '{{escapeQuotes cellValue}}' })).toBeVisible();
|
|
2
|
+
{ const tableRow = {{> locator}}.getByRole('row').nth({{rowIndex}});
|
|
3
|
+
await expect(tableRow.getByRole('cell').filter({ hasText: '{{escapeQuotes cellValue}}' })).toBeVisible(); }
|
|
@@ -190,6 +190,17 @@ export class CodeGenerator {
|
|
|
190
190
|
featureName = this.featureNameToFileName(feature.name).replace('.spec.ts', '');
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
// Derive screen name from source file path when not explicitly set
|
|
194
|
+
// qa/screens/{screenName}/features/{featureName}.feature -> screenName
|
|
195
|
+
if (!this.screenName && feature.sourceFile) {
|
|
196
|
+
const sourceDir = path.dirname(feature.sourceFile);
|
|
197
|
+
const parts = sourceDir.split(path.sep);
|
|
198
|
+
const screensIndex = parts.indexOf('screens');
|
|
199
|
+
if (screensIndex >= 0 && screensIndex < parts.length - 2) {
|
|
200
|
+
this.stepMapper.setScreenContext(parts[screensIndex + 1]);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
193
204
|
// Set feature context for data resolution and navigation
|
|
194
205
|
this.stepMapper.setFeatureContext(featureName, feature.path);
|
|
195
206
|
|
|
@@ -57,6 +57,15 @@ export class StepMapper {
|
|
|
57
57
|
this.selectorResolver.setFeatureContext(featureName);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Update screen context (used in --all mode to set per-feature screen name)
|
|
62
|
+
*/
|
|
63
|
+
setScreenContext(screenName: string): void {
|
|
64
|
+
this.screenName = screenName;
|
|
65
|
+
this.selectorResolver.setScreenContext(screenName);
|
|
66
|
+
this.dataResolver.setScreenContext(screenName);
|
|
67
|
+
}
|
|
68
|
+
|
|
60
69
|
/**
|
|
61
70
|
* Set scenario context for path variable resolution
|
|
62
71
|
*/
|