my-frontend-observer 0.1.0 → 0.3.0
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 +82 -1
- package/README.md +30 -7
- package/dist/application/observationPersistence.js +1 -0
- package/dist/application/observationPersistence.js.map +1 -1
- package/dist/browser/chromiumAdapter.js +58 -4
- package/dist/browser/chromiumAdapter.js.map +1 -1
- package/dist/browser/evidenceCapture.d.ts +46 -3
- package/dist/browser/evidenceCapture.js +393 -94
- package/dist/browser/evidenceCapture.js.map +1 -1
- package/dist/browser/scrollCapture.d.ts +32 -0
- package/dist/browser/scrollCapture.js +163 -0
- package/dist/browser/scrollCapture.js.map +1 -0
- package/dist/browser/types.d.ts +3 -1
- package/dist/cli.js +165 -7
- package/dist/cli.js.map +1 -1
- package/dist/domain/diagnostics.d.ts +1 -1
- package/dist/domain/diagnostics.js +2 -0
- package/dist/domain/diagnostics.js.map +1 -1
- package/dist/domain/identity.d.ts +8 -3
- package/dist/domain/identity.js +10 -4
- package/dist/domain/identity.js.map +1 -1
- package/dist/domain/schema.d.ts +164 -6
- package/dist/domain/schema.js +314 -4
- package/dist/domain/schema.js.map +1 -1
- package/dist/domain/scrollEvidence.d.ts +51 -0
- package/dist/domain/scrollEvidence.js +134 -0
- package/dist/domain/scrollEvidence.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/request/request.d.ts +57 -1
- package/dist/request/request.js +292 -14
- package/dist/request/request.js.map +1 -1
- package/docs/ARCHITECTURE.md +62 -1
- package/docs/CI_CD.md +49 -8
- package/docs/COMMANDS.md +184 -9
- package/docs/CONTRACTS.md +135 -6
- package/docs/CURRENT_STATE.md +128 -6
- package/docs/DEVELOPMENT.md +41 -3
- package/docs/PROJECT_OVERVIEW.md +12 -6
- package/docs/QUICKSTART.md +3 -1
- package/docs/RELEASE.md +12 -5
- package/docs/ROADMAP.md +9 -0
- package/docs/SECURITY.md +6 -2
- package/docs/WORKFLOWS.md +41 -14
- package/package.json +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { EvidenceField } from './evidence.js';
|
|
2
|
+
import type { Viewport } from '../request/request.js';
|
|
3
|
+
import type { ScrollableMetrics, OverflowEvidence, ViewportRelationEvidence, TargetGeometry, ScrollRuntimeSnapshot, TargetScrollRuntimeState, TargetScrollTransition, ScrollScenarioTransition, ScrollOwnerInterpretation } from './schema.js';
|
|
4
|
+
/**
|
|
5
|
+
* Derived only from a bounding rectangle (viewport-relative, as produced by
|
|
6
|
+
* `getBoundingClientRect()`) plus viewport width/height - never from source
|
|
7
|
+
* styles or locator kind (Batch 1 frozen contract). `above`/`below` require
|
|
8
|
+
* the rectangle to be *entirely* outside the viewport on that axis; any
|
|
9
|
+
* vertical overlap with `[0, viewport.height)` is `intersecting`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function deriveViewportRelation(rect: TargetGeometry, viewport: Viewport): ViewportRelationEvidence;
|
|
12
|
+
/**
|
|
13
|
+
* Distinguishes a computed `overflow-x`/`overflow-y` CSS declaration from
|
|
14
|
+
* actual dimensional overflow. `overflow-x: auto`/`overflow-y: scroll` alone
|
|
15
|
+
* never implies actual overflow - only `scrollWidth > clientWidth` /
|
|
16
|
+
* `scrollHeight > clientHeight` do.
|
|
17
|
+
*/
|
|
18
|
+
export declare function deriveOverflowEvidence(metrics: ScrollableMetrics, overflowX: string, overflowY: string): OverflowEvidence;
|
|
19
|
+
/**
|
|
20
|
+
* Bounded before/after change evidence for one configured target across the
|
|
21
|
+
* one scroll action - not a generic recursive diff. Returns `undefined`
|
|
22
|
+
* (rather than fabricating zeroed/default values) when either snapshot's
|
|
23
|
+
* metrics/boundingRect/viewportRelation evidence for this target is not
|
|
24
|
+
* itself usable (e.g. the target never resolved), consistent with
|
|
25
|
+
* `enteredViewport`/`leftViewport` only being evaluated when both
|
|
26
|
+
* viewport-relation states are valid.
|
|
27
|
+
*/
|
|
28
|
+
export declare function deriveTargetScrollTransition(initial: TargetScrollRuntimeState, final: TargetScrollRuntimeState): TargetScrollTransition | undefined;
|
|
29
|
+
/** Derives the bounded scenario transition evidence purely from the two already-captured runtime snapshots - no re-measurement, no generic JSON diffing. A target absent from either snapshot's `targets` map, or whose per-target transition cannot be derived (see `deriveTargetScrollTransition`), is simply omitted from `targets` here. */
|
|
30
|
+
export declare function deriveScrollScenarioTransition(initial: ScrollRuntimeSnapshot, final: ScrollRuntimeSnapshot): ScrollScenarioTransition;
|
|
31
|
+
/**
|
|
32
|
+
* Conservative scroll-owner derivation, shared by both `window-scroll-by`
|
|
33
|
+
* and `target-scroll-by` scenarios: relies solely on observed scroll
|
|
34
|
+
* *position* changes (`scrollTop`/`scrollLeft`/`window.scrollX`/
|
|
35
|
+
* `window.scrollY`), never on a target's bounding-rectangle movement (which
|
|
36
|
+
* moves for every configured target whenever the document scrolls,
|
|
37
|
+
* regardless of who "owns" scrolling - using it here would falsely
|
|
38
|
+
* attribute document scrolling to every visible target) and never on
|
|
39
|
+
* computed overflow, `position: fixed`/`sticky`, target name, locator kind,
|
|
40
|
+
* or DOM hierarchy.
|
|
41
|
+
*
|
|
42
|
+
* Rules (frozen Batch 1 vocabulary):
|
|
43
|
+
* - no window movement, no target movement -> `none`;
|
|
44
|
+
* - window movement, no competing target movement -> `document`;
|
|
45
|
+
* - no window movement, exactly one target's own scroll position moved
|
|
46
|
+
* (on either or both axes - two axes of the *same* target is still one
|
|
47
|
+
* owner) -> `target:<name>`;
|
|
48
|
+
* - anything else (window plus a target, or more than one target) ->
|
|
49
|
+
* `indeterminate` - multiple plausible owners, never forced to pick one.
|
|
50
|
+
*/
|
|
51
|
+
export declare function deriveScrollOwner(transition: ScrollScenarioTransition): EvidenceField<ScrollOwnerInterpretation>;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derived only from a bounding rectangle (viewport-relative, as produced by
|
|
3
|
+
* `getBoundingClientRect()`) plus viewport width/height - never from source
|
|
4
|
+
* styles or locator kind (Batch 1 frozen contract). `above`/`below` require
|
|
5
|
+
* the rectangle to be *entirely* outside the viewport on that axis; any
|
|
6
|
+
* vertical overlap with `[0, viewport.height)` is `intersecting`.
|
|
7
|
+
*/
|
|
8
|
+
export function deriveViewportRelation(rect, viewport) {
|
|
9
|
+
const vertical = rect.bottom <= 0 ? 'above' : rect.y >= viewport.height ? 'below' : 'intersecting';
|
|
10
|
+
const intersectsViewport = rect.right > 0 && rect.x < viewport.width && rect.bottom > 0 && rect.y < viewport.height;
|
|
11
|
+
const fullyWithinViewport = rect.x >= 0 && rect.y >= 0 && rect.right <= viewport.width && rect.bottom <= viewport.height;
|
|
12
|
+
return { vertical, intersectsViewport, fullyWithinViewport };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Distinguishes a computed `overflow-x`/`overflow-y` CSS declaration from
|
|
16
|
+
* actual dimensional overflow. `overflow-x: auto`/`overflow-y: scroll` alone
|
|
17
|
+
* never implies actual overflow - only `scrollWidth > clientWidth` /
|
|
18
|
+
* `scrollHeight > clientHeight` do.
|
|
19
|
+
*/
|
|
20
|
+
export function deriveOverflowEvidence(metrics, overflowX, overflowY) {
|
|
21
|
+
return {
|
|
22
|
+
horizontalOverflow: metrics.scrollWidth > metrics.clientWidth,
|
|
23
|
+
verticalOverflow: metrics.scrollHeight > metrics.clientHeight,
|
|
24
|
+
overflowX,
|
|
25
|
+
overflowY,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function numberChange(before, after) {
|
|
29
|
+
return { before, after, changed: before !== after };
|
|
30
|
+
}
|
|
31
|
+
function extractAvailable(field) {
|
|
32
|
+
return field.state === 'available' || field.state === 'partial' ? field.value : undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Bounded before/after change evidence for one configured target across the
|
|
36
|
+
* one scroll action - not a generic recursive diff. Returns `undefined`
|
|
37
|
+
* (rather than fabricating zeroed/default values) when either snapshot's
|
|
38
|
+
* metrics/boundingRect/viewportRelation evidence for this target is not
|
|
39
|
+
* itself usable (e.g. the target never resolved), consistent with
|
|
40
|
+
* `enteredViewport`/`leftViewport` only being evaluated when both
|
|
41
|
+
* viewport-relation states are valid.
|
|
42
|
+
*/
|
|
43
|
+
export function deriveTargetScrollTransition(initial, final) {
|
|
44
|
+
const initialMetrics = extractAvailable(initial.metrics);
|
|
45
|
+
const finalMetrics = extractAvailable(final.metrics);
|
|
46
|
+
const initialRect = extractAvailable(initial.boundingRect);
|
|
47
|
+
const finalRect = extractAvailable(final.boundingRect);
|
|
48
|
+
const initialRelation = extractAvailable(initial.viewportRelation);
|
|
49
|
+
const finalRelation = extractAvailable(final.viewportRelation);
|
|
50
|
+
if (!initialMetrics || !finalMetrics || !initialRect || !finalRect || !initialRelation || !finalRelation) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
const enteredViewport = !initialRelation.intersectsViewport && finalRelation.intersectsViewport;
|
|
54
|
+
const leftViewport = initialRelation.intersectsViewport && !finalRelation.intersectsViewport;
|
|
55
|
+
return {
|
|
56
|
+
scrollTop: numberChange(initialMetrics.scrollTop, finalMetrics.scrollTop),
|
|
57
|
+
scrollLeft: numberChange(initialMetrics.scrollLeft, finalMetrics.scrollLeft),
|
|
58
|
+
boundingRectPosition: {
|
|
59
|
+
before: { x: initialRect.x, y: initialRect.y },
|
|
60
|
+
after: { x: finalRect.x, y: finalRect.y },
|
|
61
|
+
changed: initialRect.x !== finalRect.x || initialRect.y !== finalRect.y,
|
|
62
|
+
},
|
|
63
|
+
viewportRelation: { before: initialRelation.vertical, after: finalRelation.vertical, changed: initialRelation.vertical !== finalRelation.vertical },
|
|
64
|
+
enteredViewport,
|
|
65
|
+
leftViewport,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Derives the bounded scenario transition evidence purely from the two already-captured runtime snapshots - no re-measurement, no generic JSON diffing. A target absent from either snapshot's `targets` map, or whose per-target transition cannot be derived (see `deriveTargetScrollTransition`), is simply omitted from `targets` here. */
|
|
69
|
+
export function deriveScrollScenarioTransition(initial, final) {
|
|
70
|
+
const targets = {};
|
|
71
|
+
for (const [name, initialState] of Object.entries(initial.targets)) {
|
|
72
|
+
const finalState = final.targets[name];
|
|
73
|
+
if (!finalState)
|
|
74
|
+
continue;
|
|
75
|
+
const transition = deriveTargetScrollTransition(initialState, finalState);
|
|
76
|
+
if (transition)
|
|
77
|
+
targets[name] = transition;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
windowScrollX: numberChange(initial.window.scrollX, final.window.scrollX),
|
|
81
|
+
windowScrollY: numberChange(initial.window.scrollY, final.window.scrollY),
|
|
82
|
+
targets,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Conservative scroll-owner derivation, shared by both `window-scroll-by`
|
|
87
|
+
* and `target-scroll-by` scenarios: relies solely on observed scroll
|
|
88
|
+
* *position* changes (`scrollTop`/`scrollLeft`/`window.scrollX`/
|
|
89
|
+
* `window.scrollY`), never on a target's bounding-rectangle movement (which
|
|
90
|
+
* moves for every configured target whenever the document scrolls,
|
|
91
|
+
* regardless of who "owns" scrolling - using it here would falsely
|
|
92
|
+
* attribute document scrolling to every visible target) and never on
|
|
93
|
+
* computed overflow, `position: fixed`/`sticky`, target name, locator kind,
|
|
94
|
+
* or DOM hierarchy.
|
|
95
|
+
*
|
|
96
|
+
* Rules (frozen Batch 1 vocabulary):
|
|
97
|
+
* - no window movement, no target movement -> `none`;
|
|
98
|
+
* - window movement, no competing target movement -> `document`;
|
|
99
|
+
* - no window movement, exactly one target's own scroll position moved
|
|
100
|
+
* (on either or both axes - two axes of the *same* target is still one
|
|
101
|
+
* owner) -> `target:<name>`;
|
|
102
|
+
* - anything else (window plus a target, or more than one target) ->
|
|
103
|
+
* `indeterminate` - multiple plausible owners, never forced to pick one.
|
|
104
|
+
*/
|
|
105
|
+
export function deriveScrollOwner(transition) {
|
|
106
|
+
const windowMoved = transition.windowScrollX.changed || transition.windowScrollY.changed;
|
|
107
|
+
const changedTargetNames = Object.entries(transition.targets)
|
|
108
|
+
.filter(([, t]) => t.scrollTop.changed || t.scrollLeft.changed)
|
|
109
|
+
.map(([name]) => name);
|
|
110
|
+
let value;
|
|
111
|
+
let derivedFrom;
|
|
112
|
+
if (!windowMoved && changedTargetNames.length === 0) {
|
|
113
|
+
value = { kind: 'none' };
|
|
114
|
+
derivedFrom = ['window.scrollX', 'window.scrollY', ...Object.keys(transition.targets).flatMap((name) => [`${name}.scrollTop`, `${name}.scrollLeft`])];
|
|
115
|
+
}
|
|
116
|
+
else if (windowMoved && changedTargetNames.length === 0) {
|
|
117
|
+
value = { kind: 'document' };
|
|
118
|
+
derivedFrom = ['window.scrollX', 'window.scrollY'];
|
|
119
|
+
}
|
|
120
|
+
else if (!windowMoved && changedTargetNames.length === 1) {
|
|
121
|
+
const target = changedTargetNames[0];
|
|
122
|
+
value = { kind: 'target', target };
|
|
123
|
+
derivedFrom = [`${target}.scrollTop`, `${target}.scrollLeft`];
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
value = { kind: 'indeterminate' };
|
|
127
|
+
derivedFrom = [
|
|
128
|
+
...(windowMoved ? ['window.scrollX', 'window.scrollY'] : []),
|
|
129
|
+
...changedTargetNames.flatMap((name) => [`${name}.scrollTop`, `${name}.scrollLeft`]),
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
return { state: 'available', source: 'derived', value, derivedFrom };
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=scrollEvidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrollEvidence.js","sourceRoot":"","sources":["../../src/domain/scrollEvidence.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,11 +4,11 @@ export type { DiagnosticCode, DiagnosticSeverity, Diagnostic } from './domain/di
|
|
|
4
4
|
export { DIAGNOSTIC_CODES, DIAGNOSTIC_SEVERITY, orderDiagnostics } from './domain/diagnostics.js';
|
|
5
5
|
export type { CompletionState, RequestPhase } from './domain/completion.js';
|
|
6
6
|
export { deriveCompletion } from './domain/completion.js';
|
|
7
|
-
export type { ObservationArtifact, ArtifactReference, TargetEvidenceRecord, TargetGeometry, TargetComputedStyle, TargetLayoutMetrics, TargetVisibility, TargetSemantics, SchemaValidationResult, } from './domain/schema.js';
|
|
8
|
-
export { ARTIFACT_KIND, SCHEMA_VERSION, PRODUCER_NAME, getProducerInfo, isValidObservationArtifact } from './domain/schema.js';
|
|
7
|
+
export type { ObservationArtifact, ArtifactReference, TargetEvidenceRecord, TargetGeometry, TargetComputedStyle, TargetLayoutMetrics, TargetVisibility, TargetSemantics, TargetLocatorKind, TargetSelectionStatus, TargetSelectionConfidence, TargetLocatorAttemptStatus, TargetLocatorAttempt, TargetResolution, TargetSemanticState, TargetLandmarkRole, TargetContainment, SchemaValidationResult, ScrollableMetrics, OverflowEvidence, WindowScrollSnapshot, DocumentScrollSnapshot, VerticalViewportRelation, ViewportRelationEvidence, TargetScrollRuntimeState, ScrollRuntimeSnapshot, ScrollValueChange, TargetScrollTransition, ScrollScenarioTransition, ScrollOwnerInterpretation, ScrollScenarioEvidence, } from './domain/schema.js';
|
|
8
|
+
export { ARTIFACT_KIND, SCHEMA_VERSION, PRODUCER_NAME, TARGET_LANDMARK_ROLES, getProducerInfo, isValidObservationArtifact, } from './domain/schema.js';
|
|
9
9
|
export { buildRequestIdentity, buildObservationIdentity } from './domain/identity.js';
|
|
10
|
-
export type { NamedTarget, Viewport, ReadinessCondition, ReadinessConfig, NormalizedObservationRequest, RawObservationRequest, NormalizeRequestResult, } from './request/request.js';
|
|
11
|
-
export { normalizeRequest } from './request/request.js';
|
|
10
|
+
export type { NamedTarget, RawNamedTarget, TargetLocator, Viewport, ReadinessCondition, ReadinessConfig, NormalizedObservationRequest, RawObservationRequest, NormalizeRequestResult, ScrollAction, ScrollScenario, } from './request/request.js';
|
|
11
|
+
export { normalizeRequest, SCROLL_DELTA_MAX_ABS } from './request/request.js';
|
|
12
12
|
export type { NormalizeOutputLocationResult } from './request/paths.js';
|
|
13
13
|
export { normalizeOutputLocation } from './request/paths.js';
|
|
14
14
|
export type { SafetyDecision } from './safety/policy.js';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { isValidEvidenceField } from './domain/evidence.js';
|
|
2
2
|
export { DIAGNOSTIC_CODES, DIAGNOSTIC_SEVERITY, orderDiagnostics } from './domain/diagnostics.js';
|
|
3
3
|
export { deriveCompletion } from './domain/completion.js';
|
|
4
|
-
export { ARTIFACT_KIND, SCHEMA_VERSION, PRODUCER_NAME, getProducerInfo, isValidObservationArtifact } from './domain/schema.js';
|
|
4
|
+
export { ARTIFACT_KIND, SCHEMA_VERSION, PRODUCER_NAME, TARGET_LANDMARK_ROLES, getProducerInfo, isValidObservationArtifact, } from './domain/schema.js';
|
|
5
5
|
export { buildRequestIdentity, buildObservationIdentity } from './domain/identity.js';
|
|
6
|
-
export { normalizeRequest } from './request/request.js';
|
|
6
|
+
export { normalizeRequest, SCROLL_DELTA_MAX_ABS } from './request/request.js';
|
|
7
7
|
export { normalizeOutputLocation } from './request/paths.js';
|
|
8
8
|
export { classifyUrl, classifyRedirect, classifySubresource, classifyPopup, classifyDownload } from './safety/policy.js';
|
|
9
9
|
export { runBrowserCapture } from './application/browserCaptureService.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGlG,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGlG,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAmC1D,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAetF,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGzH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAG3E,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEvF,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC"}
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
import type { Diagnostic } from '../domain/diagnostics.js';
|
|
2
|
+
export type TargetLocator = {
|
|
3
|
+
kind: 'role';
|
|
4
|
+
role: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'id';
|
|
8
|
+
value: string;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'data-attribute';
|
|
11
|
+
attribute: string;
|
|
12
|
+
value: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'semantic-element';
|
|
15
|
+
tag: string;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'css';
|
|
18
|
+
selector: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'text';
|
|
21
|
+
text: string;
|
|
22
|
+
};
|
|
2
23
|
export interface NamedTarget {
|
|
3
24
|
name: string;
|
|
4
|
-
|
|
25
|
+
locators: TargetLocator[];
|
|
26
|
+
}
|
|
27
|
+
/** Raw, not-yet-validated target shape as it may appear in a RawObservationRequest. Exactly one of `selector` (legacy) or `locators` (canonical) may be present, never both. */
|
|
28
|
+
export interface RawNamedTarget {
|
|
29
|
+
name?: unknown;
|
|
30
|
+
selector?: unknown;
|
|
31
|
+
locators?: unknown;
|
|
5
32
|
}
|
|
6
33
|
export interface Viewport {
|
|
7
34
|
width: number;
|
|
@@ -12,6 +39,25 @@ export interface ReadinessConfig {
|
|
|
12
39
|
condition: ReadinessCondition;
|
|
13
40
|
timeoutMs: number;
|
|
14
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* v0.3 Batch 1 canonical scroll-action shape. Exactly the two bounded action
|
|
44
|
+
* kinds below are supported; `target` on `target-scroll-by` refers to the
|
|
45
|
+
* existing stable observer-owned target `name` (see `NamedTarget`), never a
|
|
46
|
+
* CSS selector, Playwright locator, or DOM id evaluated directly.
|
|
47
|
+
*/
|
|
48
|
+
export type ScrollAction = {
|
|
49
|
+
kind: 'window-scroll-by';
|
|
50
|
+
deltaX: number;
|
|
51
|
+
deltaY: number;
|
|
52
|
+
} | {
|
|
53
|
+
kind: 'target-scroll-by';
|
|
54
|
+
target: string;
|
|
55
|
+
deltaX: number;
|
|
56
|
+
deltaY: number;
|
|
57
|
+
};
|
|
58
|
+
export interface ScrollScenario {
|
|
59
|
+
action: ScrollAction;
|
|
60
|
+
}
|
|
15
61
|
export interface NormalizedObservationRequest {
|
|
16
62
|
targetUrl: string;
|
|
17
63
|
viewport: Viewport;
|
|
@@ -19,6 +65,7 @@ export interface NormalizedObservationRequest {
|
|
|
19
65
|
outputLocation: string;
|
|
20
66
|
timeoutMs: number;
|
|
21
67
|
readiness: ReadinessConfig;
|
|
68
|
+
scrollScenario?: ScrollScenario;
|
|
22
69
|
}
|
|
23
70
|
export interface RawObservationRequest {
|
|
24
71
|
targetUrl?: unknown;
|
|
@@ -27,6 +74,7 @@ export interface RawObservationRequest {
|
|
|
27
74
|
outputLocation?: unknown;
|
|
28
75
|
timeoutMs?: unknown;
|
|
29
76
|
readiness?: unknown;
|
|
77
|
+
scrollScenario?: unknown;
|
|
30
78
|
}
|
|
31
79
|
export type NormalizeRequestResult = {
|
|
32
80
|
ok: true;
|
|
@@ -35,6 +83,14 @@ export type NormalizeRequestResult = {
|
|
|
35
83
|
ok: false;
|
|
36
84
|
diagnostics: Diagnostic[];
|
|
37
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Conservative bound for a single controlled-observation scroll action. No
|
|
88
|
+
* existing repository precedent for a scroll-delta magnitude; chosen large
|
|
89
|
+
* enough to reach realistic overflow content (documents/containers well
|
|
90
|
+
* beyond one viewport) while staying far short of a pathological/runaway
|
|
91
|
+
* request - see docs/CONTRACTS.md and tests/unit/request.test.ts.
|
|
92
|
+
*/
|
|
93
|
+
export declare const SCROLL_DELTA_MAX_ABS = 20000;
|
|
38
94
|
/**
|
|
39
95
|
* Total, never throws. Collects every applicable diagnostic before returning
|
|
40
96
|
* (does not short-circuit on the first violation) so callers see every
|