@owlmeans/test-ui 0.1.18-rc.37 → 0.1.18-rc.39
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/README.md +1 -1
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/testing-ui/SKILL.md +41 -14
- package/build/marketing-consent.d.ts +13 -2
- package/build/marketing-consent.d.ts.map +1 -1
- package/build/marketing-consent.js +44 -4
- package/build/marketing-consent.js.map +1 -1
- package/build/supervisor.d.ts.map +1 -1
- package/build/supervisor.js +8 -3
- package/build/supervisor.js.map +1 -1
- package/package.json +5 -5
- package/src/marketing-consent.ts +59 -6
- package/src/supervisor.ts +8 -2
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
58
58
|
your project's skill store (`.agents/skills/`):
|
|
59
59
|
|
|
60
60
|
```sh
|
|
61
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
61
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.39
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/test-ui",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.39",
|
|
5
|
+
"generatedAt": "2026-09-24T14:00:35.001Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -6,7 +6,7 @@ description: Category-D component-level acceptance tests for OwlMeans Common UI
|
|
|
6
6
|
|
|
7
7
|
# UI Acceptance Tests — Category D (bun test + Playwright as a library)
|
|
8
8
|
|
|
9
|
-
**Install:** `"@owlmeans/test-ui": "^0.1.18-rc.
|
|
9
|
+
**Install:** `"@owlmeans/test-ui": "^0.1.18-rc.39"` in `devDependencies`
|
|
10
10
|
|
|
11
11
|
`@owlmeans/test-ui` depends on `playwright`, so the browser library arrives with it; add
|
|
12
12
|
`playwright` to `devDependencies` as well when a spec imports a launcher itself. The Vite harness
|
|
@@ -72,7 +72,7 @@ sits behind auth without hand-rolling a token:
|
|
|
72
72
|
| `authenticateViaSupervisorApi(opts)` | Drive the live PK supervisor flow over the backend API (init → sign → authenticate → dispatch), registering the user on first use. Options: `{ apiBaseUrl, userId, pk, paths?, fetchImpl? }`. |
|
|
73
73
|
| `loginViaDispatcher(page, baseUrl, token, opts?)` | Inject a bearer through the standard `/dispatcher?token=…` route, wait for the app to navigate away, then answer marketing consent (see below). Options: `{ dispatcherPath?, waitUntil?, marketingConsent? }`. |
|
|
74
74
|
| `loginViaSupervisorForm(page, opts)` | Drive the real login form end-to-end — navigate, answer consent, fill user id + key, submit, wait for the landing, then answer marketing consent (see below). Options: `{ baseUrl, userId, pk, path?, expectPath?, timeout?, waitUntil?, consent?, screenshotDir?, marketingConsent? }`. |
|
|
75
|
-
| `answerMarketingConsent(page, opts?)` | Answer the `@owlmeans/web-marketing-consent` full-page step if it is shown right after login. Options: `{ accept?: 'all' \| 'none', timeout? }`, default `accept: 'all'`. Returns whether the step was actually shown and answered — `false` means it never appeared. |
|
|
75
|
+
| `answerMarketingConsent(page, opts?)` | Answer the `@owlmeans/web-marketing-consent` full-page step if it is shown right after login. Options: `{ accept?: 'all' \| 'none' \| 'skip', terms?: 'accept' \| 'leave', timeout? }`, default `accept: 'all'`, `terms: 'accept'`, `timeout: 30_000`. Returns whether the step was actually shown and answered — `false` means it never appeared. Throws if a Terms box could not be confirmed. |
|
|
76
76
|
|
|
77
77
|
These need a project whose backend trusts the private key they sign with, so they belong to specs
|
|
78
78
|
that run against a real app rather than a mounted component. See `[[supervisor-auth]]` for the
|
|
@@ -314,16 +314,23 @@ dialog itself.
|
|
|
314
314
|
## `answerMarketingConsent` — cheap absence detection, unlike the cookie dialog
|
|
315
315
|
|
|
316
316
|
`loginViaSupervisorForm` and `loginViaDispatcher` both call `answerMarketingConsent(page, { accept:
|
|
317
|
-
'all' })` right after they confirm the app has navigated away from login/dispatch,
|
|
318
|
-
`
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
`
|
|
322
|
-
|
|
323
|
-
`
|
|
317
|
+
'all', timeout })` right after they confirm the app has navigated away from login/dispatch, passing
|
|
318
|
+
their **own** `timeout` through explicitly rather than relying on this helper's internal default —
|
|
319
|
+
both of them already budget more than one round trip (login + terms + items) into the value they
|
|
320
|
+
pick. Both also default `marketingConsent` (their own option, not `answerMarketingConsent`'s) to
|
|
321
|
+
`'save'` — pass `'ignore'` to skip the call in a spec that drives the step itself.
|
|
322
|
+
`@owlmeans/web-marketing-consent` renders a full-page step, when shown, with `[data-marketing-consent]`
|
|
323
|
+
(root, carrying `data-state="loading"` while its status read is outstanding and `"ready"` once it can
|
|
324
|
+
render), `[data-marketing-consent-terms]` (the Terms checkbox, Terms mode only, with `data-version`),
|
|
325
|
+
`[data-marketing-consent-terms-error]` (Terms record failed — the person stays and retries),
|
|
326
|
+
`[data-marketing-consent-all]` (select-all, never ticks Terms), `[data-marketing-consent-item="<key>"]`
|
|
327
|
+
(per-consent), `[data-marketing-consent-save]`, `[data-marketing-consent-skip]` (shown whenever the
|
|
328
|
+
step is optional-only — i.e. `!loading && !terms.needed` — not only after a failed save),
|
|
329
|
+
`[data-marketing-consent-skip-note]`, `[data-marketing-consent-signout]` (shown while a Terms box or
|
|
330
|
+
the loading state is up) and `[data-marketing-consent-error]`.
|
|
324
331
|
|
|
325
332
|
Unlike `acceptConsent`, whose `false` return deliberately costs the full wait (see above),
|
|
326
|
-
`answerMarketingConsent` does NOT pay the full `timeout` (default `
|
|
333
|
+
`answerMarketingConsent` does NOT pay the full `timeout` (default `30_000`) when the step is absent.
|
|
327
334
|
The screen is opt-in per app and most applications and environments don't have it wired in yet, and this helper
|
|
328
335
|
is called unconditionally by both login helpers — a full-timeout tax on every login, on every app,
|
|
329
336
|
whether or not the screen exists, would be an unacceptable regression to every existing suite. It
|
|
@@ -333,7 +340,27 @@ instead races `[data-marketing-consent]` against the generic "the app has alread
|
|
|
333
340
|
`loginViaSupervisorForm` uses for its own dialog-vs-form race. By the time a login helper calls this,
|
|
334
341
|
one of those markers has typically already rendered, so on an app without the screen the race
|
|
335
342
|
resolves as soon as it does — no fixed sleep, and no meaningful added latency over what the login
|
|
336
|
-
helper already paid to get there.
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
343
|
+
helper already paid to get there.
|
|
344
|
+
|
|
345
|
+
Once the step's root is present, it may still be `data-state="loading"` (its own status read is
|
|
346
|
+
outstanding) — the helper races that attribute clearing against the whole root detaching on its own
|
|
347
|
+
(nothing was pending, so it auto-continued while this waited), via two `page.waitForSelector` calls
|
|
348
|
+
rather than an in-page `waitForFunction`/`evaluate` (this package's `tsconfig` has no `lib: dom`, so
|
|
349
|
+
no TS runs inside the browser context here). An older `web-marketing-consent` that predates
|
|
350
|
+
`data-state` entirely satisfies the "not loading" selector immediately, so this costs nothing there.
|
|
351
|
+
|
|
352
|
+
When a Terms box is present, `opts.terms` (default `'accept'`) ticks it before saving; `'leave'`
|
|
353
|
+
keeps it unticked, for a spec that means to exercise the blocked state itself — the confirm click
|
|
354
|
+
still fires (with `{ force: true }`, since the control is never natively `disabled`), and the helper
|
|
355
|
+
then *expects* the box to still be up afterward. `opts.accept` (default `'all'`) additionally clicks
|
|
356
|
+
select-all when present, `'none'` saves with every item unchecked, and `'skip'` clicks
|
|
357
|
+
`[data-marketing-consent-skip]` instead of saving — valid only when no Terms box is on screen.
|
|
358
|
+
|
|
359
|
+
Returns `false` when the step never appeared. Otherwise it **throws** in two cases rather than
|
|
360
|
+
silently swallowing them: a `[data-marketing-consent-terms-error]` after attempting to confirm
|
|
361
|
+
Terms, and a Terms box still on screen after a failed/blocked confirm (Skip is never offered there
|
|
362
|
+
on purpose, so there is no fallback and no honest way to report success). Short of those, it returns
|
|
363
|
+
`true` whether the save succeeded outright or fell back to clicking
|
|
364
|
+
`[data-marketing-consent-skip]` after a save error on an optional-only screen (logged as a console
|
|
365
|
+
warning, never thrown) — the step is "answered" either way, so a spec is never permanently blocked
|
|
366
|
+
behind a flaky save.
|
|
@@ -3,9 +3,18 @@ export interface AnswerMarketingConsentOptions {
|
|
|
3
3
|
/**
|
|
4
4
|
* Which choice to save when the step is shown. `'all'` (the default) ticks the "select all"
|
|
5
5
|
* checkbox before saving; `'none'` saves with every item left unchecked, which is a valid,
|
|
6
|
-
* fully-compliant state on its own
|
|
6
|
+
* fully-compliant state on its own; `'skip'` clicks "Skip for now" instead of saving anything —
|
|
7
|
+
* only valid when a Terms box is not on screen (nothing calls it there; see {@link terms}).
|
|
7
8
|
*/
|
|
8
|
-
accept?: 'none' | 'all';
|
|
9
|
+
accept?: 'none' | 'all' | 'skip';
|
|
10
|
+
/**
|
|
11
|
+
* When a Terms box is on screen (`appendMarketingConsent({ terms: 'step' })`), `'accept'` (the
|
|
12
|
+
* default) ticks it before saving. `'leave'` leaves it unticked — for a spec that means to drive
|
|
13
|
+
* the blocked state itself; the confirm click below still fires (with `{ force: true }`, since
|
|
14
|
+
* the control is never truly `disabled`), and this helper then EXPECTS the box to still be up
|
|
15
|
+
* afterward rather than treating that as a failure.
|
|
16
|
+
*/
|
|
17
|
+
terms?: 'accept' | 'leave';
|
|
9
18
|
timeout?: number;
|
|
10
19
|
}
|
|
11
20
|
/**
|
|
@@ -26,6 +35,8 @@ export interface AnswerMarketingConsentOptions {
|
|
|
26
35
|
* @returns whether the step was actually shown and answered (including the error/skip fallback
|
|
27
36
|
* below); `false` when it never appeared within `timeout`, which is the expected result everywhere
|
|
28
37
|
* the screen is not yet configured or the visitor already has saved consents.
|
|
38
|
+
* @throws if a Terms box could not be confirmed (a `[data-marketing-consent-terms-error]`, or the
|
|
39
|
+
* box is still up with nowhere left to go — Skip is never offered there on purpose).
|
|
29
40
|
*/
|
|
30
41
|
export declare const answerMarketingConsent: (page: Page, opts?: AnswerMarketingConsentOptions) => Promise<boolean>;
|
|
31
42
|
//# sourceMappingURL=marketing-consent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketing-consent.d.ts","sourceRoot":"","sources":["../src/marketing-consent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,WAAW,6BAA6B;IAC5C
|
|
1
|
+
{"version":3,"file":"marketing-consent.d.ts","sourceRoot":"","sources":["../src/marketing-consent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,WAAW,6BAA6B;IAC5C;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAA;IAChC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAID;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,sBAAsB,SAC3B,IAAI,SAAS,6BAA6B,KAC/C,OAAO,CAAC,OAAO,CA8EjB,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const DEFAULT_MARKETING_CONSENT_TIMEOUT =
|
|
1
|
+
const DEFAULT_MARKETING_CONSENT_TIMEOUT = 30_000;
|
|
2
2
|
/**
|
|
3
3
|
* Answer the marketing-consent full-page step (`@owlmeans/web-marketing-consent`) if it is shown
|
|
4
4
|
* right after login, so a spec driving {@link loginViaSupervisorForm} or {@link loginViaDispatcher}
|
|
@@ -17,6 +17,8 @@ const DEFAULT_MARKETING_CONSENT_TIMEOUT = 6_000;
|
|
|
17
17
|
* @returns whether the step was actually shown and answered (including the error/skip fallback
|
|
18
18
|
* below); `false` when it never appeared within `timeout`, which is the expected result everywhere
|
|
19
19
|
* the screen is not yet configured or the visitor already has saved consents.
|
|
20
|
+
* @throws if a Terms box could not be confirmed (a `[data-marketing-consent-terms-error]`, or the
|
|
21
|
+
* box is still up with nowhere left to go — Skip is never offered there on purpose).
|
|
20
22
|
*/
|
|
21
23
|
export const answerMarketingConsent = async (page, opts) => {
|
|
22
24
|
const timeout = opts?.timeout ?? DEFAULT_MARKETING_CONSENT_TIMEOUT;
|
|
@@ -30,21 +32,59 @@ export const answerMarketingConsent = async (page, opts) => {
|
|
|
30
32
|
}
|
|
31
33
|
if (await step.count() === 0)
|
|
32
34
|
return false;
|
|
35
|
+
// The step's own status read may still be outstanding (`data-state="loading"`) — wait past it,
|
|
36
|
+
// OR notice it already auto-continued (nothing was pending) and detached on its own. An older
|
|
37
|
+
// `web-marketing-consent` that predates `data-state` entirely satisfies the first selector
|
|
38
|
+
// immediately (a missing attribute is never `"loading"`), so this costs nothing there.
|
|
39
|
+
await Promise.race([
|
|
40
|
+
page.waitForSelector('[data-marketing-consent]:not([data-state="loading"])', { timeout }),
|
|
41
|
+
page.waitForSelector('[data-marketing-consent]', { state: 'detached', timeout }),
|
|
42
|
+
]).catch(() => undefined);
|
|
43
|
+
// Nothing was pending — it already auto-continued while this waited.
|
|
44
|
+
if (await step.count() === 0)
|
|
45
|
+
return true;
|
|
46
|
+
const terms = page.locator('[data-marketing-consent-terms]');
|
|
47
|
+
const hasTerms = await terms.count() > 0;
|
|
48
|
+
if (hasTerms && (opts?.terms ?? 'accept') === 'accept') {
|
|
49
|
+
await terms.check();
|
|
50
|
+
}
|
|
51
|
+
if (!hasTerms && opts?.accept === 'skip') {
|
|
52
|
+
await page.locator('[data-marketing-consent-skip]').click();
|
|
53
|
+
await step.waitFor({ state: 'detached', timeout });
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
33
56
|
if ((opts?.accept ?? 'all') === 'all') {
|
|
34
|
-
|
|
57
|
+
const all = page.locator('[data-marketing-consent-all]');
|
|
58
|
+
if (await all.count() > 0) {
|
|
59
|
+
await all.click();
|
|
60
|
+
}
|
|
35
61
|
}
|
|
36
62
|
// 'none' leaves every item unchecked and clicks nothing else before saving.
|
|
37
|
-
|
|
63
|
+
// `{ force: true }`: the confirm is never the native `disabled` — only `aria-disabled` while a
|
|
64
|
+
// Terms box is unticked, or merely styled muted with nothing changed yet — and Playwright's own
|
|
65
|
+
// actionability check honours `aria-disabled`, which this helper deliberately does not.
|
|
66
|
+
await page.locator('[data-marketing-consent-save]').click({ force: true });
|
|
38
67
|
const outcome = await Promise.race([
|
|
39
68
|
step.waitFor({ state: 'detached', timeout }).then(() => 'saved'),
|
|
40
69
|
page.locator('[data-marketing-consent-error]').waitFor({ state: 'visible', timeout })
|
|
41
|
-
.then(() => 'error')
|
|
70
|
+
.then(() => 'error'),
|
|
71
|
+
page.locator('[data-marketing-consent-terms-error]').waitFor({ state: 'visible', timeout })
|
|
72
|
+
.then(() => 'terms-error'),
|
|
42
73
|
]).catch(() => 'error');
|
|
74
|
+
if (outcome === 'terms-error') {
|
|
75
|
+
throw new Error('[@owlmeans/test-ui] the marketing-consent step could not confirm the Terms');
|
|
76
|
+
}
|
|
43
77
|
if (outcome !== 'saved') {
|
|
44
78
|
const skip = page.locator('[data-marketing-consent-skip]');
|
|
45
79
|
if (await skip.count() > 0) {
|
|
46
80
|
console.warn('[@owlmeans/test-ui] marketing consent save did not complete; using the skip link instead');
|
|
47
81
|
await skip.click();
|
|
82
|
+
await step.waitFor({ state: 'detached', timeout }).catch(() => undefined);
|
|
83
|
+
}
|
|
84
|
+
else if (await terms.count() > 0) {
|
|
85
|
+
// No Skip is ever offered while the Terms box is up — a failed/blocked confirm here has no
|
|
86
|
+
// fallback, and silently returning would hide a caller stuck behind a real requirement.
|
|
87
|
+
throw new Error('[@owlmeans/test-ui] the marketing-consent step is still showing its Terms box');
|
|
48
88
|
}
|
|
49
89
|
}
|
|
50
90
|
// Answered either way: saved, or skipped past a flaky save. Never leaves the caller blocked.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketing-consent.js","sourceRoot":"","sources":["../src/marketing-consent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"marketing-consent.js","sourceRoot":"","sources":["../src/marketing-consent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAUrE,MAAM,WAAW,2BAA2B;IAC1C,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,SAAgB,2BAA2B,KAAG,OAAO,CAAC,MAAM,CAe5F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,SACvB,IAAI,WAAW,MAAM,SAAS,MAAM,SACnC;IACL,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,QAAQ,GAAG,kBAAkB,GAAG,MAAM,GAAG,aAAa,CAAA;IAC3F;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;CACrC,KACA,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAUrE,MAAM,WAAW,2BAA2B;IAC1C,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,SAAgB,2BAA2B,KAAG,OAAO,CAAC,MAAM,CAe5F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,SACvB,IAAI,WAAW,MAAM,SAAS,MAAM,SACnC;IACL,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,QAAQ,GAAG,kBAAkB,GAAG,MAAM,GAAG,aAAa,CAAA;IAC3F;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;CACrC,KACA,OAAO,CAAC,IAAI,CAYd,CAAA;AAED,MAAM,WAAW,wBAAwB;IACvC,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAA;IACV,kDAAkD;IAClD,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACnE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB;AAgBD;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,SACjC,wBAAwB,KAC7B,OAAO,CAAC,MAAM,CAkChB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAAgB,IAAI,OAAO,MAAM,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAM1F,CAAA;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAA;IACV,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kGAAkG;IAClG,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,kBAAkB,GAAG,MAAM,GAAG,aAAa,CAAA;IAClE;;;;OAIG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC7B,2FAA2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;CACrC;AAID;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,SAClB,IAAI,SAAS;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KACtC,OAAO,CAAC,OAAO,CAajB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,SAC3B,IAAI,QAAQ,0BAA0B,KAC3C,OAAO,CAAC,IAAI,CAuCd,CAAA"}
|
package/build/supervisor.js
CHANGED
|
@@ -44,8 +44,9 @@ export const loginViaDispatcher = async (page, baseUrl, token, opts) => {
|
|
|
44
44
|
await page.goto(url.toString(), { waitUntil: opts?.waitUntil ?? 'domcontentloaded' });
|
|
45
45
|
// Wait until the dispatcher has navigated away (token consumed).
|
|
46
46
|
await page.waitForURL(u => !u.pathname.startsWith(path), { timeout: 30_000 });
|
|
47
|
-
if (opts?.marketingConsent !== 'ignore')
|
|
48
|
-
await answerMarketingConsent(page, { accept: 'all' });
|
|
47
|
+
if (opts?.marketingConsent !== 'ignore') {
|
|
48
|
+
await answerMarketingConsent(page, { accept: 'all', timeout: 30_000 });
|
|
49
|
+
}
|
|
49
50
|
};
|
|
50
51
|
const postJson = async (fetchImpl, url, body) => {
|
|
51
52
|
const res = await fetchImpl(url, {
|
|
@@ -175,7 +176,11 @@ export const loginViaSupervisorForm = async (page, opts) => {
|
|
|
175
176
|
else {
|
|
176
177
|
await page.waitForURL(url => !url.pathname.startsWith(path), { timeout });
|
|
177
178
|
}
|
|
179
|
+
// Carries the CALLER's own budget rather than the helper's smaller internal default — a slow
|
|
180
|
+
// cold environment (vite re-optimizing, a stage pod still warming) can easily spend most of a
|
|
181
|
+
// short fixed timeout just getting here, leaving too little for the two extra POSTs (terms, then
|
|
182
|
+
// items) a Terms-mode step now makes.
|
|
178
183
|
if (opts.marketingConsent !== 'ignore')
|
|
179
|
-
await answerMarketingConsent(page, { accept: 'all' });
|
|
184
|
+
await answerMarketingConsent(page, { accept: 'all', timeout });
|
|
180
185
|
};
|
|
181
186
|
//# sourceMappingURL=supervisor.js.map
|
package/build/supervisor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGzC,OAAO,EACL,iBAAiB,EAAE,QAAQ,IAAI,IAAI,EAAE,kBAAkB,EAAE,sBAAsB,EAChF,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAmB/D;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAiC,EAAmB,EAAE;IAC/F,MAAM,IAAI,GAAS;QACjB,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM;QACxC,UAAU,EAAE,IAAI,CAAC,QAAQ;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC;QAC5B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;QAC5B,IAAI,EAAE,iBAAiB,CAAC,iBAAiB;QACzC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;QACzB,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAA;IAED,OAAO,UAAU,CAAC,IAAI,EAAE,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;AACpD,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,IAAU,EAAE,OAAe,EAAE,KAAa,EAC1C,IAQC,EACc,EAAE;IACjB,MAAM,IAAI,GAAG,IAAI,EAAE,cAAc,IAAI,aAAa,CAAA;IAClD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACpC,kGAAkG;IAClG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,kBAAkB,EAAE,CAAC,CAAA;IACrF,iEAAiE;IACjE,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;IAE7E,IAAI,IAAI,EAAE,gBAAgB,KAAK,QAAQ;
|
|
1
|
+
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/test-ui",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.39",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"./harness": "./harness/index.html"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
26
|
-
"@owlmeans/basic-envelope": "^0.1.18-rc.
|
|
25
|
+
"@owlmeans/auth": "^0.1.18-rc.36",
|
|
26
|
+
"@owlmeans/basic-envelope": "^0.1.18-rc.37",
|
|
27
27
|
"@owlmeans/basic-ids": "^0.1.18-rc.33",
|
|
28
|
-
"@owlmeans/basic-keys": "^0.1.18-rc.
|
|
28
|
+
"@owlmeans/basic-keys": "^0.1.18-rc.39",
|
|
29
29
|
"@owlmeans/test": "^0.1.18-rc.32",
|
|
30
|
-
"@owlmeans/test-auth": "^0.1.18-rc.
|
|
30
|
+
"@owlmeans/test-auth": "^0.1.18-rc.37",
|
|
31
31
|
"playwright": "^1.61.1"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
package/src/marketing-consent.ts
CHANGED
|
@@ -4,13 +4,22 @@ export interface AnswerMarketingConsentOptions {
|
|
|
4
4
|
/**
|
|
5
5
|
* Which choice to save when the step is shown. `'all'` (the default) ticks the "select all"
|
|
6
6
|
* checkbox before saving; `'none'` saves with every item left unchecked, which is a valid,
|
|
7
|
-
* fully-compliant state on its own
|
|
7
|
+
* fully-compliant state on its own; `'skip'` clicks "Skip for now" instead of saving anything —
|
|
8
|
+
* only valid when a Terms box is not on screen (nothing calls it there; see {@link terms}).
|
|
8
9
|
*/
|
|
9
|
-
accept?: 'none' | 'all'
|
|
10
|
+
accept?: 'none' | 'all' | 'skip'
|
|
11
|
+
/**
|
|
12
|
+
* When a Terms box is on screen (`appendMarketingConsent({ terms: 'step' })`), `'accept'` (the
|
|
13
|
+
* default) ticks it before saving. `'leave'` leaves it unticked — for a spec that means to drive
|
|
14
|
+
* the blocked state itself; the confirm click below still fires (with `{ force: true }`, since
|
|
15
|
+
* the control is never truly `disabled`), and this helper then EXPECTS the box to still be up
|
|
16
|
+
* afterward rather than treating that as a failure.
|
|
17
|
+
*/
|
|
18
|
+
terms?: 'accept' | 'leave'
|
|
10
19
|
timeout?: number
|
|
11
20
|
}
|
|
12
21
|
|
|
13
|
-
const DEFAULT_MARKETING_CONSENT_TIMEOUT =
|
|
22
|
+
const DEFAULT_MARKETING_CONSENT_TIMEOUT = 30_000
|
|
14
23
|
|
|
15
24
|
/**
|
|
16
25
|
* Answer the marketing-consent full-page step (`@owlmeans/web-marketing-consent`) if it is shown
|
|
@@ -30,6 +39,8 @@ const DEFAULT_MARKETING_CONSENT_TIMEOUT = 6_000
|
|
|
30
39
|
* @returns whether the step was actually shown and answered (including the error/skip fallback
|
|
31
40
|
* below); `false` when it never appeared within `timeout`, which is the expected result everywhere
|
|
32
41
|
* the screen is not yet configured or the visitor already has saved consents.
|
|
42
|
+
* @throws if a Terms box could not be confirmed (a `[data-marketing-consent-terms-error]`, or the
|
|
43
|
+
* box is still up with nowhere left to go — Skip is never offered there on purpose).
|
|
33
44
|
*/
|
|
34
45
|
export const answerMarketingConsent = async (
|
|
35
46
|
page: Page, opts?: AnswerMarketingConsentOptions
|
|
@@ -46,24 +57,66 @@ export const answerMarketingConsent = async (
|
|
|
46
57
|
|
|
47
58
|
if (await step.count() === 0) return false
|
|
48
59
|
|
|
60
|
+
// The step's own status read may still be outstanding (`data-state="loading"`) — wait past it,
|
|
61
|
+
// OR notice it already auto-continued (nothing was pending) and detached on its own. An older
|
|
62
|
+
// `web-marketing-consent` that predates `data-state` entirely satisfies the first selector
|
|
63
|
+
// immediately (a missing attribute is never `"loading"`), so this costs nothing there.
|
|
64
|
+
await Promise.race([
|
|
65
|
+
page.waitForSelector('[data-marketing-consent]:not([data-state="loading"])', { timeout }),
|
|
66
|
+
page.waitForSelector('[data-marketing-consent]', { state: 'detached', timeout }),
|
|
67
|
+
]).catch(() => undefined)
|
|
68
|
+
|
|
69
|
+
// Nothing was pending — it already auto-continued while this waited.
|
|
70
|
+
if (await step.count() === 0) return true
|
|
71
|
+
|
|
72
|
+
const terms = page.locator('[data-marketing-consent-terms]')
|
|
73
|
+
const hasTerms = await terms.count() > 0
|
|
74
|
+
if (hasTerms && (opts?.terms ?? 'accept') === 'accept') {
|
|
75
|
+
await terms.check()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!hasTerms && opts?.accept === 'skip') {
|
|
79
|
+
await page.locator('[data-marketing-consent-skip]').click()
|
|
80
|
+
await step.waitFor({ state: 'detached', timeout })
|
|
81
|
+
|
|
82
|
+
return true
|
|
83
|
+
}
|
|
84
|
+
|
|
49
85
|
if ((opts?.accept ?? 'all') === 'all') {
|
|
50
|
-
|
|
86
|
+
const all = page.locator('[data-marketing-consent-all]')
|
|
87
|
+
if (await all.count() > 0) {
|
|
88
|
+
await all.click()
|
|
89
|
+
}
|
|
51
90
|
}
|
|
52
91
|
// 'none' leaves every item unchecked and clicks nothing else before saving.
|
|
53
92
|
|
|
54
|
-
|
|
93
|
+
// `{ force: true }`: the confirm is never the native `disabled` — only `aria-disabled` while a
|
|
94
|
+
// Terms box is unticked, or merely styled muted with nothing changed yet — and Playwright's own
|
|
95
|
+
// actionability check honours `aria-disabled`, which this helper deliberately does not.
|
|
96
|
+
await page.locator('[data-marketing-consent-save]').click({ force: true })
|
|
55
97
|
|
|
56
98
|
const outcome = await Promise.race([
|
|
57
99
|
step.waitFor({ state: 'detached', timeout }).then(() => 'saved' as const),
|
|
58
100
|
page.locator('[data-marketing-consent-error]').waitFor({ state: 'visible', timeout })
|
|
59
|
-
.then(() => 'error' as const)
|
|
101
|
+
.then(() => 'error' as const),
|
|
102
|
+
page.locator('[data-marketing-consent-terms-error]').waitFor({ state: 'visible', timeout })
|
|
103
|
+
.then(() => 'terms-error' as const),
|
|
60
104
|
]).catch(() => 'error' as const)
|
|
61
105
|
|
|
106
|
+
if (outcome === 'terms-error') {
|
|
107
|
+
throw new Error('[@owlmeans/test-ui] the marketing-consent step could not confirm the Terms')
|
|
108
|
+
}
|
|
109
|
+
|
|
62
110
|
if (outcome !== 'saved') {
|
|
63
111
|
const skip = page.locator('[data-marketing-consent-skip]')
|
|
64
112
|
if (await skip.count() > 0) {
|
|
65
113
|
console.warn('[@owlmeans/test-ui] marketing consent save did not complete; using the skip link instead')
|
|
66
114
|
await skip.click()
|
|
115
|
+
await step.waitFor({ state: 'detached', timeout }).catch(() => undefined)
|
|
116
|
+
} else if (await terms.count() > 0) {
|
|
117
|
+
// No Skip is ever offered while the Terms box is up — a failed/blocked confirm here has no
|
|
118
|
+
// fallback, and silently returning would hide a caller stuck behind a real requirement.
|
|
119
|
+
throw new Error('[@owlmeans/test-ui] the marketing-consent step is still showing its Terms box')
|
|
67
120
|
}
|
|
68
121
|
}
|
|
69
122
|
|
package/src/supervisor.ts
CHANGED
|
@@ -80,7 +80,9 @@ export const loginViaDispatcher = async (
|
|
|
80
80
|
// Wait until the dispatcher has navigated away (token consumed).
|
|
81
81
|
await page.waitForURL(u => !u.pathname.startsWith(path), { timeout: 30_000 })
|
|
82
82
|
|
|
83
|
-
if (opts?.marketingConsent !== 'ignore')
|
|
83
|
+
if (opts?.marketingConsent !== 'ignore') {
|
|
84
|
+
await answerMarketingConsent(page, { accept: 'all', timeout: 30_000 })
|
|
85
|
+
}
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
export interface SupervisorApiAuthOptions {
|
|
@@ -283,5 +285,9 @@ export const loginViaSupervisorForm = async (
|
|
|
283
285
|
await page.waitForURL(url => !url.pathname.startsWith(path), { timeout })
|
|
284
286
|
}
|
|
285
287
|
|
|
286
|
-
|
|
288
|
+
// Carries the CALLER's own budget rather than the helper's smaller internal default — a slow
|
|
289
|
+
// cold environment (vite re-optimizing, a stage pod still warming) can easily spend most of a
|
|
290
|
+
// short fixed timeout just getting here, leaving too little for the two extra POSTs (terms, then
|
|
291
|
+
// items) a Terms-mode step now makes.
|
|
292
|
+
if (opts.marketingConsent !== 'ignore') await answerMarketingConsent(page, { accept: 'all', timeout })
|
|
287
293
|
}
|