@futdevpro/dynamo-e2e 1.18.24 → 1.18.25
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/CHANGELOG.md +12 -0
- package/README.md +139 -139
- package/build/_modules/generators/_models/form-suite-generate-options.interface.d.ts +6 -0
- package/build/_modules/generators/_models/form-suite-generate-options.interface.d.ts.map +1 -1
- package/build/_modules/generators/_models/form-suite-test-import-options.interface.d.ts +22 -0
- package/build/_modules/generators/_models/form-suite-test-import-options.interface.d.ts.map +1 -0
- package/build/_modules/generators/_models/form-suite-test-import-options.interface.js +3 -0
- package/build/_modules/generators/_models/form-suite-test-import-options.interface.js.map +1 -0
- package/build/_modules/generators/_models/index.d.ts +1 -0
- package/build/_modules/generators/_models/index.d.ts.map +1 -1
- package/build/_modules/generators/_models/index.js +1 -0
- package/build/_modules/generators/_models/index.js.map +1 -1
- package/build/_modules/generators/form-suite.generator.d.ts +20 -0
- package/build/_modules/generators/form-suite.generator.d.ts.map +1 -1
- package/build/_modules/generators/form-suite.generator.js +44 -10
- package/build/_modules/generators/form-suite.generator.js.map +1 -1
- package/build/_modules/runtime/_collections/notification-detector-page-script.const.js +136 -136
- package/build/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
Minden release a `dynamo-e2e-foundation` HYPERPLAN MP-N ütemezést követi.
|
|
4
4
|
Verzióformátum: `MM.mm.p` (két-számjegyes major-minor, Dynamo-konvenció).
|
|
5
5
|
|
|
6
|
+
## [01.18.25] — 2026-09-29 — Form suite: a failed setup names the status + URL; configurable `test` import (BFR-ADVENTOR-038)
|
|
7
|
+
|
|
8
|
+
- Every generated setup hook's load check now carries the route, the HTTP status and the final URL in its failure
|
|
9
|
+
message (`form-route '/login' → HTTP 504 https://…`) instead of a bare `toBeTruthy`. Adventor's `e2e-feature` failed
|
|
10
|
+
87 / 88 on one generated case and the cause (gateway 504? 502? real error?) could not be recovered.
|
|
11
|
+
- The legacy `expect(response?.ok()).toBeTruthy();` line stays byte-identical after it (consumer post-processing anchors
|
|
12
|
+
on it — master-prompter's `gen-feature-suites.js`). The route is string-escaped in the `goto` too (a quote used to break
|
|
13
|
+
the generated file; an ordinary route is unchanged).
|
|
14
|
+
- Added `testImport?: { from, name? }` to `emit()`: the spec imports the project's own `test` (a `test.extend` layer,
|
|
15
|
+
e.g. a gateway-504 retry) while `expect` / `Locator` / `Page` stay on `@playwright/test`. Without it: unchanged output.
|
|
16
|
+
- Tests: 12 specs (the emitted load lines executed + every spec TS-parsed); mutations 6/6 killed; suite 548/0.
|
|
17
|
+
|
|
6
18
|
## [01.18.24] — 2026-09-26 — Confirm fields: `matchField` (BFR-ADVENTOR-035)
|
|
7
19
|
|
|
8
20
|
- Added `matchField` to the field settings: a CONFIRM field (e.g. `passwordAgain` → `password`). Every case first fills
|
package/README.md
CHANGED
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
# @futdevpro/dynamo-e2e
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@futdevpro/dynamo-e2e)
|
|
4
|
-
[](./coverage/)
|
|
5
|
-
[](./src/)
|
|
6
|
-
[](./__documentations/plans/dynamo-e2e-foundation/HYPERPLAN.md)
|
|
7
|
-
|
|
8
|
-
End-to-end testing engine for the Dynamo + FDP ecosystem.
|
|
9
|
-
|
|
10
|
-
## What
|
|
11
|
-
|
|
12
|
-
A Dynamo bedrock-package that turns Forms v2 Settings POJOs into Playwright
|
|
13
|
-
test suites — **auto-generated**, **typed**, **overridable**, **diffable**.
|
|
14
|
-
|
|
15
|
-
Three layers in one package:
|
|
16
|
-
|
|
17
|
-
1. **Form-coverage** — every field-type has a pre-curated positive + negative
|
|
18
|
-
input matrix; the generator emits ~20-50 tests per form from a single
|
|
19
|
-
Settings POJO.
|
|
20
|
-
2. **Viewport matrix** *(Wave-2)* — auto-fan-out tests over 7 standard
|
|
21
|
-
viewports + overflow/touch-target a11y detection.
|
|
22
|
-
3. **Core Web Vitals diagnostics** *(Wave-3)* — synthetic LCP / CLS / INP /
|
|
23
|
-
TTFB measurement + percentile aggregation + attribution.
|
|
24
|
-
|
|
25
|
-
## Status
|
|
26
|
-
|
|
27
|
-
**Wave-1..4 + MP-10/MP-11** (2026-06-10) — Layer A contracts, Layer B
|
|
28
|
-
generators (form-suite + viewport-suite + CWV-suite), Layer C runtime
|
|
29
|
-
fixtures + page-objects, Overseer CICD pipeline registered, **75%+ test
|
|
30
|
-
coverage gate** active (statements **97.84%**, branches **87.13%**,
|
|
31
|
-
functions **98.55%**, lines **97.84%**). 104 specs, 0 failures.
|
|
32
|
-
|
|
33
|
-
Plan-net: `__documentations/plans/dynamo-e2e-foundation/HYPERPLAN.md`
|
|
34
|
-
(11 MPs, 4900+ LOC planning).
|
|
35
|
-
|
|
36
|
-
## Install
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
pnpm add -D @futdevpro/dynamo-e2e @playwright/test
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
`@futdevpro/fsm-dynamo` is a peer-dep — bring your own (or no Settings
|
|
43
|
-
POJO source if you only use the runtime presets).
|
|
44
|
-
|
|
45
|
-
## Quick start
|
|
46
|
-
|
|
47
|
-
```typescript
|
|
48
|
-
import { DyFM_TextFieldNew_Settings } from '@futdevpro/fsm-dynamo/ngx-models';
|
|
49
|
-
import { DyE2E_FormSuite_Generator } from '@futdevpro/dynamo-e2e/generators';
|
|
50
|
-
|
|
51
|
-
const settings = new DyFM_FormNew_Settings({
|
|
52
|
-
key: 'login',
|
|
53
|
-
fields: [
|
|
54
|
-
new DyFM_TextFieldNew_Settings({ key: 'email', /* ... */ }),
|
|
55
|
-
],
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const specSource = DyE2E_FormSuite_Generator.emit({
|
|
59
|
-
formSettings: settings,
|
|
60
|
-
formRoute: '/login',
|
|
61
|
-
formSelector: 'dynamo-form-new',
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// → write specSource to `e2e/tests/generated/login-form.spec.ts`
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Sub-exports
|
|
68
|
-
|
|
69
|
-
- `@futdevpro/dynamo-e2e/contracts` — POJO types
|
|
70
|
-
- `@futdevpro/dynamo-e2e/generators` — Node-only emission engine
|
|
71
|
-
- `@futdevpro/dynamo-e2e/runtime` — Playwright fixtures + page-objects (Wave-4) + the live notification detector
|
|
72
|
-
(`DyE2E_NotificationDetector_Util`, see below)
|
|
73
|
-
- `@futdevpro/dynamo-e2e/presets` — pre-built suites + `DyE2E_getPlaywrightConfig` / `DyE2E_getGlobalSetup` playwright-config factory (fleet e2e-config SSOT)
|
|
74
|
-
- `@futdevpro/dynamo-e2e/game` — capability-gated deterministic game seam, failure artifacts and bidirectional journey-catalog validation
|
|
75
|
-
- `@futdevpro/dynamo-e2e/cwv` — Core Web Vitals (Wave-3)
|
|
76
|
-
|
|
77
|
-
## Playwright preset — CI timeouts and the failure budget
|
|
78
|
-
|
|
79
|
-
```ts
|
|
80
|
-
import { DyE2E_getPlaywrightConfig, DyE2E_ciTimeout } from '@futdevpro/dynamo-e2e/presets';
|
|
81
|
-
|
|
82
|
-
export default DyE2E_getPlaywrightConfig({
|
|
83
|
-
defaultBaseUrl: 'https://test.example.hu',
|
|
84
|
-
ciTimeoutFactor: 3, // CI only: timeout / expectTimeout / actionTimeout / navigationTimeout × 3 (default 1)
|
|
85
|
-
maxFailuresInCi: 1, // CI only: stop after the first failure (default: unset = unchanged)
|
|
86
|
-
});
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
> ⚠️ **A call-site `{ timeout }` overrides the config.** `expect(x).toBeVisible({ timeout: 15_000 })` ignores the preset's
|
|
90
|
-
> `expect.timeout` (and its `ciTimeoutFactor`). Scale those values with `DyE2E_ciTimeout(15_000)` — unchanged locally,
|
|
91
|
-
> × `E2E_CI_TIMEOUT_FACTOR` (or 3) under `CI`. Measured: a shared CI runner was 2.3–4.7× slower than a local machine,
|
|
92
|
-
> and a smoke suite with hard-coded call-site timeouts stayed red for months while its config "looked right".
|
|
93
|
-
|
|
94
|
-
## Live notification detector (`/runtime`)
|
|
95
|
-
|
|
96
|
-
Records every user-visible notification — DyNX `dynamo-notification-card` / `dynamo-notifications-area`, mat-snackbar
|
|
97
|
-
(`red-` / `yellow-` / `blue-` / `green-snackbar`), `[role=alert]` — at the moment it APPEARS, so a toast that
|
|
98
|
-
auto-dismissed before the end of the test is still in the report. It also snapshots the visible error banners (with a
|
|
99
|
-
`rawTechnicalLeak` flag for texts like `Http failure response`, `/api/`, `[object Object]`) and collects the page's
|
|
100
|
-
`console` errors/warnings and uncaught `pageerror`s.
|
|
101
|
-
|
|
102
|
-
```ts
|
|
103
|
-
import { DyE2E_NotificationDetector_Util } from '@futdevpro/dynamo-e2e/runtime';
|
|
104
|
-
|
|
105
|
-
await DyE2E_NotificationDetector_Util.attach(context); // before the first navigation
|
|
106
|
-
// ... the flow ...
|
|
107
|
-
const report = await DyE2E_NotificationDetector_Util.collect(page);
|
|
108
|
-
expect(report.notifications.filter((n) => n.type === 'error')).toEqual([]);
|
|
109
|
-
console.log(DyE2E_NotificationDetector_Util.summarize(report, 'login'));
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Captures survive a full-page navigation (they are reported to Node through a Playwright binding). The page-side code
|
|
113
|
-
is plain JavaScript, so no `__name` shim is needed under `tsx` / esbuild. `collect()` throws on a context without
|
|
114
|
-
`attach()` — an empty report would otherwise read as "no notifications".
|
|
115
|
-
|
|
116
|
-
## Login-flow notification sweep (`/runtime` + CLI)
|
|
117
|
-
|
|
118
|
-
Built on the detector: opens the login page of many projects, submits it with a WRONG password (so the ERROR branch
|
|
119
|
-
is measured without a test account) and prints one matrix row per project — notifications · error/warning · banners ·
|
|
120
|
-
modal dialogs · raw-technical leaks · console errors. Framework-level defects show up only when many projects are
|
|
121
|
-
measured the same way.
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
dye2e notification-sweep --targets TEST-TARGETS.md --json sweep.json # or a JSON [{ key, loginUrl | baseUrl }]
|
|
125
|
-
dye2e notification-sweep --targets targets.json --only a,b --fail-on-leak # exit 1 on a raw technical leak
|
|
126
|
-
```
|
|
127
|
-
```ts
|
|
128
|
-
const outcomes = await DyE2E_NotificationSweep_Util.sweep(browser, targets, { settleMs: 5000 });
|
|
129
|
-
console.log(DyE2E_NotificationSweep_Util.matrix(outcomes.map((o) => o.row)));
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Guards in code, not in docs: the probe address must be on a reserved domain (`example.com`, `*.test`, `*.invalid` …)
|
|
133
|
-
or on one you declare with `ownDomains` — anything else throws before a page is opened; the form is submitted only on
|
|
134
|
-
a test host (`test.*`, `*.test`, `localhost` …, or `allowSubmitHosts`) — anything else is loaded but NOT submitted,
|
|
135
|
-
and the row says so. `real: true` / `--real` uses `E2E_PERSISTENT_USER_EMAIL` / `_PASSWORD`; without them the row says
|
|
136
|
-
it fell back to the probe. Modal dialogs (a "not the production system" notice, an error dialog) are RECORDED —
|
|
137
|
-
text + leak flag — before they are closed; a non-modal cookie bar is left alone.
|
|
138
|
-
|
|
139
|
-
Detailed game-preset contract: [`__documentations/game-preset.md`](__documentations/game-preset.md).
|
|
1
|
+
# @futdevpro/dynamo-e2e
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@futdevpro/dynamo-e2e)
|
|
4
|
+
[](./coverage/)
|
|
5
|
+
[](./src/)
|
|
6
|
+
[](./__documentations/plans/dynamo-e2e-foundation/HYPERPLAN.md)
|
|
7
|
+
|
|
8
|
+
End-to-end testing engine for the Dynamo + FDP ecosystem.
|
|
9
|
+
|
|
10
|
+
## What
|
|
11
|
+
|
|
12
|
+
A Dynamo bedrock-package that turns Forms v2 Settings POJOs into Playwright
|
|
13
|
+
test suites — **auto-generated**, **typed**, **overridable**, **diffable**.
|
|
14
|
+
|
|
15
|
+
Three layers in one package:
|
|
16
|
+
|
|
17
|
+
1. **Form-coverage** — every field-type has a pre-curated positive + negative
|
|
18
|
+
input matrix; the generator emits ~20-50 tests per form from a single
|
|
19
|
+
Settings POJO.
|
|
20
|
+
2. **Viewport matrix** *(Wave-2)* — auto-fan-out tests over 7 standard
|
|
21
|
+
viewports + overflow/touch-target a11y detection.
|
|
22
|
+
3. **Core Web Vitals diagnostics** *(Wave-3)* — synthetic LCP / CLS / INP /
|
|
23
|
+
TTFB measurement + percentile aggregation + attribution.
|
|
24
|
+
|
|
25
|
+
## Status
|
|
26
|
+
|
|
27
|
+
**Wave-1..4 + MP-10/MP-11** (2026-06-10) — Layer A contracts, Layer B
|
|
28
|
+
generators (form-suite + viewport-suite + CWV-suite), Layer C runtime
|
|
29
|
+
fixtures + page-objects, Overseer CICD pipeline registered, **75%+ test
|
|
30
|
+
coverage gate** active (statements **97.84%**, branches **87.13%**,
|
|
31
|
+
functions **98.55%**, lines **97.84%**). 104 specs, 0 failures.
|
|
32
|
+
|
|
33
|
+
Plan-net: `__documentations/plans/dynamo-e2e-foundation/HYPERPLAN.md`
|
|
34
|
+
(11 MPs, 4900+ LOC planning).
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pnpm add -D @futdevpro/dynamo-e2e @playwright/test
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`@futdevpro/fsm-dynamo` is a peer-dep — bring your own (or no Settings
|
|
43
|
+
POJO source if you only use the runtime presets).
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { DyFM_TextFieldNew_Settings } from '@futdevpro/fsm-dynamo/ngx-models';
|
|
49
|
+
import { DyE2E_FormSuite_Generator } from '@futdevpro/dynamo-e2e/generators';
|
|
50
|
+
|
|
51
|
+
const settings = new DyFM_FormNew_Settings({
|
|
52
|
+
key: 'login',
|
|
53
|
+
fields: [
|
|
54
|
+
new DyFM_TextFieldNew_Settings({ key: 'email', /* ... */ }),
|
|
55
|
+
],
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const specSource = DyE2E_FormSuite_Generator.emit({
|
|
59
|
+
formSettings: settings,
|
|
60
|
+
formRoute: '/login',
|
|
61
|
+
formSelector: 'dynamo-form-new',
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// → write specSource to `e2e/tests/generated/login-form.spec.ts`
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Sub-exports
|
|
68
|
+
|
|
69
|
+
- `@futdevpro/dynamo-e2e/contracts` — POJO types
|
|
70
|
+
- `@futdevpro/dynamo-e2e/generators` — Node-only emission engine
|
|
71
|
+
- `@futdevpro/dynamo-e2e/runtime` — Playwright fixtures + page-objects (Wave-4) + the live notification detector
|
|
72
|
+
(`DyE2E_NotificationDetector_Util`, see below)
|
|
73
|
+
- `@futdevpro/dynamo-e2e/presets` — pre-built suites + `DyE2E_getPlaywrightConfig` / `DyE2E_getGlobalSetup` playwright-config factory (fleet e2e-config SSOT)
|
|
74
|
+
- `@futdevpro/dynamo-e2e/game` — capability-gated deterministic game seam, failure artifacts and bidirectional journey-catalog validation
|
|
75
|
+
- `@futdevpro/dynamo-e2e/cwv` — Core Web Vitals (Wave-3)
|
|
76
|
+
|
|
77
|
+
## Playwright preset — CI timeouts and the failure budget
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { DyE2E_getPlaywrightConfig, DyE2E_ciTimeout } from '@futdevpro/dynamo-e2e/presets';
|
|
81
|
+
|
|
82
|
+
export default DyE2E_getPlaywrightConfig({
|
|
83
|
+
defaultBaseUrl: 'https://test.example.hu',
|
|
84
|
+
ciTimeoutFactor: 3, // CI only: timeout / expectTimeout / actionTimeout / navigationTimeout × 3 (default 1)
|
|
85
|
+
maxFailuresInCi: 1, // CI only: stop after the first failure (default: unset = unchanged)
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
> ⚠️ **A call-site `{ timeout }` overrides the config.** `expect(x).toBeVisible({ timeout: 15_000 })` ignores the preset's
|
|
90
|
+
> `expect.timeout` (and its `ciTimeoutFactor`). Scale those values with `DyE2E_ciTimeout(15_000)` — unchanged locally,
|
|
91
|
+
> × `E2E_CI_TIMEOUT_FACTOR` (or 3) under `CI`. Measured: a shared CI runner was 2.3–4.7× slower than a local machine,
|
|
92
|
+
> and a smoke suite with hard-coded call-site timeouts stayed red for months while its config "looked right".
|
|
93
|
+
|
|
94
|
+
## Live notification detector (`/runtime`)
|
|
95
|
+
|
|
96
|
+
Records every user-visible notification — DyNX `dynamo-notification-card` / `dynamo-notifications-area`, mat-snackbar
|
|
97
|
+
(`red-` / `yellow-` / `blue-` / `green-snackbar`), `[role=alert]` — at the moment it APPEARS, so a toast that
|
|
98
|
+
auto-dismissed before the end of the test is still in the report. It also snapshots the visible error banners (with a
|
|
99
|
+
`rawTechnicalLeak` flag for texts like `Http failure response`, `/api/`, `[object Object]`) and collects the page's
|
|
100
|
+
`console` errors/warnings and uncaught `pageerror`s.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { DyE2E_NotificationDetector_Util } from '@futdevpro/dynamo-e2e/runtime';
|
|
104
|
+
|
|
105
|
+
await DyE2E_NotificationDetector_Util.attach(context); // before the first navigation
|
|
106
|
+
// ... the flow ...
|
|
107
|
+
const report = await DyE2E_NotificationDetector_Util.collect(page);
|
|
108
|
+
expect(report.notifications.filter((n) => n.type === 'error')).toEqual([]);
|
|
109
|
+
console.log(DyE2E_NotificationDetector_Util.summarize(report, 'login'));
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Captures survive a full-page navigation (they are reported to Node through a Playwright binding). The page-side code
|
|
113
|
+
is plain JavaScript, so no `__name` shim is needed under `tsx` / esbuild. `collect()` throws on a context without
|
|
114
|
+
`attach()` — an empty report would otherwise read as "no notifications".
|
|
115
|
+
|
|
116
|
+
## Login-flow notification sweep (`/runtime` + CLI)
|
|
117
|
+
|
|
118
|
+
Built on the detector: opens the login page of many projects, submits it with a WRONG password (so the ERROR branch
|
|
119
|
+
is measured without a test account) and prints one matrix row per project — notifications · error/warning · banners ·
|
|
120
|
+
modal dialogs · raw-technical leaks · console errors. Framework-level defects show up only when many projects are
|
|
121
|
+
measured the same way.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
dye2e notification-sweep --targets TEST-TARGETS.md --json sweep.json # or a JSON [{ key, loginUrl | baseUrl }]
|
|
125
|
+
dye2e notification-sweep --targets targets.json --only a,b --fail-on-leak # exit 1 on a raw technical leak
|
|
126
|
+
```
|
|
127
|
+
```ts
|
|
128
|
+
const outcomes = await DyE2E_NotificationSweep_Util.sweep(browser, targets, { settleMs: 5000 });
|
|
129
|
+
console.log(DyE2E_NotificationSweep_Util.matrix(outcomes.map((o) => o.row)));
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Guards in code, not in docs: the probe address must be on a reserved domain (`example.com`, `*.test`, `*.invalid` …)
|
|
133
|
+
or on one you declare with `ownDomains` — anything else throws before a page is opened; the form is submitted only on
|
|
134
|
+
a test host (`test.*`, `*.test`, `localhost` …, or `allowSubmitHosts`) — anything else is loaded but NOT submitted,
|
|
135
|
+
and the row says so. `real: true` / `--real` uses `E2E_PERSISTENT_USER_EMAIL` / `_PASSWORD`; without them the row says
|
|
136
|
+
it fell back to the probe. Modal dialogs (a "not the production system" notice, an error dialog) are RECORDED —
|
|
137
|
+
text + leak flag — before they are closed; a non-modal cookie bar is left alone.
|
|
138
|
+
|
|
139
|
+
Detailed game-preset contract: [`__documentations/game-preset.md`](__documentations/game-preset.md).
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DyE2E_FormTestSuite_Settings } from '../../contracts/_models/interfaces/form-test-suite-settings.interface';
|
|
2
2
|
import { DyE2E_FormSettings_Shape } from './form-settings-shape.interface';
|
|
3
|
+
import { DyE2E_FormSuiteTestImport_Options } from './form-suite-test-import-options.interface';
|
|
3
4
|
/**
|
|
4
5
|
* A `DyE2E_FormSuite_Generator.emit()` input-objektum.
|
|
5
6
|
*
|
|
@@ -38,5 +39,10 @@ export interface DyE2E_FormSuiteGenerate_Options {
|
|
|
38
39
|
* tooling-kód). Üres / hiányzó → a régi viselkedés (közvetlen route-navigáció).
|
|
39
40
|
*/
|
|
40
41
|
openSteps?: string[];
|
|
42
|
+
/**
|
|
43
|
+
* BFR-ADVENTOR-038 — import the project's own `test` (a `test.extend` fixture layer) instead of the plain
|
|
44
|
+
* `@playwright/test` one. Missing → the unchanged `@playwright/test` import.
|
|
45
|
+
*/
|
|
46
|
+
testImport?: DyE2E_FormSuiteTestImport_Options;
|
|
41
47
|
}
|
|
42
48
|
//# sourceMappingURL=form-suite-generate-options.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-suite-generate-options.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/form-suite-generate-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,uEAAuE,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"form-suite-generate-options.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/form-suite-generate-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,uEAAuE,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,iCAAiC,EAAE,MAAM,4CAA4C,CAAC;AAE/F;;;;;;;GAOG;AACH,MAAM,WAAW,+BAA+B;IAC9C,6EAA6E;IAC7E,YAAY,EAAE,wBAAwB,CAAC;IACvC,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,4BAA4B,CAAC;IAC7C,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,iCAAiC,CAAC;CAChD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BFR-ADVENTOR-038 — where the generated form-suite spec takes its `test` from.
|
|
3
|
+
*
|
|
4
|
+
* Lets a project bind its own `test.extend` fixture layer (e.g. a gateway-504 retry layer) to the generated suite
|
|
5
|
+
* instead of the plain `@playwright/test` `test`. `expect` / `Locator` / `Page` keep coming from `@playwright/test`.
|
|
6
|
+
*
|
|
7
|
+
* Sample usage:
|
|
8
|
+
* ```ts
|
|
9
|
+
* DyE2E_FormSuite_Generator.emit({
|
|
10
|
+
* formSettings: loginSettings,
|
|
11
|
+
* formRoute: '/login',
|
|
12
|
+
* testImport: { from: '../_config/e2e-test.fixture' }, // → import { test } from '../_config/e2e-test.fixture';
|
|
13
|
+
* });
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export interface DyE2E_FormSuiteTestImport_Options {
|
|
17
|
+
/** The module specifier, exactly as it should appear in the generated spec (relative to the spec file). */
|
|
18
|
+
from: string;
|
|
19
|
+
/** The exported name of the project's `test` (default: `'test'`). */
|
|
20
|
+
name?: string;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=form-suite-test-import-options.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-suite-test-import-options.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/form-suite-test-import-options.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iCAAiC;IAChD,2GAA2G;IAC3G,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-suite-test-import-options.interface.js","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/form-suite-test-import-options.interface.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './form-settings-shape.interface';
|
|
2
2
|
export * from './form-suite-generate-options.interface';
|
|
3
|
+
export * from './form-suite-test-import-options.interface';
|
|
3
4
|
export * from './route-descriptor.interface';
|
|
4
5
|
export * from './viewport-suite-generate-options.interface';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6CAA6C,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6CAA6C,CAAC"}
|
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./form-settings-shape.interface"), exports);
|
|
18
18
|
__exportStar(require("./form-suite-generate-options.interface"), exports);
|
|
19
|
+
__exportStar(require("./form-suite-test-import-options.interface"), exports);
|
|
19
20
|
__exportStar(require("./route-descriptor.interface"), exports);
|
|
20
21
|
__exportStar(require("./viewport-suite-generate-options.interface"), exports);
|
|
21
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAgD;AAChD,0EAAwD;AACxD,+DAA6C;AAC7C,8EAA4D"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/_modules/generators/_models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAgD;AAChD,0EAAwD;AACxD,6EAA2D;AAC3D,+DAA6C;AAC7C,8EAA4D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DyE2E_FormSuiteGenerate_Options } from './_models/form-suite-generate-options.interface';
|
|
2
|
+
import { DyE2E_FormSuiteTestImport_Options } from './_models/form-suite-test-import-options.interface';
|
|
2
3
|
/**
|
|
3
4
|
* A FŐ GENERATOR. Bemenet: a `formSettings` (duck-typed POJO) + `formRoute` +
|
|
4
5
|
* opcionális `suiteSettings`. Kimenet: emit-elt Playwright `spec.ts` string.
|
|
@@ -25,5 +26,24 @@ export declare class DyE2E_FormSuite_Generator {
|
|
|
25
26
|
*/
|
|
26
27
|
static readonly STATEFUL_FIELD_TYPES: ReadonlySet<string>;
|
|
27
28
|
static emit(options: DyE2E_FormSuiteGenerate_Options): string;
|
|
29
|
+
/**
|
|
30
|
+
* BFR-ADVENTOR-038 — the `page.goto(formRoute)` + load-check lines of a setup hook.
|
|
31
|
+
*
|
|
32
|
+
* The FIRST check carries the HTTP status and the final URL in its message, so a failed setup says WHY
|
|
33
|
+
* (a gateway 504? a restarting container's 502? a real 404?) instead of a bare `toBeTruthy`. The SECOND line is
|
|
34
|
+
* the unchanged legacy ok-assert: it can no longer fail on its own (the first one already asserted the same
|
|
35
|
+
* condition), but it stays byte-identical because consumer post-processing anchors on it
|
|
36
|
+
* (master-prompter `e2e/scripts/gen-feature-suites.js` inserts its overlay-dismiss handlers after it).
|
|
37
|
+
* The route is string-escaped (a quote in it used to break the generated file); an ordinary route is unchanged.
|
|
38
|
+
*/
|
|
39
|
+
static routeLoadLines(formRoute: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* BFR-ADVENTOR-038 — the import line(s) that bring `test` into the generated spec.
|
|
42
|
+
*
|
|
43
|
+
* Default: `test` from `@playwright/test` (unchanged output). With `testImport` the project's own `test`
|
|
44
|
+
* (e.g. a `test.extend` fixture layer) is imported instead — `expect` / `Locator` / `Page` stay on
|
|
45
|
+
* `@playwright/test`. With `sharedPageLoad` the imported test is bound as `playwrightTest` and extended below.
|
|
46
|
+
*/
|
|
47
|
+
static testImportLines(anyShared: boolean, testImport?: DyE2E_FormSuiteTestImport_Options): string[];
|
|
28
48
|
}
|
|
29
49
|
//# sourceMappingURL=form-suite.generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-suite.generator.d.ts","sourceRoot":"","sources":["../../../src/_modules/generators/form-suite.generator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,+BAA+B,EAAE,MAAM,iDAAiD,CAAC;
|
|
1
|
+
{"version":3,"file":"form-suite.generator.d.ts","sourceRoot":"","sources":["../../../src/_modules/generators/form-suite.generator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,+BAA+B,EAAE,MAAM,iDAAiD,CAAC;AAClG,OAAO,EAAE,iCAAiC,EAAE,MAAM,oDAAoD,CAAC;AAEvG;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,yBAAyB;IAEpC,8EAA8E;IAC9E,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAkB;IAExD;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAGtD;IAEH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,+BAA+B,GAAG,MAAM;IA+H7D;;;;;;;;;OASG;IACH,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAShD;;;;;;OAMG;IACH,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,iCAAiC,GAAG,MAAM,EAAE;CAcrG"}
|
|
@@ -36,7 +36,7 @@ class DyE2E_FormSuite_Generator {
|
|
|
36
36
|
'autocomplete', 'file', 'files',
|
|
37
37
|
]);
|
|
38
38
|
static emit(options) {
|
|
39
|
-
const { formSettings, formRoute, formSelector, suiteSettings, headerComment, openSteps } = options;
|
|
39
|
+
const { formSettings, formRoute, formSelector, suiteSettings, headerComment, openSteps, testImport } = options;
|
|
40
40
|
const runMode = suiteSettings?.runMode ?? test_run_mode_type_enum_1.DyE2E_TestRunMode_Type.full;
|
|
41
41
|
// Dialog-open preamble: a goto UTÁN, a selector-wait ELŐTT futó verbatim
|
|
42
42
|
// Playwright-sorok (dialog-mounted formokhoz). Üres → régi route-only viselkedés.
|
|
@@ -48,11 +48,11 @@ class DyE2E_FormSuite_Generator {
|
|
|
48
48
|
const sharesPage = (fieldType) => !!suiteSettings?.sharedPageLoad && !DyE2E_FormSuite_Generator.STATEFUL_FIELD_TYPES.has(fieldType);
|
|
49
49
|
const anyShared = formSettings.fields.some((field) => sharesPage(field.type) && !!(0, field_type_registry_const_1.getTestCaseSet)(field.type));
|
|
50
50
|
const imports = [
|
|
51
|
-
anyShared
|
|
52
|
-
? `import { test as playwrightTest, expect, Locator, Page } from '@playwright/test';`
|
|
53
|
-
: `import { test, expect, Locator } from '@playwright/test';`,
|
|
51
|
+
...DyE2E_FormSuite_Generator.testImportLines(anyShared, testImport),
|
|
54
52
|
...(suiteSettings?.extraImports ?? []),
|
|
55
53
|
];
|
|
54
|
+
// BFR-ADVENTOR-038 — the load lines of every setup hook (one source, three hooks)
|
|
55
|
+
const routeLoad = DyE2E_FormSuite_Generator.routeLoadLines(formRoute);
|
|
56
56
|
const describePrefix = suiteSettings?.describePrefix ?? `Form: ${formSettings.key}`;
|
|
57
57
|
const fieldBlocks = [];
|
|
58
58
|
for (const field of formSettings.fields) {
|
|
@@ -87,8 +87,7 @@ test.beforeAll(async ({ browser }, testInfo): Promise<void> => {
|
|
|
87
87
|
ignoreHTTPSErrors: ignoreHTTPSErrors, extraHTTPHeaders: extraHTTPHeaders,
|
|
88
88
|
})).newPage();
|
|
89
89
|
sharedPage = page;
|
|
90
|
-
|
|
91
|
-
expect(response?.ok()).toBeTruthy();${openStepsBlock}${formWait}
|
|
90
|
+
${routeLoad}${openStepsBlock}${formWait}
|
|
92
91
|
});
|
|
93
92
|
|
|
94
93
|
test.afterAll(async (): Promise<void> => {
|
|
@@ -96,8 +95,7 @@ test.afterAll(async (): Promise<void> => {
|
|
|
96
95
|
sharedPage = undefined;
|
|
97
96
|
});`
|
|
98
97
|
: `test.beforeEach(async ({ page }): Promise<void> => {
|
|
99
|
-
|
|
100
|
-
expect(response?.ok()).toBeTruthy();${openStepsBlock}${formWait}
|
|
98
|
+
${routeLoad}${openStepsBlock}${formWait}
|
|
101
99
|
});`;
|
|
102
100
|
fieldBlocks.push(`test.describe('Field: ${field.key} (${field.type})', (): void => {
|
|
103
101
|
${spec_emission_util_1.DyE2E_SpecEmission_Util.indent(`${loadHook}
|
|
@@ -109,8 +107,7 @@ ${cases}`, 1)}
|
|
|
109
107
|
? ''
|
|
110
108
|
: `\n\ntest.describe('Form-level orchestration', (): void => {
|
|
111
109
|
${spec_emission_util_1.DyE2E_SpecEmission_Util.indent(`test.beforeEach(async ({ page }): Promise<void> => {
|
|
112
|
-
|
|
113
|
-
expect(response?.ok()).toBeTruthy();${openStepsBlock}
|
|
110
|
+
${routeLoad}${openStepsBlock}
|
|
114
111
|
});
|
|
115
112
|
|
|
116
113
|
${form_level_emission_util_1.DyE2E_FormLevelEmission_Util.emitAll(formSettings)}`, 1)}
|
|
@@ -137,6 +134,43 @@ ${fieldBlocks.join('\n\n')}${formLevelBlock}
|
|
|
137
134
|
});
|
|
138
135
|
`;
|
|
139
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* BFR-ADVENTOR-038 — the `page.goto(formRoute)` + load-check lines of a setup hook.
|
|
139
|
+
*
|
|
140
|
+
* The FIRST check carries the HTTP status and the final URL in its message, so a failed setup says WHY
|
|
141
|
+
* (a gateway 504? a restarting container's 502? a real 404?) instead of a bare `toBeTruthy`. The SECOND line is
|
|
142
|
+
* the unchanged legacy ok-assert: it can no longer fail on its own (the first one already asserted the same
|
|
143
|
+
* condition), but it stays byte-identical because consumer post-processing anchors on it
|
|
144
|
+
* (master-prompter `e2e/scripts/gen-feature-suites.js` inserts its overlay-dismiss handlers after it).
|
|
145
|
+
* The route is string-escaped (a quote in it used to break the generated file); an ordinary route is unchanged.
|
|
146
|
+
*/
|
|
147
|
+
static routeLoadLines(formRoute) {
|
|
148
|
+
const route = spec_emission_util_1.DyE2E_SpecEmission_Util.escapeString(formRoute);
|
|
149
|
+
return ` const response = await page.goto('${route}');
|
|
150
|
+
expect(response?.ok(), 'form-route \\'${route}\\' → HTTP ' + (response?.status() ?? 'no response') + ' ' + (response?.url() ?? ''))
|
|
151
|
+
.toBeTruthy();
|
|
152
|
+
expect(response?.ok()).toBeTruthy();`;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* BFR-ADVENTOR-038 — the import line(s) that bring `test` into the generated spec.
|
|
156
|
+
*
|
|
157
|
+
* Default: `test` from `@playwright/test` (unchanged output). With `testImport` the project's own `test`
|
|
158
|
+
* (e.g. a `test.extend` fixture layer) is imported instead — `expect` / `Locator` / `Page` stay on
|
|
159
|
+
* `@playwright/test`. With `sharedPageLoad` the imported test is bound as `playwrightTest` and extended below.
|
|
160
|
+
*/
|
|
161
|
+
static testImportLines(anyShared, testImport) {
|
|
162
|
+
const localName = anyShared ? 'playwrightTest' : 'test';
|
|
163
|
+
const playwrightTypes = anyShared ? 'expect, Locator, Page' : 'expect, Locator';
|
|
164
|
+
if (!testImport) {
|
|
165
|
+
return [`import { test${anyShared ? ' as playwrightTest' : ''}, ${playwrightTypes} } from '@playwright/test';`];
|
|
166
|
+
}
|
|
167
|
+
const exportedName = testImport.name ?? 'test';
|
|
168
|
+
const binding = exportedName === localName ? exportedName : `${exportedName} as ${localName}`;
|
|
169
|
+
return [
|
|
170
|
+
`import { ${playwrightTypes} } from '@playwright/test';`,
|
|
171
|
+
`import { ${binding} } from '${spec_emission_util_1.DyE2E_SpecEmission_Util.escapeString(testImport.from)}';`,
|
|
172
|
+
];
|
|
173
|
+
}
|
|
140
174
|
}
|
|
141
175
|
exports.DyE2E_FormSuite_Generator = DyE2E_FormSuite_Generator;
|
|
142
176
|
//# sourceMappingURL=form-suite.generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-suite.generator.js","sourceRoot":"","sources":["../../../src/_modules/generators/form-suite.generator.ts"],"names":[],"mappings":";;;AAAA,yFAAqF;AACrF,kHAAoG;AAEpG,4EAA8E;AAC9E,sFAAuF;AACvF,0EAA4E;AAC5E,gFAAiF;
|
|
1
|
+
{"version":3,"file":"form-suite.generator.js","sourceRoot":"","sources":["../../../src/_modules/generators/form-suite.generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,115 +22,115 @@ exports.DYE2E_NOTIFICATION_BINDING_NAME = '__dye2e_notification_binding__';
|
|
|
22
22
|
* → error · `bg-orange-50` / `yellow-snackbar` / `warning` → warning · `bg-green-50` / `green-snackbar` /
|
|
23
23
|
* `check_circle` → success · `bg-blue-50` / `blue-snackbar` → info.
|
|
24
24
|
*/
|
|
25
|
-
exports.DYE2E_NOTIFICATION_DETECTOR_PAGE_SCRIPT = `
|
|
26
|
-
(function () {
|
|
27
|
-
var w = window;
|
|
28
|
-
if (w.__dye2e_notifications__) { return; }
|
|
29
|
-
var list = [];
|
|
30
|
-
w.__dye2e_notifications__ = list;
|
|
31
|
-
var bindingName = '${exports.DYE2E_NOTIFICATION_BINDING_NAME}';
|
|
32
|
-
var perf = w.performance;
|
|
33
|
-
var origin = String(Math.round(perf && perf.timeOrigin ? perf.timeOrigin : Date.now()));
|
|
34
|
-
var counter = 0;
|
|
35
|
-
var recentKeys = {};
|
|
36
|
-
var recorded = {};
|
|
37
|
-
var checks = [
|
|
38
|
-
['dynx-card', 'dynamo-notification-card'],
|
|
39
|
-
['notif-area', 'dynamo-notifications-area'],
|
|
40
|
-
['snackbar', 'mat-snack-bar-container, .mat-mdc-snack-bar-container, simple-snack-bar, ' +
|
|
41
|
-
'.red-snackbar, .yellow-snackbar, .green-snackbar, .blue-snackbar'],
|
|
42
|
-
['role-alert', '[role="alert"], [role="alertdialog"]']
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
function nowMs() { return perf ? perf.now() : 0; }
|
|
46
|
-
function squash(text) { return (text || '').replace(/\\s+/g, ' ').trim(); }
|
|
47
|
-
function textOf(el, selector) {
|
|
48
|
-
try {
|
|
49
|
-
var node = el.querySelector(selector);
|
|
50
|
-
return node ? squash(node.textContent) : '';
|
|
51
|
-
} catch (e) { return ''; }
|
|
52
|
-
}
|
|
53
|
-
function classify(el) {
|
|
54
|
-
var html = el.outerHTML || '';
|
|
55
|
-
if (/bg-red-50|red-snackbar|>\\s*error\\s*</.test(html)) { return 'error'; }
|
|
56
|
-
if (/bg-orange-50|yellow-snackbar|>\\s*warning\\s*</.test(html)) { return 'warning'; }
|
|
57
|
-
if (/bg-green-50|green-snackbar|>\\s*check_circle\\s*</.test(html)) { return 'success'; }
|
|
58
|
-
if (/bg-blue-50|blue-snackbar/.test(html)) { return 'info'; }
|
|
59
|
-
return 'unknown';
|
|
60
|
-
}
|
|
61
|
-
function read(el) {
|
|
62
|
-
var structured = textOf(el, '.text-slate-700') || textOf(el, '.mat-mdc-snack-bar-label') ||
|
|
63
|
-
textOf(el, '[matsnackbarlabel]');
|
|
64
|
-
return {
|
|
65
|
-
type: classify(el),
|
|
66
|
-
structured: !!structured,
|
|
67
|
-
title: (structured || squash(el.textContent)).slice(0, 400),
|
|
68
|
-
message: textOf(el, '.text-slate-500').slice(0, 400),
|
|
69
|
-
html: squash(el.outerHTML).slice(0, 500)
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function emit(entry) {
|
|
73
|
-
try {
|
|
74
|
-
if (typeof w[bindingName] === 'function') { w[bindingName](entry); }
|
|
75
|
-
} catch (e) { /* the page must never break because of the detector */ }
|
|
76
|
-
}
|
|
77
|
-
function enrich(entry, state, el) {
|
|
78
|
-
if (!el.isConnected) { return; }
|
|
79
|
-
var fresh = read(el);
|
|
80
|
-
var changed = false;
|
|
81
|
-
if (entry.type === 'unknown' && fresh.type !== 'unknown') { entry.type = fresh.type; changed = true; }
|
|
82
|
-
if (fresh.title && fresh.title !== entry.title && (!entry.title || !state.structured)) {
|
|
83
|
-
entry.title = fresh.title; state.structured = fresh.structured; changed = true;
|
|
84
|
-
}
|
|
85
|
-
if (!entry.message && fresh.message) { entry.message = fresh.message; changed = true; }
|
|
86
|
-
if (changed) { entry.html = fresh.html; emit(entry); }
|
|
87
|
-
}
|
|
88
|
-
function record(kind, el) {
|
|
89
|
-
var seen = recorded[kind] || (recorded[kind] = new WeakSet());
|
|
90
|
-
if (seen.has(el)) { return; }
|
|
91
|
-
seen.add(el);
|
|
92
|
-
var data = read(el);
|
|
93
|
-
var t = nowMs();
|
|
94
|
-
var key = kind + '|' + data.type + '|' + data.title;
|
|
95
|
-
if (data.title && recentKeys[key] !== undefined && t - recentKeys[key] < 1500) { return; }
|
|
96
|
-
recentKeys[key] = t;
|
|
97
|
-
counter += 1;
|
|
98
|
-
var entry = {
|
|
99
|
-
id: origin + '-' + counter,
|
|
100
|
-
kind: kind,
|
|
101
|
-
type: data.type,
|
|
102
|
-
title: data.title,
|
|
103
|
-
message: data.message,
|
|
104
|
-
url: location.href,
|
|
105
|
-
at: Date.now(),
|
|
106
|
-
sinceDocumentStartMs: Math.round(t),
|
|
107
|
-
html: data.html
|
|
108
|
-
};
|
|
109
|
-
var state = { structured: data.structured };
|
|
110
|
-
list.push(entry);
|
|
111
|
-
emit(entry);
|
|
112
|
-
setTimeout(function () { enrich(entry, state, el); }, 50);
|
|
113
|
-
setTimeout(function () { enrich(entry, state, el); }, 300);
|
|
114
|
-
}
|
|
115
|
-
function scan(node) {
|
|
116
|
-
if (!node || node.nodeType !== 1) { return; }
|
|
117
|
-
for (var i = 0; i < checks.length; i++) {
|
|
118
|
-
try {
|
|
119
|
-
if (node.matches(checks[i][1])) { record(checks[i][0], node); }
|
|
120
|
-
var found = node.querySelectorAll(checks[i][1]);
|
|
121
|
-
for (var j = 0; j < found.length; j++) { record(checks[i][0], found[j]); }
|
|
122
|
-
} catch (e) { /* one bad selector must not stop the other checks */ }
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
new MutationObserver(function (mutations) {
|
|
127
|
-
for (var i = 0; i < mutations.length; i++) {
|
|
128
|
-
var added = mutations[i].addedNodes;
|
|
129
|
-
for (var j = 0; j < added.length; j++) { scan(added[j]); }
|
|
130
|
-
}
|
|
131
|
-
}).observe(document, { childList: true, subtree: true });
|
|
132
|
-
scan(document.documentElement);
|
|
133
|
-
})();
|
|
25
|
+
exports.DYE2E_NOTIFICATION_DETECTOR_PAGE_SCRIPT = `
|
|
26
|
+
(function () {
|
|
27
|
+
var w = window;
|
|
28
|
+
if (w.__dye2e_notifications__) { return; }
|
|
29
|
+
var list = [];
|
|
30
|
+
w.__dye2e_notifications__ = list;
|
|
31
|
+
var bindingName = '${exports.DYE2E_NOTIFICATION_BINDING_NAME}';
|
|
32
|
+
var perf = w.performance;
|
|
33
|
+
var origin = String(Math.round(perf && perf.timeOrigin ? perf.timeOrigin : Date.now()));
|
|
34
|
+
var counter = 0;
|
|
35
|
+
var recentKeys = {};
|
|
36
|
+
var recorded = {};
|
|
37
|
+
var checks = [
|
|
38
|
+
['dynx-card', 'dynamo-notification-card'],
|
|
39
|
+
['notif-area', 'dynamo-notifications-area'],
|
|
40
|
+
['snackbar', 'mat-snack-bar-container, .mat-mdc-snack-bar-container, simple-snack-bar, ' +
|
|
41
|
+
'.red-snackbar, .yellow-snackbar, .green-snackbar, .blue-snackbar'],
|
|
42
|
+
['role-alert', '[role="alert"], [role="alertdialog"]']
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
function nowMs() { return perf ? perf.now() : 0; }
|
|
46
|
+
function squash(text) { return (text || '').replace(/\\s+/g, ' ').trim(); }
|
|
47
|
+
function textOf(el, selector) {
|
|
48
|
+
try {
|
|
49
|
+
var node = el.querySelector(selector);
|
|
50
|
+
return node ? squash(node.textContent) : '';
|
|
51
|
+
} catch (e) { return ''; }
|
|
52
|
+
}
|
|
53
|
+
function classify(el) {
|
|
54
|
+
var html = el.outerHTML || '';
|
|
55
|
+
if (/bg-red-50|red-snackbar|>\\s*error\\s*</.test(html)) { return 'error'; }
|
|
56
|
+
if (/bg-orange-50|yellow-snackbar|>\\s*warning\\s*</.test(html)) { return 'warning'; }
|
|
57
|
+
if (/bg-green-50|green-snackbar|>\\s*check_circle\\s*</.test(html)) { return 'success'; }
|
|
58
|
+
if (/bg-blue-50|blue-snackbar/.test(html)) { return 'info'; }
|
|
59
|
+
return 'unknown';
|
|
60
|
+
}
|
|
61
|
+
function read(el) {
|
|
62
|
+
var structured = textOf(el, '.text-slate-700') || textOf(el, '.mat-mdc-snack-bar-label') ||
|
|
63
|
+
textOf(el, '[matsnackbarlabel]');
|
|
64
|
+
return {
|
|
65
|
+
type: classify(el),
|
|
66
|
+
structured: !!structured,
|
|
67
|
+
title: (structured || squash(el.textContent)).slice(0, 400),
|
|
68
|
+
message: textOf(el, '.text-slate-500').slice(0, 400),
|
|
69
|
+
html: squash(el.outerHTML).slice(0, 500)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function emit(entry) {
|
|
73
|
+
try {
|
|
74
|
+
if (typeof w[bindingName] === 'function') { w[bindingName](entry); }
|
|
75
|
+
} catch (e) { /* the page must never break because of the detector */ }
|
|
76
|
+
}
|
|
77
|
+
function enrich(entry, state, el) {
|
|
78
|
+
if (!el.isConnected) { return; }
|
|
79
|
+
var fresh = read(el);
|
|
80
|
+
var changed = false;
|
|
81
|
+
if (entry.type === 'unknown' && fresh.type !== 'unknown') { entry.type = fresh.type; changed = true; }
|
|
82
|
+
if (fresh.title && fresh.title !== entry.title && (!entry.title || !state.structured)) {
|
|
83
|
+
entry.title = fresh.title; state.structured = fresh.structured; changed = true;
|
|
84
|
+
}
|
|
85
|
+
if (!entry.message && fresh.message) { entry.message = fresh.message; changed = true; }
|
|
86
|
+
if (changed) { entry.html = fresh.html; emit(entry); }
|
|
87
|
+
}
|
|
88
|
+
function record(kind, el) {
|
|
89
|
+
var seen = recorded[kind] || (recorded[kind] = new WeakSet());
|
|
90
|
+
if (seen.has(el)) { return; }
|
|
91
|
+
seen.add(el);
|
|
92
|
+
var data = read(el);
|
|
93
|
+
var t = nowMs();
|
|
94
|
+
var key = kind + '|' + data.type + '|' + data.title;
|
|
95
|
+
if (data.title && recentKeys[key] !== undefined && t - recentKeys[key] < 1500) { return; }
|
|
96
|
+
recentKeys[key] = t;
|
|
97
|
+
counter += 1;
|
|
98
|
+
var entry = {
|
|
99
|
+
id: origin + '-' + counter,
|
|
100
|
+
kind: kind,
|
|
101
|
+
type: data.type,
|
|
102
|
+
title: data.title,
|
|
103
|
+
message: data.message,
|
|
104
|
+
url: location.href,
|
|
105
|
+
at: Date.now(),
|
|
106
|
+
sinceDocumentStartMs: Math.round(t),
|
|
107
|
+
html: data.html
|
|
108
|
+
};
|
|
109
|
+
var state = { structured: data.structured };
|
|
110
|
+
list.push(entry);
|
|
111
|
+
emit(entry);
|
|
112
|
+
setTimeout(function () { enrich(entry, state, el); }, 50);
|
|
113
|
+
setTimeout(function () { enrich(entry, state, el); }, 300);
|
|
114
|
+
}
|
|
115
|
+
function scan(node) {
|
|
116
|
+
if (!node || node.nodeType !== 1) { return; }
|
|
117
|
+
for (var i = 0; i < checks.length; i++) {
|
|
118
|
+
try {
|
|
119
|
+
if (node.matches(checks[i][1])) { record(checks[i][0], node); }
|
|
120
|
+
var found = node.querySelectorAll(checks[i][1]);
|
|
121
|
+
for (var j = 0; j < found.length; j++) { record(checks[i][0], found[j]); }
|
|
122
|
+
} catch (e) { /* one bad selector must not stop the other checks */ }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
new MutationObserver(function (mutations) {
|
|
127
|
+
for (var i = 0; i < mutations.length; i++) {
|
|
128
|
+
var added = mutations[i].addedNodes;
|
|
129
|
+
for (var j = 0; j < added.length; j++) { scan(added[j]); }
|
|
130
|
+
}
|
|
131
|
+
}).observe(document, { childList: true, subtree: true });
|
|
132
|
+
scan(document.documentElement);
|
|
133
|
+
})();
|
|
134
134
|
`;
|
|
135
135
|
/**
|
|
136
136
|
* Page-side expression: the visible error banners / inline error texts at this moment (not toasts — e.g. a login
|
|
@@ -138,32 +138,32 @@ exports.DYE2E_NOTIFICATION_DETECTOR_PAGE_SCRIPT = `
|
|
|
138
138
|
* already counted banner is part of it, not a new one (measured: a `role=alert` box with its `.error-text` and icon
|
|
139
139
|
* was counted three times). PURE JavaScript.
|
|
140
140
|
*/
|
|
141
|
-
exports.DYE2E_VISIBLE_ERRORS_PAGE_EXPRESSION = `
|
|
142
|
-
(function () {
|
|
143
|
-
var selectors = ['.error-text', '[class*="error-text"]', 'mat-error', '.mat-mdc-form-field-error',
|
|
144
|
-
'.text-red-200', '.text-red-500', '.text-red-600', '.text-red-700', '[role="alert"]'];
|
|
145
|
-
var out = [];
|
|
146
|
-
var seen = {};
|
|
147
|
-
var picked = [];
|
|
148
|
-
var found = document.querySelectorAll(selectors.join(','));
|
|
149
|
-
for (var i = 0; i < found.length; i++) {
|
|
150
|
-
var el = found[i];
|
|
151
|
-
var text = (el.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
152
|
-
if (!text || text.length > 300 || !(el instanceof HTMLElement)) { continue; }
|
|
153
|
-
var rect = el.getBoundingClientRect();
|
|
154
|
-
var style = getComputedStyle(el);
|
|
155
|
-
var visible = el.offsetParent !== null && rect.width > 0 && rect.height > 0 &&
|
|
156
|
-
style.visibility !== 'hidden' && style.display !== 'none';
|
|
157
|
-
var key = el.tagName + '|' + text;
|
|
158
|
-
if (!visible || seen[key]) { continue; }
|
|
159
|
-
var inside = false;
|
|
160
|
-
for (var j = 0; j < picked.length; j++) { if (picked[j].contains(el)) { inside = true; break; } }
|
|
161
|
-
if (inside) { continue; }
|
|
162
|
-
seen[key] = true;
|
|
163
|
-
picked.push(el);
|
|
164
|
-
out.push({ tag: el.tagName.toLowerCase(), cls: String(el.className || '').slice(0, 120), text: text.slice(0, 260) });
|
|
165
|
-
}
|
|
166
|
-
return out;
|
|
167
|
-
})()
|
|
141
|
+
exports.DYE2E_VISIBLE_ERRORS_PAGE_EXPRESSION = `
|
|
142
|
+
(function () {
|
|
143
|
+
var selectors = ['.error-text', '[class*="error-text"]', 'mat-error', '.mat-mdc-form-field-error',
|
|
144
|
+
'.text-red-200', '.text-red-500', '.text-red-600', '.text-red-700', '[role="alert"]'];
|
|
145
|
+
var out = [];
|
|
146
|
+
var seen = {};
|
|
147
|
+
var picked = [];
|
|
148
|
+
var found = document.querySelectorAll(selectors.join(','));
|
|
149
|
+
for (var i = 0; i < found.length; i++) {
|
|
150
|
+
var el = found[i];
|
|
151
|
+
var text = (el.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
152
|
+
if (!text || text.length > 300 || !(el instanceof HTMLElement)) { continue; }
|
|
153
|
+
var rect = el.getBoundingClientRect();
|
|
154
|
+
var style = getComputedStyle(el);
|
|
155
|
+
var visible = el.offsetParent !== null && rect.width > 0 && rect.height > 0 &&
|
|
156
|
+
style.visibility !== 'hidden' && style.display !== 'none';
|
|
157
|
+
var key = el.tagName + '|' + text;
|
|
158
|
+
if (!visible || seen[key]) { continue; }
|
|
159
|
+
var inside = false;
|
|
160
|
+
for (var j = 0; j < picked.length; j++) { if (picked[j].contains(el)) { inside = true; break; } }
|
|
161
|
+
if (inside) { continue; }
|
|
162
|
+
seen[key] = true;
|
|
163
|
+
picked.push(el);
|
|
164
|
+
out.push({ tag: el.tagName.toLowerCase(), cls: String(el.className || '').slice(0, 120), text: text.slice(0, 260) });
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
})()
|
|
168
168
|
`;
|
|
169
169
|
//# sourceMappingURL=notification-detector-page-script.const.js.map
|
package/build/index.js
CHANGED
|
@@ -25,5 +25,5 @@ __exportStar(require("./_modules/vqa/index"), exports);
|
|
|
25
25
|
__exportStar(require("./_modules/game/index"), exports);
|
|
26
26
|
__exportStar(require("./_modules/coverage/index"), exports);
|
|
27
27
|
/** Package-version stamp — npm-publish-time runtime-érték. */
|
|
28
|
-
exports.DYE2E_PACKAGE_VERSION = '01.18.
|
|
28
|
+
exports.DYE2E_PACKAGE_VERSION = '01.18.25';
|
|
29
29
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/dynamo-e2e",
|
|
3
|
-
"version": "01.18.
|
|
3
|
+
"version": "01.18.25",
|
|
4
4
|
"description": "End-to-end testing engine for the Dynamo + FDP ecosystem — auto-generated form-coverage tests, viewport audit matrix, CWV diagnostics. Settings-POJO-first.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "core-package",
|