@futdevpro/dynamo-e2e 1.18.26 → 1.18.30

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 (88) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +10 -0
  3. package/build/_modules/contracts/_collections/test-case-sets/password-field-test-cases.const.d.ts +4 -0
  4. package/build/_modules/contracts/_collections/test-case-sets/password-field-test-cases.const.d.ts.map +1 -1
  5. package/build/_modules/contracts/_collections/test-case-sets/password-field-test-cases.const.js +39 -3
  6. package/build/_modules/contracts/_collections/test-case-sets/password-field-test-cases.const.js.map +1 -1
  7. package/build/_modules/contracts/_enums/field-test-case-type.enum.d.ts +5 -0
  8. package/build/_modules/contracts/_enums/field-test-case-type.enum.d.ts.map +1 -1
  9. package/build/_modules/contracts/_enums/field-test-case-type.enum.js +5 -0
  10. package/build/_modules/contracts/_enums/field-test-case-type.enum.js.map +1 -1
  11. package/build/_modules/contracts/_models/interfaces/form-test-suite-settings.interface.d.ts +9 -1
  12. package/build/_modules/contracts/_models/interfaces/form-test-suite-settings.interface.d.ts.map +1 -1
  13. package/build/_modules/generators/_collections/field-emission.util.d.ts +11 -0
  14. package/build/_modules/generators/_collections/field-emission.util.d.ts.map +1 -1
  15. package/build/_modules/generators/_collections/field-emission.util.js +43 -6
  16. package/build/_modules/generators/_collections/field-emission.util.js.map +1 -1
  17. package/build/_modules/generators/_collections/form-level-emission.util.d.ts.map +1 -1
  18. package/build/_modules/generators/_collections/form-level-emission.util.js +5 -6
  19. package/build/_modules/generators/_collections/form-level-emission.util.js.map +1 -1
  20. package/build/_modules/generators/_collections/json-schema.util.d.ts.map +1 -1
  21. package/build/_modules/generators/_collections/json-schema.util.js +2 -0
  22. package/build/_modules/generators/_collections/json-schema.util.js.map +1 -1
  23. package/build/_modules/generators/_collections/test-case-filter.util.d.ts +6 -0
  24. package/build/_modules/generators/_collections/test-case-filter.util.d.ts.map +1 -1
  25. package/build/_modules/generators/_collections/test-case-filter.util.js +36 -0
  26. package/build/_modules/generators/_collections/test-case-filter.util.js.map +1 -1
  27. package/build/_modules/generators/_models/form-settings-shape.interface.d.ts +13 -0
  28. package/build/_modules/generators/_models/form-settings-shape.interface.d.ts.map +1 -1
  29. package/build/_modules/generators/form-suite.generator.d.ts.map +1 -1
  30. package/build/_modules/generators/form-suite.generator.js +4 -1
  31. package/build/_modules/generators/form-suite.generator.js.map +1 -1
  32. package/build/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.d.ts +6 -0
  33. package/build/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.d.ts.map +1 -0
  34. package/build/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.js +255 -0
  35. package/build/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.js.map +1 -0
  36. package/build/_modules/ui-check/_collections/detectors/dead-control.detector.d.ts +36 -0
  37. package/build/_modules/ui-check/_collections/detectors/dead-control.detector.d.ts.map +1 -0
  38. package/build/_modules/ui-check/_collections/detectors/dead-control.detector.js +133 -0
  39. package/build/_modules/ui-check/_collections/detectors/dead-control.detector.js.map +1 -0
  40. package/build/_modules/ui-check/_collections/detectors/nested-scroll.detector.d.ts +25 -0
  41. package/build/_modules/ui-check/_collections/detectors/nested-scroll.detector.d.ts.map +1 -0
  42. package/build/_modules/ui-check/_collections/detectors/nested-scroll.detector.js +47 -0
  43. package/build/_modules/ui-check/_collections/detectors/nested-scroll.detector.js.map +1 -0
  44. package/build/_modules/ui-check/_collections/detectors/non-toggling-control.detector.d.ts +33 -0
  45. package/build/_modules/ui-check/_collections/detectors/non-toggling-control.detector.d.ts.map +1 -0
  46. package/build/_modules/ui-check/_collections/detectors/non-toggling-control.detector.js +119 -0
  47. package/build/_modules/ui-check/_collections/detectors/non-toggling-control.detector.js.map +1 -0
  48. package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.d.ts +20 -0
  49. package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.d.ts.map +1 -0
  50. package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.js +30 -0
  51. package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.js.map +1 -0
  52. package/build/_modules/ui-check/_collections/ui-check-guard.util.d.ts +60 -0
  53. package/build/_modules/ui-check/_collections/ui-check-guard.util.d.ts.map +1 -0
  54. package/build/_modules/ui-check/_collections/ui-check-guard.util.js +144 -0
  55. package/build/_modules/ui-check/_collections/ui-check-guard.util.js.map +1 -0
  56. package/build/_modules/ui-check/_collections/ui-check-page.util.d.ts +80 -0
  57. package/build/_modules/ui-check/_collections/ui-check-page.util.d.ts.map +1 -0
  58. package/build/_modules/ui-check/_collections/ui-check-page.util.js +195 -0
  59. package/build/_modules/ui-check/_collections/ui-check-page.util.js.map +1 -0
  60. package/build/_modules/ui-check/_collections/ui-check-runner.util.d.ts +41 -0
  61. package/build/_modules/ui-check/_collections/ui-check-runner.util.d.ts.map +1 -0
  62. package/build/_modules/ui-check/_collections/ui-check-runner.util.js +146 -0
  63. package/build/_modules/ui-check/_collections/ui-check-runner.util.js.map +1 -0
  64. package/build/_modules/ui-check/_models/ui-check-context.interface.d.ts +39 -0
  65. package/build/_modules/ui-check/_models/ui-check-context.interface.d.ts.map +1 -0
  66. package/build/_modules/ui-check/_models/ui-check-context.interface.js +3 -0
  67. package/build/_modules/ui-check/_models/ui-check-context.interface.js.map +1 -0
  68. package/build/_modules/ui-check/_models/ui-check-detector.interface.d.ts +32 -0
  69. package/build/_modules/ui-check/_models/ui-check-detector.interface.d.ts.map +1 -0
  70. package/build/_modules/ui-check/_models/ui-check-detector.interface.js +3 -0
  71. package/build/_modules/ui-check/_models/ui-check-detector.interface.js.map +1 -0
  72. package/build/_modules/ui-check/_models/ui-check-finding.interface.d.ts +30 -0
  73. package/build/_modules/ui-check/_models/ui-check-finding.interface.d.ts.map +1 -0
  74. package/build/_modules/ui-check/_models/ui-check-finding.interface.js +3 -0
  75. package/build/_modules/ui-check/_models/ui-check-finding.interface.js.map +1 -0
  76. package/build/_modules/ui-check/_models/ui-check-report.interface.d.ts +38 -0
  77. package/build/_modules/ui-check/_models/ui-check-report.interface.d.ts.map +1 -0
  78. package/build/_modules/ui-check/_models/ui-check-report.interface.js +3 -0
  79. package/build/_modules/ui-check/_models/ui-check-report.interface.js.map +1 -0
  80. package/build/_modules/ui-check/index.d.ts +27 -0
  81. package/build/_modules/ui-check/index.d.ts.map +1 -0
  82. package/build/_modules/ui-check/index.js +43 -0
  83. package/build/_modules/ui-check/index.js.map +1 -0
  84. package/build/index.d.ts +1 -0
  85. package/build/index.d.ts.map +1 -1
  86. package/build/index.js +2 -1
  87. package/build/index.js.map +1 -1
  88. package/package.json +10 -1
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyE2E_NestedScroll_Detector = void 0;
4
+ const ui_check_page_scripts_const_1 = require("../constants/ui-check-page-scripts.const");
5
+ const ui_check_page_util_1 = require("../ui-check-page.util");
6
+ /**
7
+ * Two-level scrolling of the main content: the DOCUMENT scrolls AND an inner container holding the main content
8
+ * (≥ 40 % of the viewport height and width) scrolls too — so part of the page (often the footer) is reachable only
9
+ * with a second scroll. Small inner scrollers (lists, textareas, drop-downs) do not count.
10
+ *
11
+ * Origin: `BL-QA-FDPUI-003` — Master Prompter, logged in: the catalog scrolls inside a `div.flex` (2 196 px), the
12
+ * footer in the outer window (QA-1, round 126, 2026-10-20).
13
+ */
14
+ class DyE2E_NestedScroll_Detector {
15
+ id = 'nested-scroll';
16
+ errorClass = 'two-level-scroll';
17
+ description = 'The document and an inner main-content container scroll at the same time.';
18
+ origin = {
19
+ code: 'BL-QA-FDPUI-003', foundBy: 'QA-1 round 126 (owner example class)', date: '2026-10-20',
20
+ };
21
+ interactive = false;
22
+ /** The inner container counts when it covers at least this share of the viewport height. */
23
+ static minHeightShare = 0.4;
24
+ /** …and at least this share of the viewport width. */
25
+ static minWidthShare = 0.4;
26
+ async run(page, context) {
27
+ const measure = await ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['nestedScroll'], { minHeightShare: DyE2E_NestedScroll_Detector.minHeightShare,
28
+ minWidthShare: DyE2E_NestedScroll_Detector.minWidthShare });
29
+ if (!measure.documentScrolls) {
30
+ return [];
31
+ }
32
+ return measure.inner.map((inner) => ({
33
+ detector: this.id,
34
+ errorClass: this.errorClass,
35
+ url: page.url() || context.url,
36
+ target: { selector: inner.selector, tag: inner.tag, text: inner.className, testId: null, ariaLabel: null },
37
+ measured: `The document scrolls (${measure.documentScrollHeight} px in a ${measure.viewportHeight} px ` +
38
+ `viewport) AND "${inner.selector}" scrolls inside it (${inner.scrollHeight} px in ${inner.clientHeight} px, ` +
39
+ `${inner.visibleHeight} px of it visible).`,
40
+ expected: 'One scroll level for the main content: either the document scrolls, or the inner container fills ' +
41
+ 'the viewport and the document does not.',
42
+ details: { ...measure, inner: inner },
43
+ }));
44
+ }
45
+ }
46
+ exports.DyE2E_NestedScroll_Detector = DyE2E_NestedScroll_Detector;
47
+ //# sourceMappingURL=nested-scroll.detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-scroll.detector.js","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/detectors/nested-scroll.detector.ts"],"names":[],"mappings":";;;AAKA,0FAA0F;AAC1F,8DAA+D;AAY/D;;;;;;;GAOG;AACH,MAAa,2BAA2B;IAE7B,EAAE,GAAW,eAAe,CAAC;IAC7B,UAAU,GAAW,kBAAkB,CAAC;IACxC,WAAW,GAAW,2EAA2E,CAAC;IAClG,MAAM,GAAkC;QAC/C,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,sCAAsC,EAAE,IAAI,EAAE,YAAY;KAC7F,CAAC;IACO,WAAW,GAAY,KAAK,CAAC;IAEtC,4FAA4F;IAC5F,MAAM,CAAU,cAAc,GAAW,GAAG,CAAC;IAE7C,sDAAsD;IACtD,MAAM,CAAU,aAAa,GAAW,GAAG,CAAC;IAE5C,KAAK,CAAC,GAAG,CAAC,IAAU,EAAE,OAAuC;QAC3D,MAAM,OAAO,GAAwC,MAAM,2CAAsB,CAAC,QAAQ,CAAC,IAAI,EAC7F,4DAA8B,CAAC,cAAc,CAAC,EAC9C,EAAE,cAAc,EAAE,2BAA2B,CAAC,cAAc;YAC1D,aAAa,EAAE,2BAA2B,CAAC,aAAa,EAAE,CAAC,CAAC;QAEhE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAA2D,EACpD,EAAE,CAAC,CAAC;YACnC,QAAQ,EAAE,IAAI,CAAC,EAAE;YACjB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,OAAO,CAAC,GAAG;YAC9B,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;YAC1G,QAAQ,EAAE,yBAAyB,OAAO,CAAC,oBAAoB,YAAY,OAAO,CAAC,cAAc,MAAM;gBACrG,kBAAkB,KAAK,CAAC,QAAQ,wBAAwB,KAAK,CAAC,YAAY,UAAU,KAAK,CAAC,YAAY,OAAO;gBAC7G,GAAG,KAAK,CAAC,aAAa,qBAAqB;YAC7C,QAAQ,EAAE,mGAAmG;gBAC3G,yCAAyC;YAC3C,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE;SACtC,CAAC,CAAC,CAAC;IACN,CAAC;;AAvCH,kEAwCC"}
@@ -0,0 +1,33 @@
1
+ import { Page } from '@playwright/test';
2
+ import { DyE2E_UICheckContext_Interface } from '../../_models/ui-check-context.interface';
3
+ import { DyE2E_UICheckDetector_Interface, DyE2E_UICheckOrigin_Interface } from '../../_models/ui-check-detector.interface';
4
+ import { DyE2E_UICheckFinding_Interface } from '../../_models/ui-check-finding.interface';
5
+ /**
6
+ * A checkbox / switch that does not toggle like one: on a fresh page it is pressed, a dialog it opened is closed the
7
+ * user's way (its own accept / close button, else Escape), then it is pressed AGAIN. Each press must flip the state;
8
+ * a press that fails (something covers the control) or does not flip it is a finding.
9
+ *
10
+ * Origin: owner 2026-10-20 (`IN-2026-10-20-HONNIE-10`, `-11`) — the Terms checkbox of the registration could be
11
+ * pressed only after navigating away and back; a generated e2e case had found it on 2026-09-23 and was switched off
12
+ * instead (BFR-FLEET-013).
13
+ */
14
+ export declare class DyE2E_NonTogglingControl_Detector implements DyE2E_UICheckDetector_Interface {
15
+ readonly id: string;
16
+ readonly errorClass: string;
17
+ readonly description: string;
18
+ readonly origin: DyE2E_UICheckOrigin_Interface;
19
+ readonly interactive: boolean;
20
+ notes: string[];
21
+ /** Buttons that close a dialog the user's way. */
22
+ static readonly closeButtonPattern: RegExp;
23
+ run(page: Page, context: DyE2E_UICheckContext_Interface): Promise<DyE2E_UICheckFinding_Interface[]>;
24
+ /** One press: state before, the press, the dialog it opened (closed), state after. */
25
+ private pressOnce;
26
+ /** The visible modal dialogs (their button texts). */
27
+ private dialogs;
28
+ /** Closes the newest dialog with its own accept / close button, else with Escape; returns how. */
29
+ private closeDialog;
30
+ /** The finding of a control whose last step failed. */
31
+ private finding;
32
+ }
33
+ //# sourceMappingURL=non-toggling-control.detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-toggling-control.detector.d.ts","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/detectors/non-toggling-control.detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AAC1F,OAAO,EAAE,+BAA+B,EAAE,6BAA6B,EAAE,MAAM,2CAA2C,CAAC;AAC3H,OAAO,EAAE,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AAc1F;;;;;;;;GAQG;AACH,qBAAa,iCAAkC,YAAW,+BAA+B;IAEvF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAA0B;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAA4B;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAgF;IAC5G,QAAQ,CAAC,MAAM,EAAE,6BAA6B,CAE5C;IACF,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAQ;IACrC,KAAK,EAAE,MAAM,EAAE,CAAM;IAErB,kDAAkD;IAClD,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CACuE;IAE3G,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAoCzG,sFAAsF;YACxE,SAAS;IA8BvB,sDAAsD;YACxC,OAAO;IAIrB,kGAAkG;YACpF,WAAW;IAsBzB,uDAAuD;IACvD,OAAO,CAAC,OAAO;CAuBhB"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyE2E_NonTogglingControl_Detector = void 0;
4
+ const ui_check_page_scripts_const_1 = require("../constants/ui-check-page-scripts.const");
5
+ const ui_check_guard_util_1 = require("../ui-check-guard.util");
6
+ const ui_check_page_util_1 = require("../ui-check-page.util");
7
+ /**
8
+ * A checkbox / switch that does not toggle like one: on a fresh page it is pressed, a dialog it opened is closed the
9
+ * user's way (its own accept / close button, else Escape), then it is pressed AGAIN. Each press must flip the state;
10
+ * a press that fails (something covers the control) or does not flip it is a finding.
11
+ *
12
+ * Origin: owner 2026-10-20 (`IN-2026-10-20-HONNIE-10`, `-11`) — the Terms checkbox of the registration could be
13
+ * pressed only after navigating away and back; a generated e2e case had found it on 2026-09-23 and was switched off
14
+ * instead (BFR-FLEET-013).
15
+ */
16
+ class DyE2E_NonTogglingControl_Detector {
17
+ id = 'non-toggling-control';
18
+ errorClass = 'toggle-does-not-toggle';
19
+ description = 'A checkbox / switch whose press (first or second) does not flip its state.';
20
+ origin = {
21
+ code: 'BFR-FLEET-013', foundBy: 'owner (HONNIE-10 / -11)', date: '2026-10-20',
22
+ };
23
+ interactive = true;
24
+ notes = [];
25
+ /** Buttons that close a dialog the user's way. */
26
+ static closeButtonPattern = /^(accept|i accept|agree|i agree|ok|okay|close|done|got it|understood|elfogad|elfogadom|rendben|bezár|értem)/i;
27
+ async run(page, context) {
28
+ const guard = await ui_check_guard_util_1.DyE2E_UICheckGuard_Util.installNetworkGuard(page, context);
29
+ const findings = [];
30
+ this.notes = [];
31
+ try {
32
+ await ui_check_page_util_1.DyE2E_UICheckPage_Util.reload(page, context);
33
+ const listed = await ui_check_page_util_1.DyE2E_UICheckPage_Util.listControls(page, context, 'toggle');
34
+ for (const control of [...listed.controls, ...listed.denied.filter((c) => !c.destructive)]) {
35
+ await ui_check_page_util_1.DyE2E_UICheckPage_Util.reload(page, context);
36
+ const steps = [];
37
+ for (const press of [1, 2]) {
38
+ const step = await this.pressOnce(page, control.selector, press, context);
39
+ steps.push(step);
40
+ if (context.trace) {
41
+ this.notes.push(`trace "${control.text || control.ariaLabel}" press ${press}: ${step.before} → ` +
42
+ `${step.after}${step.dialog ? ` (${step.dialog})` : ''}${step.pressError ? `, error ${step.pressError}` : ''}`);
43
+ }
44
+ if (step.pressError || step.after === step.before) {
45
+ findings.push(this.finding(control, steps, context));
46
+ break;
47
+ }
48
+ }
49
+ }
50
+ }
51
+ finally {
52
+ await guard.remove();
53
+ }
54
+ return findings;
55
+ }
56
+ /** One press: state before, the press, the dialog it opened (closed), state after. */
57
+ async pressOnce(page, selector, press, context) {
58
+ const before = await ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['toggleState'], selector);
59
+ const dialogsBefore = (await this.dialogs(page)).length;
60
+ let pressError = null;
61
+ let dialog = null;
62
+ try {
63
+ await page.locator(selector).first().click({ timeout: 3_000 });
64
+ }
65
+ catch (error) {
66
+ pressError = ui_check_page_util_1.DyE2E_UICheckPage_Util.describePressError(error);
67
+ }
68
+ await page.waitForTimeout(context.settleMs ?? ui_check_page_util_1.DyE2E_UICheckPage_Util.defaultSettleMs);
69
+ const dialogs = await this.dialogs(page);
70
+ if (!pressError && dialogs.length > dialogsBefore) {
71
+ dialog = await this.closeDialog(page, dialogs[dialogs.length - 1]);
72
+ await page.waitForTimeout(context.settleMs ?? ui_check_page_util_1.DyE2E_UICheckPage_Util.defaultSettleMs);
73
+ }
74
+ const after = await ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['toggleState'], selector);
75
+ return { press: press, before: before, after: after, pressError: pressError, dialog: dialog };
76
+ }
77
+ /** The visible modal dialogs (their button texts). */
78
+ async dialogs(page) {
79
+ return ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['openDialogs']);
80
+ }
81
+ /** Closes the newest dialog with its own accept / close button, else with Escape; returns how. */
82
+ async closeDialog(page, buttons) {
83
+ const label = buttons.find((text) => DyE2E_NonTogglingControl_Detector.closeButtonPattern.test(text));
84
+ if (label) {
85
+ const button = page.locator('[role="dialog"], [role="alertdialog"], mat-dialog-container, ' +
86
+ '.mat-mdc-dialog-container, dialog[open]').last().locator('button, [role="button"], a', { hasText: label })
87
+ .first();
88
+ try {
89
+ await button.click({ timeout: 3_000 });
90
+ return `opened a dialog, closed with its "${label}" button`;
91
+ }
92
+ catch (error) {
93
+ // the dialog's own button cannot be pressed (covered) ⇒ fall back to Escape
94
+ }
95
+ }
96
+ await page.keyboard.press('Escape');
97
+ return `opened a dialog (buttons: ${buttons.join(', ') || 'none'}), closed with Escape`;
98
+ }
99
+ /** The finding of a control whose last step failed. */
100
+ finding(control, steps, context) {
101
+ const last = steps[steps.length - 1];
102
+ const label = control.text || control.ariaLabel || control.testId || control.selector;
103
+ const history = steps.slice(0, -1).map((s) => `press ${s.press}: ${s.before} → ${s.after}${s.dialog ? ` (${s.dialog})` : ''}`).join('; ');
104
+ const what = last.pressError
105
+ ? `press ${last.press} failed: ${last.pressError}`
106
+ : `press ${last.press} left it "${last.after}"${last.dialog ? ` (${last.dialog})` : ''}`;
107
+ return {
108
+ detector: this.id,
109
+ errorClass: this.errorClass,
110
+ url: context.url,
111
+ target: ui_check_page_util_1.DyE2E_UICheckPage_Util.toTarget(control),
112
+ measured: `"${label}": ${history ? history + '; ' : ''}${what}.`,
113
+ expected: 'Every press flips the state (on ⇄ off), also right after a dialog it opened was closed.',
114
+ details: { steps: steps },
115
+ };
116
+ }
117
+ }
118
+ exports.DyE2E_NonTogglingControl_Detector = DyE2E_NonTogglingControl_Detector;
119
+ //# sourceMappingURL=non-toggling-control.detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-toggling-control.detector.js","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/detectors/non-toggling-control.detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { DyE2E_UICheckDetector_Interface } from '../_models/ui-check-detector.interface';
2
+ /**
3
+ * The DEFAULT, growing UI detector list (BFR-FLEET-012) — every page, form and feature gets all of them.
4
+ *
5
+ * Each entry was written for a defect a HUMAN identified, and joined the list only after it caught that real defect AND
6
+ * stayed silent on the fixed version (the proofs: `__documentations/UI-CHECK-DETECTORS.md`). New human-found defect
7
+ * class ⇒ new detector; a project may add its own, and switch one off only with a coded, dated waiver.
8
+ */
9
+ export declare const DyE2E_UICheckDefaultDetectors_Const: readonly DyE2E_UICheckDetector_Interface[];
10
+ /**
11
+ * CANDIDATES — written, tested on minimal fixtures, but their real-defect proof is not complete yet, so they are NOT in
12
+ * the default list. Opt in:
13
+ * `detectors: [ ...DyE2E_UICheckDefaultDetectors_Const, ...DyE2E_UICheckCandidateDetectors_Const ]`.
14
+ * - `nested-scroll`: fires on the real defect (`BL-QA-FDPUI-003`, MP TEST 2026-10-20), the "silent after the fix" half
15
+ * waits for the fix;
16
+ * - `non-toggling-control`: the owner's checkbox defect could not be reproduced on 2026-10-20 (MP + Adventor TEST,
17
+ * desktop + mobile, five close paths) — the exact place is needed from the human who saw it.
18
+ */
19
+ export declare const DyE2E_UICheckCandidateDetectors_Const: readonly DyE2E_UICheckDetector_Interface[];
20
+ //# sourceMappingURL=ui-check-default-detectors.const.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-check-default-detectors.const.d.ts","sourceRoot":"","sources":["../../../../src/_modules/ui-check/_collections/ui-check-default-detectors.const.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,wCAAwC,CAAC;AAKzF;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,EAAE,SAAS,+BAA+B,EAEzF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qCAAqC,EAAE,SAAS,+BAA+B,EAG3F,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyE2E_UICheckCandidateDetectors_Const = exports.DyE2E_UICheckDefaultDetectors_Const = void 0;
4
+ const dead_control_detector_1 = require("./detectors/dead-control.detector");
5
+ const nested_scroll_detector_1 = require("./detectors/nested-scroll.detector");
6
+ const non_toggling_control_detector_1 = require("./detectors/non-toggling-control.detector");
7
+ /**
8
+ * The DEFAULT, growing UI detector list (BFR-FLEET-012) — every page, form and feature gets all of them.
9
+ *
10
+ * Each entry was written for a defect a HUMAN identified, and joined the list only after it caught that real defect AND
11
+ * stayed silent on the fixed version (the proofs: `__documentations/UI-CHECK-DETECTORS.md`). New human-found defect
12
+ * class ⇒ new detector; a project may add its own, and switch one off only with a coded, dated waiver.
13
+ */
14
+ exports.DyE2E_UICheckDefaultDetectors_Const = [
15
+ new dead_control_detector_1.DyE2E_DeadControl_Detector(),
16
+ ];
17
+ /**
18
+ * CANDIDATES — written, tested on minimal fixtures, but their real-defect proof is not complete yet, so they are NOT in
19
+ * the default list. Opt in:
20
+ * `detectors: [ ...DyE2E_UICheckDefaultDetectors_Const, ...DyE2E_UICheckCandidateDetectors_Const ]`.
21
+ * - `nested-scroll`: fires on the real defect (`BL-QA-FDPUI-003`, MP TEST 2026-10-20), the "silent after the fix" half
22
+ * waits for the fix;
23
+ * - `non-toggling-control`: the owner's checkbox defect could not be reproduced on 2026-10-20 (MP + Adventor TEST,
24
+ * desktop + mobile, five close paths) — the exact place is needed from the human who saw it.
25
+ */
26
+ exports.DyE2E_UICheckCandidateDetectors_Const = [
27
+ new nested_scroll_detector_1.DyE2E_NestedScroll_Detector(),
28
+ new non_toggling_control_detector_1.DyE2E_NonTogglingControl_Detector(),
29
+ ];
30
+ //# sourceMappingURL=ui-check-default-detectors.const.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-check-default-detectors.const.js","sourceRoot":"","sources":["../../../../src/_modules/ui-check/_collections/ui-check-default-detectors.const.ts"],"names":[],"mappings":";;;AACA,6EAA+E;AAC/E,+EAAiF;AACjF,6FAA8F;AAE9F;;;;;;GAMG;AACU,QAAA,mCAAmC,GAA+C;IAC7F,IAAI,kDAA0B,EAAE;CACjC,CAAC;AAEF;;;;;;;;GAQG;AACU,QAAA,qCAAqC,GAA+C;IAC/F,IAAI,oDAA2B,EAAE;IACjC,IAAI,iEAAiC,EAAE;CACxC,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { Page, Request } from '@playwright/test';
2
+ import { DyE2E_UICheckContext_Interface } from '../_models/ui-check-context.interface';
3
+ /** What the network guard saw while it was installed. */
4
+ export interface DyE2E_UICheckNetworkLog_Interface {
5
+ /** Requests started (document, xhr, fetch, websocket, eventsource) — an effect of a press. */
6
+ started: number;
7
+ /** Requests the guard aborted — they never reached a server. */
8
+ aborted: string[];
9
+ }
10
+ /** A removable network guard. */
11
+ export interface DyE2E_UICheckNetworkGuard_Interface {
12
+ log: DyE2E_UICheckNetworkLog_Interface;
13
+ /** Zeroes the log (before the next press). */
14
+ reset(): void;
15
+ remove(): Promise<void>;
16
+ }
17
+ /**
18
+ * The safety layer of the interactive UI detectors (BFR-FLEET-012) — the rules are CODE, not advice:
19
+ * 1. a control is pressed only on a test host, anonymously or with a throwaway account;
20
+ * 2. a control whose text / label / test id names payment, e-mail sending, deletion, logout, publishing … is NEVER
21
+ * pressed (`defaultDenyPattern`, plus `data-e2e-destructive`);
22
+ * 3. while a control is pressed, every mutating request (non-GET) is ABORTED — unless it matches `mutationAllow`, and
23
+ * even then a payment / e-mail URL (`hardDenyUrlPattern`) or a non-reserved e-mail address in the body aborts it;
24
+ * every navigation away from the page's host is aborted too;
25
+ * 4. every WebSocket opened while the guard is on is MOCKED: its messages never reach a server (a sent message still
26
+ * counts as an effect) — a socket action (e.g. starting a paid run) cannot slip past the HTTP guard.
27
+ * So a press can never pay, never send a mail to a real address, and never change real data.
28
+ */
29
+ export declare class DyE2E_UICheckGuard_Util {
30
+ /** Controls never pressed: payment, e-mail sending, deletion, logout, publishing (EN + HU). */
31
+ static readonly defaultDenyPattern: RegExp;
32
+ /** Request URLs never let through, even when `mutationAllow` matches: payment and e-mail sending. */
33
+ static readonly hardDenyUrlPattern: RegExp;
34
+ /** Methods that do not change server state. */
35
+ static readonly safeMethods: string[];
36
+ /** Resource types that count as the effect of a press. */
37
+ static readonly effectResourceTypes: string[];
38
+ /** E-mail addresses in a text (request body). */
39
+ private static readonly emailPattern;
40
+ /**
41
+ * Throws (with the reason) unless an interactive detector may run on `context`: a test host and an anonymous or
42
+ * throwaway account. Called by the runner BEFORE the page is touched.
43
+ */
44
+ static assertInteractiveAllowed(context: DyE2E_UICheckContext_Interface, detectorId: string): void;
45
+ /** Whether a control (its text, label, title, test id) is on the deny list. */
46
+ static isDenied(label: string, context: DyE2E_UICheckContext_Interface, destructive: boolean): boolean;
47
+ /** Whether a request may reach the server during a press (see the class doc). */
48
+ static isRequestAllowed(request: Request, context: DyE2E_UICheckContext_Interface): boolean;
49
+ /** Whether every e-mail address in `body` is reserved / undeliverable or on an own domain. */
50
+ static bodyEmailsAllowed(body: string, ownDomains: string[]): boolean;
51
+ /**
52
+ * Installs the network guard on `page` (HTTP route + request counter + WebSocket mock); `remove()` takes them off.
53
+ * Playwright has no `unrouteWebSocket`: after `remove()` NEW sockets connect to the server again, sockets opened
54
+ * while the guard was on stay mocked until the next load.
55
+ */
56
+ static installNetworkGuard(page: Page, context: DyE2E_UICheckContext_Interface): Promise<DyE2E_UICheckNetworkGuard_Interface>;
57
+ /** Whether two URLs share a host. */
58
+ private static sameHost;
59
+ }
60
+ //# sourceMappingURL=ui-check-guard.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-check-guard.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/ui-check/_collections/ui-check-guard.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAyB,MAAM,kBAAkB,CAAC;AAGxE,OAAO,EAAE,8BAA8B,EAAE,MAAM,uCAAuC,CAAC;AAEvF,yDAAyD;AACzD,MAAM,WAAW,iCAAiC;IAChD,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,iCAAiC;AACjC,MAAM,WAAW,mCAAmC;IAClD,GAAG,EAAE,iCAAiC,CAAC;IACvC,8CAA8C;IAC9C,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAuB;IAElC,+FAA+F;IAC/F,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAKxB;IAElB,qGAAqG;IACrG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAGxB;IAElB,+CAA+C;IAC/C,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,CAAgC;IAErE,0DAA0D;IAC1D,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAA8D;IAE3G,iDAAiD;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAqD;IAEzF;;;OAGG;IACH,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,8BAA8B,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAWlG,+EAA+E;IAC/E,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,8BAA8B,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO;IAStG,iFAAiF;IACjF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,8BAA8B,GAAG,OAAO;IAmB3F,8FAA8F;IAC9F,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO;IAMrE;;;;OAIG;WACU,mBAAmB,CAC9B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,mCAAmC,CAAC;IAqD/C,qCAAqC;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ;CAOxB"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyE2E_UICheckGuard_Util = void 0;
4
+ const notification_sweep_util_1 = require("../../runtime/_collections/notification-sweep.util");
5
+ /**
6
+ * The safety layer of the interactive UI detectors (BFR-FLEET-012) — the rules are CODE, not advice:
7
+ * 1. a control is pressed only on a test host, anonymously or with a throwaway account;
8
+ * 2. a control whose text / label / test id names payment, e-mail sending, deletion, logout, publishing … is NEVER
9
+ * pressed (`defaultDenyPattern`, plus `data-e2e-destructive`);
10
+ * 3. while a control is pressed, every mutating request (non-GET) is ABORTED — unless it matches `mutationAllow`, and
11
+ * even then a payment / e-mail URL (`hardDenyUrlPattern`) or a non-reserved e-mail address in the body aborts it;
12
+ * every navigation away from the page's host is aborted too;
13
+ * 4. every WebSocket opened while the guard is on is MOCKED: its messages never reach a server (a sent message still
14
+ * counts as an effect) — a socket action (e.g. starting a paid run) cannot slip past the HTTP guard.
15
+ * So a press can never pay, never send a mail to a real address, and never change real data.
16
+ */
17
+ class DyE2E_UICheckGuard_Util {
18
+ /** Controls never pressed: payment, e-mail sending, deletion, logout, publishing (EN + HU). */
19
+ static defaultDenyPattern = new RegExp([
20
+ '\\blog\\s*-?\\s*out\\b', '\\bsign\\s*-?\\s*out\\b', 'kijelentkez', '\\bdelete\\b', 'törl[éő]', '\\bremove\\b',
21
+ 'eltávolít', '\\bpay', 'fizet', '\\bbuy\\b', 'vásárl', '\\bcheckout\\b', '\\bpurchase', '\\border\\b', 'megrendel',
22
+ '\\bsubscri', 'előfizet', '\\bpublish', 'közzétesz', 'közzététel', '\\bsend\\b', 'küld', '\\binvite', 'meghív',
23
+ 'e-?mail', '\\bdonat', 'adomány', '\\bdeactivat', '\\btransfer\\b', '\\bwithdraw', '\\bcredit', 'kredit',
24
+ ].join('|'), 'i');
25
+ /** Request URLs never let through, even when `mutationAllow` matches: payment and e-mail sending. */
26
+ static hardDenyUrlPattern = new RegExp([
27
+ 'pay', 'checkout', 'purchase', 'order', 'invoice', 'billing', 'simplepay', 'barion', 'stripe', 'paypal', 'credit',
28
+ 'mail', 'invite', 'newsletter', 'notify', 'send',
29
+ ].join('|'), 'i');
30
+ /** Methods that do not change server state. */
31
+ static safeMethods = ['GET', 'HEAD', 'OPTIONS'];
32
+ /** Resource types that count as the effect of a press. */
33
+ static effectResourceTypes = ['document', 'xhr', 'fetch', 'websocket', 'eventsource'];
34
+ /** E-mail addresses in a text (request body). */
35
+ static emailPattern = /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/gi;
36
+ /**
37
+ * Throws (with the reason) unless an interactive detector may run on `context`: a test host and an anonymous or
38
+ * throwaway account. Called by the runner BEFORE the page is touched.
39
+ */
40
+ static assertInteractiveAllowed(context, detectorId) {
41
+ if (!notification_sweep_util_1.DyE2E_NotificationSweep_Util.isSubmitAllowed(context.url, context.allowHosts ?? [])) {
42
+ throw new Error(`UI-check "${detectorId}" refused: "${context.url}" is not a test host (test.*, *.test, ` +
43
+ 'localhost, 127.0.0.1 or allowHosts) — interactive detectors press controls, so they never run elsewhere.');
44
+ }
45
+ if (context.accountKind !== 'anonymous' && context.accountKind !== 'throwaway') {
46
+ throw new Error(`UI-check "${detectorId}" refused: accountKind must be "anonymous" or "throwaway" ` +
47
+ `(got "${String(context.accountKind)}") — a persistent or real account is never used for pressing controls.`);
48
+ }
49
+ }
50
+ /** Whether a control (its text, label, title, test id) is on the deny list. */
51
+ static isDenied(label, context, destructive) {
52
+ if (destructive) {
53
+ return true;
54
+ }
55
+ const patterns = [DyE2E_UICheckGuard_Util.defaultDenyPattern, ...(context.extraDenyPatterns ?? [])];
56
+ return patterns.some((pattern) => pattern.test(label));
57
+ }
58
+ /** Whether a request may reach the server during a press (see the class doc). */
59
+ static isRequestAllowed(request, context) {
60
+ const url = request.url();
61
+ if (request.isNavigationRequest() && !DyE2E_UICheckGuard_Util.sameHost(url, context.url)) {
62
+ return false;
63
+ }
64
+ if (DyE2E_UICheckGuard_Util.safeMethods.includes(request.method().toUpperCase())) {
65
+ return !(request.isNavigationRequest() && DyE2E_UICheckGuard_Util.hardDenyUrlPattern.test(new URL(url).pathname));
66
+ }
67
+ if (!(context.mutationAllow ?? []).some((pattern) => pattern.test(url))) {
68
+ return false;
69
+ }
70
+ if (DyE2E_UICheckGuard_Util.hardDenyUrlPattern.test(url)) {
71
+ return false;
72
+ }
73
+ return DyE2E_UICheckGuard_Util.bodyEmailsAllowed(request.postData() ?? '', context.ownEmailDomains ?? []);
74
+ }
75
+ /** Whether every e-mail address in `body` is reserved / undeliverable or on an own domain. */
76
+ static bodyEmailsAllowed(body, ownDomains) {
77
+ const emails = body.match(DyE2E_UICheckGuard_Util.emailPattern) ?? [];
78
+ return emails.every((email) => notification_sweep_util_1.DyE2E_NotificationSweep_Util.isAllowedProbeEmail(email, ownDomains));
79
+ }
80
+ /**
81
+ * Installs the network guard on `page` (HTTP route + request counter + WebSocket mock); `remove()` takes them off.
82
+ * Playwright has no `unrouteWebSocket`: after `remove()` NEW sockets connect to the server again, sockets opened
83
+ * while the guard was on stay mocked until the next load.
84
+ */
85
+ static async installNetworkGuard(page, context) {
86
+ const log = { started: 0, aborted: [] };
87
+ let active = true;
88
+ const socketHandler = (socket) => {
89
+ if (!active) {
90
+ socket.connectToServer();
91
+ return;
92
+ }
93
+ socket.onMessage(() => {
94
+ log.started++;
95
+ log.aborted.push(`WS message to ${socket.url()} (mocked, never forwarded)`);
96
+ });
97
+ };
98
+ if (typeof page.routeWebSocket !== 'function') {
99
+ throw new Error('UI-check guard refused: this Playwright has no page.routeWebSocket (needs >= 1.48) — without ' +
100
+ 'it a WebSocket action of a pressed control could reach the server.');
101
+ }
102
+ await page.routeWebSocket(/.*/, socketHandler);
103
+ const onRequest = (request) => {
104
+ if (DyE2E_UICheckGuard_Util.effectResourceTypes.includes(request.resourceType())) {
105
+ log.started++;
106
+ }
107
+ };
108
+ const handler = async (route) => {
109
+ const request = route.request();
110
+ if (DyE2E_UICheckGuard_Util.isRequestAllowed(request, context)) {
111
+ await route.fallback();
112
+ }
113
+ else {
114
+ log.aborted.push(`${request.method()} ${request.url()}`);
115
+ await route.abort('blockedbyclient');
116
+ }
117
+ };
118
+ page.on('request', onRequest);
119
+ await page.route('**/*', handler);
120
+ return {
121
+ log: log,
122
+ reset: () => {
123
+ log.started = 0;
124
+ log.aborted = [];
125
+ },
126
+ remove: async () => {
127
+ active = false;
128
+ page.off('request', onRequest);
129
+ await page.unroute('**/*', handler);
130
+ },
131
+ };
132
+ }
133
+ /** Whether two URLs share a host. */
134
+ static sameHost(a, b) {
135
+ try {
136
+ return new URL(a).host === new URL(b).host;
137
+ }
138
+ catch (error) {
139
+ return false;
140
+ }
141
+ }
142
+ }
143
+ exports.DyE2E_UICheckGuard_Util = DyE2E_UICheckGuard_Util;
144
+ //# sourceMappingURL=ui-check-guard.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-check-guard.util.js","sourceRoot":"","sources":["../../../../src/_modules/ui-check/_collections/ui-check-guard.util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { Page } from '@playwright/test';
2
+ import { DyE2E_UICheckContext_Interface } from '../_models/ui-check-context.interface';
3
+ import { DyE2E_UICheckTarget_Interface } from '../_models/ui-check-finding.interface';
4
+ import { DyE2E_UICheckNetworkGuard_Interface } from './ui-check-guard.util';
5
+ /** A control as listed in the page (`listControls`). */
6
+ export interface DyE2E_UICheckControl_Interface extends DyE2E_UICheckTarget_Interface {
7
+ title: string;
8
+ destructive: boolean;
9
+ }
10
+ /** Everything a press caused (or failed to cause). */
11
+ export interface DyE2E_UICheckPressEffect_Interface {
12
+ /** The press itself failed (covered, detached, timed out) — the first line of the error. */
13
+ pressError: string | null;
14
+ urlBefore: string;
15
+ urlAfter: string;
16
+ mutations: number;
17
+ mutationSamples: string[];
18
+ requests: number;
19
+ abortedRequests: string[];
20
+ popups: number;
21
+ downloads: number;
22
+ nativeDialogs: number;
23
+ consoleErrors: string[];
24
+ /** Any effect at all. */
25
+ hadEffect: boolean;
26
+ }
27
+ /** Shared page operations of the UI detectors. */
28
+ export declare class DyE2E_UICheckPage_Util {
29
+ /** Default wait after a press, ms. */
30
+ static readonly defaultSettleMs: number;
31
+ /** Default number of controls pressed per detector and page. */
32
+ static readonly defaultMaxControls: number;
33
+ /** Console errors caused by the network guard's aborts (not by the product). */
34
+ static readonly guardInducedError: RegExp;
35
+ /** Length a reported console error is cut to — AFTER the guard filter (cut first, the filter misses the tail). */
36
+ static readonly maxErrorLength: number;
37
+ /**
38
+ * The browser page itself crashed (renderer out of memory, killed) — the measurement's failure, not a finding.
39
+ * Measured (QA-1 round 128, Adventor `/preset-library`): 2 of 3 long detector runs; the 13 controls pressed one by
40
+ * one WITHOUT the detector did not crash it. After a renderer crash Playwright reports the page as CLOSED on the next
41
+ * call (measured with CDP `Page.crash`), so that text belongs here too.
42
+ */
43
+ static readonly pageCrashError: RegExp;
44
+ /** Whether `error` says that the page crashed. */
45
+ static isPageCrash(error: unknown): boolean;
46
+ /**
47
+ * Whether a console error was caused by the guard's own abort: an abort-type text, or the text names the path of a
48
+ * request the guard aborted. QA-1 round 128 (Adventor "Download my data"): the product logged
49
+ * `DyNX_ApiService call "newPrivacyExportRequest" ERROR: Http failure response for https://…/privacy-request/new/…: 0
50
+ * Unknown Error` — the text was cut to 200 characters BEFORE this check, so "Unknown Error" was lost and the guard's
51
+ * own abort was reported as the product's console error.
52
+ */
53
+ static isGuardInducedError(text: string, aborted: string[]): boolean;
54
+ /** Runs one of `DyE2E_UICheckPageScripts_Const` in the page. */
55
+ static evaluate<T>(page: Page, script: string, arg?: unknown): Promise<T>;
56
+ /**
57
+ * Loads the page under check fresh, waits until it settled, and runs `context.prepare`. The console errors the page
58
+ * logs WITHOUT any press are added to `background` — a press is not blamed for them.
59
+ */
60
+ static reload(page: Page, context: DyE2E_UICheckContext_Interface, background?: Set<string>): Promise<void>;
61
+ /** A console error without its volatile parts (numbers, ids), so a repeating background error matches itself. */
62
+ static errorSignature(text: string): string;
63
+ /** The identity of a control across reloads (its CSS path may shift when an earlier press changed the page). */
64
+ static signature(control: DyE2E_UICheckControl_Interface): string;
65
+ /** The first line of a press error, plus the Playwright call-log line that names the cause (e.g. what covers it). */
66
+ static describePressError(error: unknown): string;
67
+ /** The visible, enabled controls of one kind, minus the denied ones (returned separately). */
68
+ static listControls(page: Page, context: DyE2E_UICheckContext_Interface, kind: 'press' | 'toggle'): Promise<{
69
+ controls: DyE2E_UICheckControl_Interface[];
70
+ denied: DyE2E_UICheckControl_Interface[];
71
+ }>;
72
+ /**
73
+ * Presses `selector` with every effect channel watched: URL, meaningful DOM mutations, requests (started — the
74
+ * guard aborts the mutating ones), popups, downloads, native dialogs, console errors.
75
+ */
76
+ static press(page: Page, selector: string, guard: DyE2E_UICheckNetworkGuard_Interface, context: DyE2E_UICheckContext_Interface, background?: Set<string>): Promise<DyE2E_UICheckPressEffect_Interface>;
77
+ /** The target part of a finding, from a listed control. */
78
+ static toTarget(control: DyE2E_UICheckControl_Interface): DyE2E_UICheckTarget_Interface;
79
+ }
80
+ //# sourceMappingURL=ui-check-page.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-check-page.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/ui-check/_collections/ui-check-page.util.ts"],"names":[],"mappings":"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"}