@futdevpro/dynamo-e2e 1.18.32 → 1.18.33
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 +9 -0
- package/build/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.d.ts.map +1 -1
- package/build/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.js +65 -0
- package/build/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.js.map +1 -1
- package/build/_modules/ui-check/_collections/detectors/scroll-trap.detector.d.ts +41 -0
- package/build/_modules/ui-check/_collections/detectors/scroll-trap.detector.d.ts.map +1 -0
- package/build/_modules/ui-check/_collections/detectors/scroll-trap.detector.js +86 -0
- package/build/_modules/ui-check/_collections/detectors/scroll-trap.detector.js.map +1 -0
- package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.d.ts +4 -0
- package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.d.ts.map +1 -1
- package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.js +6 -0
- package/build/_modules/ui-check/_collections/ui-check-default-detectors.const.js.map +1 -1
- package/build/_modules/ui-check/index.d.ts +1 -0
- package/build/_modules/ui-check/index.d.ts.map +1 -1
- package/build/_modules/ui-check/index.js +1 -0
- package/build/_modules/ui-check/index.js.map +1 -1
- package/build/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
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.33] — 2026-10-28 — `/ui-check` `scroll-trap` candidate (BFR-ORGANIZER-029)
|
|
7
|
+
|
|
8
|
+
- **New candidate detector `scroll-trap`** (BFR-ORGANIZER-029, owner 2026-10-26: "nem lehet scrollozni"): a
|
|
9
|
+
non-scrolling `overflow-y: auto|scroll` + `overscroll-behavior-y: contain|none` element inside a scrolling ancestor
|
|
10
|
+
(or document) — the wheel over it moves nothing. Structural candidates + a wheel test (a finding only where NOTHING
|
|
11
|
+
moved; the scroll positions are restored). Not interactive. Opt in via `DyE2E_UICheckCandidateDetectors_Const`.
|
|
12
|
+
- Specs: +3 real-browser (`/trap-bug` fires; `/trap-fixed`, `/trap-owns-scroll`, `/trap-covered` silent; the frame
|
|
13
|
+
restored), full suite 600/0; mutants: the wheel layer off and the restore off are caught (2/2).
|
|
14
|
+
|
|
6
15
|
## [01.18.32] — 2026-10-24 — `/ui-check` `covered-control` candidate, the current tab is not pressed, CRLF on a single-line field (BFR-ADVENTOR-081, BFR-MASTERPROMPTER-125, -121)
|
|
7
16
|
|
|
8
17
|
- **New candidate detector `covered-control`** (BFR-ADVENTOR-081): a visible, enabled control (links included) whose
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-check-page-scripts.const.d.ts","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"ui-check-page-scripts.const.d.ts","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwY3E,CAAC"}
|
|
@@ -321,5 +321,70 @@ exports.DyE2E_UICheckPageScripts_Const = {
|
|
|
321
321
|
window.scrollTo(startX, startY);
|
|
322
322
|
return { checked: checked, covered: out };
|
|
323
323
|
}`,
|
|
324
|
+
// BFR-ORGANIZER-029 — a scroll container with overscroll containment that does NOT scroll itself, inside a scrolling
|
|
325
|
+
// ancestor (or document): the structural candidates of a scroll trap, with the centre of their visible part.
|
|
326
|
+
scrollTraps: `(arg) => {
|
|
327
|
+
const root = document.scrollingElement || document.documentElement;
|
|
328
|
+
const vh = window.innerHeight;
|
|
329
|
+
const vw = window.innerWidth;
|
|
330
|
+
const cssPath = (el) => {
|
|
331
|
+
const parts = [];
|
|
332
|
+
let node = el;
|
|
333
|
+
while (node && node.nodeType === 1 && node !== document.documentElement) {
|
|
334
|
+
if (node.id && /^[A-Za-z][\\w-]*$/.test(node.id)) { parts.unshift('#' + node.id); break; }
|
|
335
|
+
const tag = node.tagName.toLowerCase();
|
|
336
|
+
const parent = node.parentElement;
|
|
337
|
+
const same = parent ? Array.from(parent.children).filter((c) => c.tagName === node.tagName) : [];
|
|
338
|
+
parts.unshift(same.length > 1 ? tag + ':nth-of-type(' + (same.indexOf(node) + 1) + ')' : tag);
|
|
339
|
+
node = parent;
|
|
340
|
+
}
|
|
341
|
+
return parts.join(' > ');
|
|
342
|
+
};
|
|
343
|
+
const scrolls = (el) => /(auto|scroll|overlay)/.test(getComputedStyle(el).overflowY)
|
|
344
|
+
&& el.scrollHeight > el.clientHeight + 1;
|
|
345
|
+
const documentScrolls = root.scrollHeight > vh + 1;
|
|
346
|
+
const out = [];
|
|
347
|
+
for (const el of Array.from(document.querySelectorAll('body *'))) {
|
|
348
|
+
if (out.length >= arg.max) break;
|
|
349
|
+
const cs = getComputedStyle(el);
|
|
350
|
+
if (!/(auto|scroll|overlay)/.test(cs.overflowY) || !/^(contain|none)$/.test(cs.overscrollBehaviorY)) continue;
|
|
351
|
+
if (el.scrollHeight > el.clientHeight + 1) continue;
|
|
352
|
+
let scroller = null;
|
|
353
|
+
for (let a = el.parentElement; a && a !== document.body && a !== document.documentElement; a = a.parentElement) {
|
|
354
|
+
if (scrolls(a)) { scroller = a; break; }
|
|
355
|
+
}
|
|
356
|
+
if (!scroller && !documentScrolls) continue;
|
|
357
|
+
const r = el.getBoundingClientRect();
|
|
358
|
+
const top = Math.max(r.top, 0);
|
|
359
|
+
const bottom = Math.min(r.bottom, vh);
|
|
360
|
+
const left = Math.max(r.left, 0);
|
|
361
|
+
const right = Math.min(r.right, vw);
|
|
362
|
+
if (bottom - top < 20 || right - left < 20) continue;
|
|
363
|
+
out.push({ selector: cssPath(el), tag: el.tagName.toLowerCase(),
|
|
364
|
+
className: (typeof el.className === 'string' ? el.className : '').slice(0, 80),
|
|
365
|
+
overscroll: cs.overscrollBehaviorY, scrollHeight: el.scrollHeight, clientHeight: el.clientHeight,
|
|
366
|
+
scroller: scroller
|
|
367
|
+
? { selector: cssPath(scroller), scrollHeight: scroller.scrollHeight, clientHeight: scroller.clientHeight }
|
|
368
|
+
: { selector: 'document', scrollHeight: root.scrollHeight, clientHeight: vh },
|
|
369
|
+
x: Math.round((left + right) / 2), y: Math.round((top + bottom) / 2) });
|
|
370
|
+
}
|
|
371
|
+
return out;
|
|
372
|
+
}`,
|
|
373
|
+
// BFR-ORGANIZER-029 — the scroll positions of an element, all its ancestors and the window (the wheel test).
|
|
374
|
+
scrollChain: `(selector) => {
|
|
375
|
+
const out = [];
|
|
376
|
+
for (let n = document.querySelector(selector); n && n.nodeType === 1; n = n.parentElement) out.push(n.scrollTop);
|
|
377
|
+
out.push(window.scrollY);
|
|
378
|
+
return out;
|
|
379
|
+
}`,
|
|
380
|
+
// BFR-ORGANIZER-029 — puts the positions `scrollChain` read back (the page is left as it was found).
|
|
381
|
+
restoreScrollChain: `(arg) => {
|
|
382
|
+
let i = 0;
|
|
383
|
+
for (let n = document.querySelector(arg.selector); n && n.nodeType === 1; n = n.parentElement) {
|
|
384
|
+
n.scrollTop = arg.positions[i++] || 0;
|
|
385
|
+
}
|
|
386
|
+
window.scrollTo(window.scrollX, arg.positions[i] || 0);
|
|
387
|
+
return true;
|
|
388
|
+
}`,
|
|
324
389
|
};
|
|
325
390
|
//# sourceMappingURL=ui-check-page-scripts.const.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-check-page-scripts.const.js","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACU,QAAA,8BAA8B,GAAqC;IAE9E;;;OAGG;IACH,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+DZ;IAEF,gHAAgH;IAChH,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkElB;IAEF,iEAAiE;IACjE,iBAAiB,EAAE;;;;;;;IAOjB;IAEF;;;;;OAKG;IACH,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwCf;IAEF,kEAAkE;IAClE,WAAW,EAAE;;;;;IAKX;IAEF,kEAAkE;IAClE,WAAW,EAAE;;;;;;IAMX;IAEF;;;;OAIG;IACH,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAmCZ;IAEF,gHAAgH;IAChH,sHAAsH;IACtH,2GAA2G;IAC3G,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+Df;CACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"ui-check-page-scripts.const.js","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/constants/ui-check-page-scripts.const.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACU,QAAA,8BAA8B,GAAqC;IAE9E;;;OAGG;IACH,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+DZ;IAEF,gHAAgH;IAChH,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkElB;IAEF,iEAAiE;IACjE,iBAAiB,EAAE;;;;;;;IAOjB;IAEF;;;;;OAKG;IACH,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwCf;IAEF,kEAAkE;IAClE,WAAW,EAAE;;;;;IAKX;IAEF,kEAAkE;IAClE,WAAW,EAAE;;;;;;IAMX;IAEF;;;;OAIG;IACH,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAmCZ;IAEF,gHAAgH;IAChH,sHAAsH;IACtH,2GAA2G;IAC3G,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+Df;IAEF,qHAAqH;IACrH,6GAA6G;IAC7G,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8CX;IAEF,6GAA6G;IAC7G,WAAW,EAAE;;;;;IAKX;IAEF,qGAAqG;IACrG,kBAAkB,EAAE;;;;;;;IAOlB;CACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
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 SCROLL TRAP: an element that is a scroll container (`overflow-y: auto|scroll`) with
|
|
7
|
+
* `overscroll-behavior-y: contain` (or `none`), but does NOT scroll itself (its content is not bounded), while an
|
|
8
|
+
* ancestor (or the document) does — so the wheel over its content moves nothing: the element has nothing to scroll and
|
|
9
|
+
* the `contain` forbids handing the scroll on.
|
|
10
|
+
*
|
|
11
|
+
* Two layers: (1) STRUCTURAL — the candidates above; (2) BEHAVIOURAL — the wheel over each candidate's centre, and the
|
|
12
|
+
* scroll positions of the candidate, all its ancestors and the window before / after. Only a candidate where NOTHING
|
|
13
|
+
* moved is a finding (a browser that chains anyway is no trap). The positions are restored afterwards; nothing is
|
|
14
|
+
* pressed, so the detector is not interactive.
|
|
15
|
+
*
|
|
16
|
+
* Origin: `BFR-ORGANIZER-029` — owner, 2026-10-26 05:09: "nem lehet scrollozni"; measured by My Assistant Dev 1 on the
|
|
17
|
+
* Organizer TEST (`v01.16.219`): 25 wheel events on the task list ⇒ 0 px, desktop and mobile; the shared
|
|
18
|
+
* `app-a-pull-to-refresh` `.ptr-root` (`overflow-y: auto` + `overscroll-behavior-y: contain`, 5435 / 5435 px) inside a
|
|
19
|
+
* scrolling frame (5732 / 844 px). `nested-scroll` cannot see it: there the document does not scroll and the trap
|
|
20
|
+
* itself is not scrollable.
|
|
21
|
+
*/
|
|
22
|
+
export declare class DyE2E_ScrollTrap_Detector implements DyE2E_UICheckDetector_Interface {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly errorClass: string;
|
|
25
|
+
readonly description: string;
|
|
26
|
+
readonly origin: DyE2E_UICheckOrigin_Interface;
|
|
27
|
+
readonly interactive: boolean;
|
|
28
|
+
notes: string[];
|
|
29
|
+
/** At most this many candidates get the wheel test (a page with more is noted). */
|
|
30
|
+
static readonly maxCandidates: number;
|
|
31
|
+
/** One wheel step, px (well over one line, so a working chain always moves something). */
|
|
32
|
+
static readonly wheelPx: number;
|
|
33
|
+
/** The wait after the wheel (Playwright does not wait for the scroll to finish). */
|
|
34
|
+
static readonly wheelSettleMs: number;
|
|
35
|
+
run(page: Page, context: DyE2E_UICheckContext_Interface): Promise<DyE2E_UICheckFinding_Interface[]>;
|
|
36
|
+
/** Wheels over the candidate and returns how many px the candidate, its ancestors and the window moved together. */
|
|
37
|
+
private wheelMovedPx;
|
|
38
|
+
/** The finding of one trapped candidate. */
|
|
39
|
+
private toFinding;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=scroll-trap.detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll-trap.detector.d.ts","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/detectors/scroll-trap.detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,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;AAmB1F;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,yBAA0B,YAAW,+BAA+B;IAE/E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAiB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAA0C;IACrE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAC8E;IAC1G,QAAQ,CAAC,MAAM,EAAE,6BAA6B,CAG5C;IACF,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAS;IACtC,KAAK,EAAE,MAAM,EAAE,CAAM;IAErB,mFAAmF;IACnF,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAM;IAE3C,0FAA0F;IAC1F,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAO;IAEtC,oFAAoF;IACpF,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAO;IAEtC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAsBzG,oHAAoH;YACtG,YAAY;IAmB1B,4CAA4C;IAC5C,OAAO,CAAC,SAAS;CAsBlB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyE2E_ScrollTrap_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
|
+
* A SCROLL TRAP: an element that is a scroll container (`overflow-y: auto|scroll`) with
|
|
8
|
+
* `overscroll-behavior-y: contain` (or `none`), but does NOT scroll itself (its content is not bounded), while an
|
|
9
|
+
* ancestor (or the document) does — so the wheel over its content moves nothing: the element has nothing to scroll and
|
|
10
|
+
* the `contain` forbids handing the scroll on.
|
|
11
|
+
*
|
|
12
|
+
* Two layers: (1) STRUCTURAL — the candidates above; (2) BEHAVIOURAL — the wheel over each candidate's centre, and the
|
|
13
|
+
* scroll positions of the candidate, all its ancestors and the window before / after. Only a candidate where NOTHING
|
|
14
|
+
* moved is a finding (a browser that chains anyway is no trap). The positions are restored afterwards; nothing is
|
|
15
|
+
* pressed, so the detector is not interactive.
|
|
16
|
+
*
|
|
17
|
+
* Origin: `BFR-ORGANIZER-029` — owner, 2026-10-26 05:09: "nem lehet scrollozni"; measured by My Assistant Dev 1 on the
|
|
18
|
+
* Organizer TEST (`v01.16.219`): 25 wheel events on the task list ⇒ 0 px, desktop and mobile; the shared
|
|
19
|
+
* `app-a-pull-to-refresh` `.ptr-root` (`overflow-y: auto` + `overscroll-behavior-y: contain`, 5435 / 5435 px) inside a
|
|
20
|
+
* scrolling frame (5732 / 844 px). `nested-scroll` cannot see it: there the document does not scroll and the trap
|
|
21
|
+
* itself is not scrollable.
|
|
22
|
+
*/
|
|
23
|
+
class DyE2E_ScrollTrap_Detector {
|
|
24
|
+
id = 'scroll-trap';
|
|
25
|
+
errorClass = 'scroll-trapped-by-overscroll-contain';
|
|
26
|
+
description = 'A non-scrolling overscroll-contain container inside a scrolling one: the wheel over it moves nothing.';
|
|
27
|
+
origin = {
|
|
28
|
+
code: 'BFR-ORGANIZER-029', foundBy: 'owner 2026-10-26, measured by My Assistant Dev 1 (Organizer TEST)',
|
|
29
|
+
date: '2026-10-26',
|
|
30
|
+
};
|
|
31
|
+
interactive = false;
|
|
32
|
+
notes = [];
|
|
33
|
+
/** At most this many candidates get the wheel test (a page with more is noted). */
|
|
34
|
+
static maxCandidates = 10;
|
|
35
|
+
/** One wheel step, px (well over one line, so a working chain always moves something). */
|
|
36
|
+
static wheelPx = 600;
|
|
37
|
+
/** The wait after the wheel (Playwright does not wait for the scroll to finish). */
|
|
38
|
+
static wheelSettleMs = 300;
|
|
39
|
+
async run(page, context) {
|
|
40
|
+
const candidates = await ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['scrollTraps'], { max: DyE2E_ScrollTrap_Detector.maxCandidates + 1 });
|
|
41
|
+
const findings = [];
|
|
42
|
+
this.notes = candidates.length > DyE2E_ScrollTrap_Detector.maxCandidates
|
|
43
|
+
? [`scroll-trap: more than ${DyE2E_ScrollTrap_Detector.maxCandidates} candidates — only the first ` +
|
|
44
|
+
`${DyE2E_ScrollTrap_Detector.maxCandidates} were wheel-tested`]
|
|
45
|
+
: [];
|
|
46
|
+
// the behavioural layer: the wheel over each candidate — a finding only where nothing moved
|
|
47
|
+
for (const candidate of candidates.slice(0, DyE2E_ScrollTrap_Detector.maxCandidates)) {
|
|
48
|
+
const movedPx = await this.wheelMovedPx(page, candidate);
|
|
49
|
+
if (!movedPx) {
|
|
50
|
+
findings.push(this.toFinding({ page: page, context: context, candidate: candidate }));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return findings;
|
|
54
|
+
}
|
|
55
|
+
/** Wheels over the candidate and returns how many px the candidate, its ancestors and the window moved together. */
|
|
56
|
+
async wheelMovedPx(page, candidate) {
|
|
57
|
+
const before = await ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['scrollChain'], candidate.selector);
|
|
58
|
+
await page.mouse.move(candidate.x, candidate.y);
|
|
59
|
+
await page.mouse.wheel(0, DyE2E_ScrollTrap_Detector.wheelPx);
|
|
60
|
+
await page.waitForTimeout(DyE2E_ScrollTrap_Detector.wheelSettleMs);
|
|
61
|
+
const after = await ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['scrollChain'], candidate.selector);
|
|
62
|
+
// the page is left as it was found
|
|
63
|
+
await ui_check_page_util_1.DyE2E_UICheckPage_Util.evaluate(page, ui_check_page_scripts_const_1.DyE2E_UICheckPageScripts_Const['restoreScrollChain'], { selector: candidate.selector, positions: before });
|
|
64
|
+
return after.reduce((sum, position, index) => sum + Math.abs(position - (before[index] ?? 0)), 0);
|
|
65
|
+
}
|
|
66
|
+
/** The finding of one trapped candidate. */
|
|
67
|
+
toFinding(set) {
|
|
68
|
+
const candidate = set.candidate;
|
|
69
|
+
return {
|
|
70
|
+
detector: this.id,
|
|
71
|
+
errorClass: this.errorClass,
|
|
72
|
+
url: set.page.url() || set.context.url,
|
|
73
|
+
target: { selector: candidate.selector, tag: candidate.tag, text: candidate.className, testId: null,
|
|
74
|
+
ariaLabel: null },
|
|
75
|
+
measured: `"${candidate.selector}" has overscroll-behavior-y: ${candidate.overscroll} but does not scroll ` +
|
|
76
|
+
`(${candidate.scrollHeight} / ${candidate.clientHeight} px), while "${candidate.scroller.selector}" does ` +
|
|
77
|
+
`(${candidate.scroller.scrollHeight} / ${candidate.scroller.clientHeight} px); a ` +
|
|
78
|
+
`${DyE2E_ScrollTrap_Detector.wheelPx} px wheel over it moved 0 px.`,
|
|
79
|
+
expected: 'The wheel over the content scrolls the page: the overscroll containment only on the element that ' +
|
|
80
|
+
'owns the scroll (a bounded height), or no containment at all.',
|
|
81
|
+
details: { ...candidate, wheelPx: DyE2E_ScrollTrap_Detector.wheelPx, movedPx: 0 },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.DyE2E_ScrollTrap_Detector = DyE2E_ScrollTrap_Detector;
|
|
86
|
+
//# sourceMappingURL=scroll-trap.detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll-trap.detector.js","sourceRoot":"","sources":["../../../../../src/_modules/ui-check/_collections/detectors/scroll-trap.detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,10 @@ export declare const DyE2E_UICheckDefaultDetectors_Const: readonly DyE2E_UICheck
|
|
|
18
18
|
* - `covered-control` (BFR-ADVENTOR-081): fires on a fixture of the measured defect (a footer over a link) and stays
|
|
19
19
|
* silent on the fixed layout; the real page (Adventor TEST 853) is fixed already, so the live proof is the
|
|
20
20
|
* "silent now" half only.
|
|
21
|
+
* - `scroll-trap` (BFR-ORGANIZER-029): fires on a fixture of the measured defect (a non-scrolling
|
|
22
|
+
* `overscroll-behavior-y: contain` box inside a scrolling frame: the wheel moves 0 px) and stays silent on the
|
|
23
|
+
* fixed layouts; the real page (Organizer TEST task list) was fixed in the project, so the live proof is the
|
|
24
|
+
* "silent now" half only.
|
|
21
25
|
*/
|
|
22
26
|
export declare const DyE2E_UICheckCandidateDetectors_Const: readonly DyE2E_UICheckDetector_Interface[];
|
|
23
27
|
//# sourceMappingURL=ui-check-default-detectors.const.d.ts.map
|
|
@@ -1 +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;
|
|
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;AAOzF;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,EAAE,SAAS,+BAA+B,EAEzF,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,qCAAqC,EAAE,SAAS,+BAA+B,EAK3F,CAAC"}
|
|
@@ -5,6 +5,7 @@ const covered_control_detector_1 = require("./detectors/covered-control.detector
|
|
|
5
5
|
const dead_control_detector_1 = require("./detectors/dead-control.detector");
|
|
6
6
|
const nested_scroll_detector_1 = require("./detectors/nested-scroll.detector");
|
|
7
7
|
const non_toggling_control_detector_1 = require("./detectors/non-toggling-control.detector");
|
|
8
|
+
const scroll_trap_detector_1 = require("./detectors/scroll-trap.detector");
|
|
8
9
|
/**
|
|
9
10
|
* The DEFAULT, growing UI detector list (BFR-FLEET-012) — every page, form and feature gets all of them.
|
|
10
11
|
*
|
|
@@ -26,10 +27,15 @@ exports.DyE2E_UICheckDefaultDetectors_Const = [
|
|
|
26
27
|
* - `covered-control` (BFR-ADVENTOR-081): fires on a fixture of the measured defect (a footer over a link) and stays
|
|
27
28
|
* silent on the fixed layout; the real page (Adventor TEST 853) is fixed already, so the live proof is the
|
|
28
29
|
* "silent now" half only.
|
|
30
|
+
* - `scroll-trap` (BFR-ORGANIZER-029): fires on a fixture of the measured defect (a non-scrolling
|
|
31
|
+
* `overscroll-behavior-y: contain` box inside a scrolling frame: the wheel moves 0 px) and stays silent on the
|
|
32
|
+
* fixed layouts; the real page (Organizer TEST task list) was fixed in the project, so the live proof is the
|
|
33
|
+
* "silent now" half only.
|
|
29
34
|
*/
|
|
30
35
|
exports.DyE2E_UICheckCandidateDetectors_Const = [
|
|
31
36
|
new nested_scroll_detector_1.DyE2E_NestedScroll_Detector(),
|
|
32
37
|
new non_toggling_control_detector_1.DyE2E_NonTogglingControl_Detector(),
|
|
33
38
|
new covered_control_detector_1.DyE2E_CoveredControl_Detector(),
|
|
39
|
+
new scroll_trap_detector_1.DyE2E_ScrollTrap_Detector(),
|
|
34
40
|
];
|
|
35
41
|
//# sourceMappingURL=ui-check-default-detectors.const.js.map
|
|
@@ -1 +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,mFAAqF;AACrF,6EAA+E;AAC/E,+EAAiF;AACjF,6FAA8F;
|
|
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,mFAAqF;AACrF,6EAA+E;AAC/E,+EAAiF;AACjF,6FAA8F;AAC9F,2EAA6E;AAE7E;;;;;;GAMG;AACU,QAAA,mCAAmC,GAA+C;IAC7F,IAAI,kDAA0B,EAAE;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACU,QAAA,qCAAqC,GAA+C;IAC/F,IAAI,oDAA2B,EAAE;IACjC,IAAI,iEAAiC,EAAE;IACvC,IAAI,wDAA6B,EAAE;IACnC,IAAI,gDAAyB,EAAE;CAChC,CAAC"}
|
|
@@ -17,6 +17,7 @@ export * from './_collections/detectors/covered-control.detector';
|
|
|
17
17
|
export * from './_collections/detectors/dead-control.detector';
|
|
18
18
|
export * from './_collections/detectors/nested-scroll.detector';
|
|
19
19
|
export * from './_collections/detectors/non-toggling-control.detector';
|
|
20
|
+
export * from './_collections/detectors/scroll-trap.detector';
|
|
20
21
|
export * from './_collections/ui-check-default-detectors.const';
|
|
21
22
|
export * from './_collections/ui-check-guard.util';
|
|
22
23
|
export * from './_collections/ui-check-page.util';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/ui-check/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,sDAAsD,CAAC;AACrE,cAAc,mDAAmD,CAAC;AAClE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,iDAAiD,CAAC;AAChE,cAAc,wDAAwD,CAAC;AACvE,cAAc,iDAAiD,CAAC;AAChE,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/ui-check/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,sDAAsD,CAAC;AACrE,cAAc,mDAAmD,CAAC;AAClE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,iDAAiD,CAAC;AAChE,cAAc,wDAAwD,CAAC;AACvE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,iDAAiD,CAAC;AAChE,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC"}
|
|
@@ -33,6 +33,7 @@ __exportStar(require("./_collections/detectors/covered-control.detector"), expor
|
|
|
33
33
|
__exportStar(require("./_collections/detectors/dead-control.detector"), exports);
|
|
34
34
|
__exportStar(require("./_collections/detectors/nested-scroll.detector"), exports);
|
|
35
35
|
__exportStar(require("./_collections/detectors/non-toggling-control.detector"), exports);
|
|
36
|
+
__exportStar(require("./_collections/detectors/scroll-trap.detector"), exports);
|
|
36
37
|
__exportStar(require("./_collections/ui-check-default-detectors.const"), exports);
|
|
37
38
|
__exportStar(require("./_collections/ui-check-guard.util"), exports);
|
|
38
39
|
__exportStar(require("./_collections/ui-check-page.util"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/ui-check/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;GAaG;AACH,uFAAqE;AACrE,oFAAkE;AAClE,iFAA+D;AAC/D,kFAAgE;AAChE,yFAAuE;AACvE,kFAAgE;AAChE,qEAAmD;AACnD,oEAAkD;AAClD,sEAAoD;AACpD,uEAAqD;AACrD,wEAAsD;AACtD,uEAAqD;AACrD,sEAAoD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/ui-check/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;GAaG;AACH,uFAAqE;AACrE,oFAAkE;AAClE,iFAA+D;AAC/D,kFAAgE;AAChE,yFAAuE;AACvE,gFAA8D;AAC9D,kFAAgE;AAChE,qEAAmD;AACnD,oEAAkD;AAClD,sEAAoD;AACpD,uEAAqD;AACrD,wEAAsD;AACtD,uEAAqD;AACrD,sEAAoD"}
|
package/build/index.js
CHANGED
|
@@ -26,5 +26,5 @@ __exportStar(require("./_modules/game/index"), exports);
|
|
|
26
26
|
__exportStar(require("./_modules/ui-check/index"), exports);
|
|
27
27
|
__exportStar(require("./_modules/coverage/index"), exports);
|
|
28
28
|
/** Package-version stamp — npm-publish-time runtime-érték. */
|
|
29
|
-
exports.DYE2E_PACKAGE_VERSION = '01.18.
|
|
29
|
+
exports.DYE2E_PACKAGE_VERSION = '01.18.33';
|
|
30
30
|
//# 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.33",
|
|
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",
|