@owlmeans/test-ui 0.1.18-rc.35 → 0.1.18-rc.37

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 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.34
61
+ npx @owlmeans/agent-skills@^0.1.18-rc.36
62
62
  ```
63
63
 
64
64
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/test-ui",
4
- "version": "0.1.18-rc.35",
5
- "generatedAt": "2026-09-22T20:45:24.040Z",
4
+ "version": "0.1.18-rc.37",
5
+ "generatedAt": "2026-09-22T22:24:39.521Z",
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.35"` in `devDependencies`
9
+ **Install:** `"@owlmeans/test-ui": "^0.1.18-rc.37"` 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
@@ -70,8 +70,9 @@ sits behind auth without hand-rolling a token:
70
70
  |---|---|
71
71
  | `pregenerateAuthToken(opts)` | Mint an `ED25519-BASIC-TOKEN …` bearer offline from a trusted private key — no browser, no round trip. Options: `{ userId, pk, scopes?, role?, entityId?, profileId?, source? }`. |
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
- | `loginViaDispatcher(page, baseUrl, token, opts?)` | Inject a bearer through the standard `/dispatcher?token=…` route and wait for the app to navigate away. |
74
- | `loginViaSupervisorForm(page, opts)` | Drive the real login form end-to-end — navigate, answer consent, fill user id + key, submit, wait for the landing. Options: `{ baseUrl, userId, pk, path?, expectPath?, timeout?, waitUntil?, consent?, screenshotDir? }`. |
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
+ | `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
76
 
76
77
  These need a project whose backend trusts the private key they sign with, so they belong to specs
77
78
  that run against a real app rather than a mounted component. See `[[supervisor-auth]]` for the
@@ -309,3 +310,30 @@ app that ships no consent widget the login helper therefore sits for a full minu
309
310
  the first field, with nothing on screen to explain it. Drive such an app with `consent: 'ignore'`,
310
311
  which skips the call entirely; that is also the switch a spec flips when it wants to answer the
311
312
  dialog itself.
313
+
314
+ ## `answerMarketingConsent` — cheap absence detection, unlike the cookie dialog
315
+
316
+ `loginViaSupervisorForm` and `loginViaDispatcher` both call `answerMarketingConsent(page, { accept:
317
+ 'all' })` right after they confirm the app has navigated away from login/dispatch, and both default
318
+ `marketingConsent` (their own option, not `answerMarketingConsent`'s) to `'save'` — pass
319
+ `'ignore'` to skip the call in a spec that drives the step itself. `@owlmeans/web-marketing-consent`
320
+ renders a full-page step, when shown, with `[data-marketing-consent]` (root),
321
+ `[data-marketing-consent-all]` (select-all), `[data-marketing-consent-item="<key>"]` (per-consent),
322
+ `[data-marketing-consent-save]`, `[data-marketing-consent-skip]` (shown only after a save error) and
323
+ `[data-marketing-consent-error]`.
324
+
325
+ Unlike `acceptConsent`, whose `false` return deliberately costs the full wait (see above),
326
+ `answerMarketingConsent` does NOT pay the full `timeout` (default `6_000`) when the step is absent.
327
+ The screen is opt-in per app and most applications and environments don't have it wired in yet, and this helper
328
+ is called unconditionally by both login helpers — a full-timeout tax on every login, on every app,
329
+ whether or not the screen exists, would be an unacceptable regression to every existing suite. It
330
+ instead races `[data-marketing-consent]` against the generic "the app has already landed" /
331
+ "still on the login screen" markers the login helpers themselves already rely on (`#app-prompt`,
332
+ `[data-login-method]`) via the same `locator('a, b, c').first().waitFor({ state: 'visible' })` idiom
333
+ `loginViaSupervisorForm` uses for its own dialog-vs-form race. By the time a login helper calls this,
334
+ one of those markers has typically already rendered, so on an app without the screen the race
335
+ 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. Returns `false` when the step never appeared; `true` when it did,
337
+ whether the save succeeded or fell back to clicking `[data-marketing-consent-skip]` after a save
338
+ error (logged as a console warning, never thrown) — the step is "answered" either way, so a spec is
339
+ never permanently blocked behind a flaky save.
package/build/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './browser.js';
2
+ export * from './marketing-consent.js';
2
3
  export * from './mount.js';
3
4
  export * from './supervisor.js';
4
5
  export type { Browser, BrowserContext, Locator, Page } from 'playwright';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,wBAAwB,CAAA;AACtC,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA"}
package/build/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './browser.js';
2
+ export * from './marketing-consent.js';
2
3
  export * from './mount.js';
3
4
  export * from './supervisor.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,wBAAwB,CAAA;AACtC,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA"}
@@ -0,0 +1,31 @@
1
+ import type { Page } from 'playwright';
2
+ export interface AnswerMarketingConsentOptions {
3
+ /**
4
+ * Which choice to save when the step is shown. `'all'` (the default) ticks the "select all"
5
+ * checkbox before saving; `'none'` saves with every item left unchecked, which is a valid,
6
+ * fully-compliant state on its own.
7
+ */
8
+ accept?: 'none' | 'all';
9
+ timeout?: number;
10
+ }
11
+ /**
12
+ * Answer the marketing-consent full-page step (`@owlmeans/web-marketing-consent`) if it is shown
13
+ * right after login, so a spec driving {@link loginViaSupervisorForm} or {@link loginViaDispatcher}
14
+ * is never blocked behind it.
15
+ *
16
+ * The screen is opt-in per app, and most apps/environments will not have it wired in — that makes
17
+ * detecting its ABSENCE cheaply the whole point. A plain `waitFor` on `[data-marketing-consent]`
18
+ * alone would cost the full `timeout` on every login of every app that never renders it (the same
19
+ * caveat `acceptConsent` documents for the cookie dialog). Instead this races the step's own root
20
+ * against the generic OwlMeans "the app has already landed" / "still on the login screen" markers
21
+ * this file's own login helpers already wait on (`#app-prompt`, `[data-login-method]`) — by the
22
+ * time a login helper calls this, one of those has typically already rendered, so the race resolves
23
+ * as soon as it does: no fixed sleep, and in the common "step absent" case, no material added
24
+ * latency over what the login helper already paid to get here.
25
+ *
26
+ * @returns whether the step was actually shown and answered (including the error/skip fallback
27
+ * below); `false` when it never appeared within `timeout`, which is the expected result everywhere
28
+ * the screen is not yet configured or the visitor already has saved consents.
29
+ */
30
+ export declare const answerMarketingConsent: (page: Page, opts?: AnswerMarketingConsentOptions) => Promise<boolean>;
31
+ //# sourceMappingURL=marketing-consent.d.ts.map
@@ -0,0 +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;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sBAAsB,SAC3B,IAAI,SAAS,6BAA6B,KAC/C,OAAO,CAAC,OAAO,CAoCjB,CAAA"}
@@ -0,0 +1,53 @@
1
+ const DEFAULT_MARKETING_CONSENT_TIMEOUT = 6_000;
2
+ /**
3
+ * Answer the marketing-consent full-page step (`@owlmeans/web-marketing-consent`) if it is shown
4
+ * right after login, so a spec driving {@link loginViaSupervisorForm} or {@link loginViaDispatcher}
5
+ * is never blocked behind it.
6
+ *
7
+ * The screen is opt-in per app, and most apps/environments will not have it wired in — that makes
8
+ * detecting its ABSENCE cheaply the whole point. A plain `waitFor` on `[data-marketing-consent]`
9
+ * alone would cost the full `timeout` on every login of every app that never renders it (the same
10
+ * caveat `acceptConsent` documents for the cookie dialog). Instead this races the step's own root
11
+ * against the generic OwlMeans "the app has already landed" / "still on the login screen" markers
12
+ * this file's own login helpers already wait on (`#app-prompt`, `[data-login-method]`) — by the
13
+ * time a login helper calls this, one of those has typically already rendered, so the race resolves
14
+ * as soon as it does: no fixed sleep, and in the common "step absent" case, no material added
15
+ * latency over what the login helper already paid to get here.
16
+ *
17
+ * @returns whether the step was actually shown and answered (including the error/skip fallback
18
+ * below); `false` when it never appeared within `timeout`, which is the expected result everywhere
19
+ * the screen is not yet configured or the visitor already has saved consents.
20
+ */
21
+ export const answerMarketingConsent = async (page, opts) => {
22
+ const timeout = opts?.timeout ?? DEFAULT_MARKETING_CONSENT_TIMEOUT;
23
+ const step = page.locator('[data-marketing-consent]');
24
+ try {
25
+ await page.locator('[data-marketing-consent], #app-prompt, [data-login-method]')
26
+ .first().waitFor({ state: 'visible', timeout });
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ if (await step.count() === 0)
32
+ return false;
33
+ if ((opts?.accept ?? 'all') === 'all') {
34
+ await page.locator('[data-marketing-consent-all]').click();
35
+ }
36
+ // 'none' leaves every item unchecked and clicks nothing else before saving.
37
+ await page.locator('[data-marketing-consent-save]').click();
38
+ const outcome = await Promise.race([
39
+ step.waitFor({ state: 'detached', timeout }).then(() => 'saved'),
40
+ page.locator('[data-marketing-consent-error]').waitFor({ state: 'visible', timeout })
41
+ .then(() => 'error')
42
+ ]).catch(() => 'error');
43
+ if (outcome !== 'saved') {
44
+ const skip = page.locator('[data-marketing-consent-skip]');
45
+ if (await skip.count() > 0) {
46
+ console.warn('[@owlmeans/test-ui] marketing consent save did not complete; using the skip link instead');
47
+ await skip.click();
48
+ }
49
+ }
50
+ // Answered either way: saved, or skipped past a flaky save. Never leaves the caller blocked.
51
+ return true;
52
+ };
53
+ //# sourceMappingURL=marketing-consent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketing-consent.js","sourceRoot":"","sources":["../src/marketing-consent.ts"],"names":[],"mappings":"AAYA,MAAM,iCAAiC,GAAG,KAAK,CAAA;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EACzC,IAAU,EAAE,IAAoC,EAC9B,EAAE;IACpB,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,iCAAiC,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAA;IAErD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,CAAC,4DAA4D,CAAC;aAC7E,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAA;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAE1C,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;QACtC,MAAM,IAAI,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,KAAK,EAAE,CAAA;IAC5D,CAAC;IACD,4EAA4E;IAE5E,MAAM,IAAI,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,KAAK,EAAE,CAAA;IAE3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAgB,CAAC;QACzE,IAAI,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;aAClF,IAAI,CAAC,GAAG,EAAE,CAAC,OAAgB,CAAC;KAChC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAgB,CAAC,CAAA;IAEhC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAA;QAC1D,IAAI,MAAM,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,0FAA0F,CAAC,CAAA;YACxG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC;IACH,CAAC;IAED,6FAA6F;IAC7F,OAAO,IAAI,CAAA;AACb,CAAC,CAAA"}
@@ -35,6 +35,12 @@ export declare const pregenerateAuthToken: (opts: PregenerateAuthTokenOptions) =
35
35
  export declare const loginViaDispatcher: (page: Page, baseUrl: string, token: string, opts?: {
36
36
  dispatcherPath?: string;
37
37
  waitUntil?: 'commit' | 'domcontentloaded' | 'load' | 'networkidle';
38
+ /**
39
+ * Answer the marketing-consent step if it is shown right after the dispatcher navigates away.
40
+ * Defaults to `'save'` (select-all and save) — see {@link answerMarketingConsent}. Pass
41
+ * `'ignore'` to skip the call entirely, e.g. in a spec that answers the step itself.
42
+ */
43
+ marketingConsent?: 'save' | 'ignore';
38
44
  }) => Promise<void>;
39
45
  export interface SupervisorApiAuthOptions {
40
46
  /** Auth-manager API base URL (the backend serving /authentication/* and /authenticate). */
@@ -96,6 +102,12 @@ export interface SupervisorFormLoginOptions {
96
102
  consent?: 'accept' | 'ignore';
97
103
  /** When set, capture the filled login form (`supervisor-login-form.png`) before submit. */
98
104
  screenshotDir?: string;
105
+ /**
106
+ * Answer the marketing-consent step if it is shown right after landing. Defaults to `'save'`
107
+ * (select-all and save) — see {@link answerMarketingConsent}. Pass `'ignore'` to skip the call
108
+ * entirely, e.g. in a spec that answers the step itself.
109
+ */
110
+ marketingConsent?: 'save' | 'ignore';
99
111
  }
100
112
  /**
101
113
  * Answer the cookie-consent dialog if one is up, so the page underneath can be driven.
@@ -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;AASrE,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;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,QAAQ,GAAG,kBAAkB,GAAG,MAAM,GAAG,aAAa,CAAA;CAAE,KACrG,OAAO,CAAC,IAAI,CAQd,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;CACvB;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,CAiCd,CAAA"}
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,CAUd,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,CAmCd,CAAA"}
@@ -5,6 +5,7 @@ import { makeKeyPairModel } from '@owlmeans/basic-keys';
5
5
  import { createIdOfLength } from '@owlmeans/basic-ids';
6
6
  import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope';
7
7
  import { makeBearer } from '@owlmeans/test-auth';
8
+ import { answerMarketingConsent } from './marketing-consent.js';
8
9
  /**
9
10
  * Mint a ready-to-use `ED25519-BASIC-TOKEN ...` bearer offline, reusing
10
11
  * `@owlmeans/test-auth`'s `makeBearer`. This is the "set a token directly"
@@ -43,6 +44,8 @@ export const loginViaDispatcher = async (page, baseUrl, token, opts) => {
43
44
  await page.goto(url.toString(), { waitUntil: opts?.waitUntil ?? 'domcontentloaded' });
44
45
  // Wait until the dispatcher has navigated away (token consumed).
45
46
  await page.waitForURL(u => !u.pathname.startsWith(path), { timeout: 30_000 });
47
+ if (opts?.marketingConsent !== 'ignore')
48
+ await answerMarketingConsent(page, { accept: 'all' });
46
49
  };
47
50
  const postJson = async (fetchImpl, url, body) => {
48
51
  const res = await fetchImpl(url, {
@@ -172,5 +175,7 @@ export const loginViaSupervisorForm = async (page, opts) => {
172
175
  else {
173
176
  await page.waitForURL(url => !url.pathname.startsWith(path), { timeout });
174
177
  }
178
+ if (opts.marketingConsent !== 'ignore')
179
+ await answerMarketingConsent(page, { accept: 'all' });
175
180
  };
176
181
  //# sourceMappingURL=supervisor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"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"}
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.35",
3
+ "version": "0.1.18-rc.37",
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.32",
26
- "@owlmeans/basic-envelope": "^0.1.18-rc.33",
27
- "@owlmeans/basic-ids": "^0.1.18-rc.31",
28
- "@owlmeans/basic-keys": "^0.1.18-rc.35",
29
- "@owlmeans/test": "^0.1.18-rc.30",
30
- "@owlmeans/test-auth": "^0.1.18-rc.33",
25
+ "@owlmeans/auth": "^0.1.18-rc.34",
26
+ "@owlmeans/basic-envelope": "^0.1.18-rc.35",
27
+ "@owlmeans/basic-ids": "^0.1.18-rc.33",
28
+ "@owlmeans/basic-keys": "^0.1.18-rc.37",
29
+ "@owlmeans/test": "^0.1.18-rc.32",
30
+ "@owlmeans/test-auth": "^0.1.18-rc.35",
31
31
  "playwright": "^1.61.1"
32
32
  },
33
33
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './browser.js'
2
+ export * from './marketing-consent.js'
2
3
  export * from './mount.js'
3
4
  export * from './supervisor.js'
4
5
  export type { Browser, BrowserContext, Locator, Page } from 'playwright'
@@ -0,0 +1,72 @@
1
+ import type { Page } from 'playwright'
2
+
3
+ export interface AnswerMarketingConsentOptions {
4
+ /**
5
+ * Which choice to save when the step is shown. `'all'` (the default) ticks the "select all"
6
+ * checkbox before saving; `'none'` saves with every item left unchecked, which is a valid,
7
+ * fully-compliant state on its own.
8
+ */
9
+ accept?: 'none' | 'all'
10
+ timeout?: number
11
+ }
12
+
13
+ const DEFAULT_MARKETING_CONSENT_TIMEOUT = 6_000
14
+
15
+ /**
16
+ * Answer the marketing-consent full-page step (`@owlmeans/web-marketing-consent`) if it is shown
17
+ * right after login, so a spec driving {@link loginViaSupervisorForm} or {@link loginViaDispatcher}
18
+ * is never blocked behind it.
19
+ *
20
+ * The screen is opt-in per app, and most apps/environments will not have it wired in — that makes
21
+ * detecting its ABSENCE cheaply the whole point. A plain `waitFor` on `[data-marketing-consent]`
22
+ * alone would cost the full `timeout` on every login of every app that never renders it (the same
23
+ * caveat `acceptConsent` documents for the cookie dialog). Instead this races the step's own root
24
+ * against the generic OwlMeans "the app has already landed" / "still on the login screen" markers
25
+ * this file's own login helpers already wait on (`#app-prompt`, `[data-login-method]`) — by the
26
+ * time a login helper calls this, one of those has typically already rendered, so the race resolves
27
+ * as soon as it does: no fixed sleep, and in the common "step absent" case, no material added
28
+ * latency over what the login helper already paid to get here.
29
+ *
30
+ * @returns whether the step was actually shown and answered (including the error/skip fallback
31
+ * below); `false` when it never appeared within `timeout`, which is the expected result everywhere
32
+ * the screen is not yet configured or the visitor already has saved consents.
33
+ */
34
+ export const answerMarketingConsent = async (
35
+ page: Page, opts?: AnswerMarketingConsentOptions
36
+ ): Promise<boolean> => {
37
+ const timeout = opts?.timeout ?? DEFAULT_MARKETING_CONSENT_TIMEOUT
38
+ const step = page.locator('[data-marketing-consent]')
39
+
40
+ try {
41
+ await page.locator('[data-marketing-consent], #app-prompt, [data-login-method]')
42
+ .first().waitFor({ state: 'visible', timeout })
43
+ } catch {
44
+ return false
45
+ }
46
+
47
+ if (await step.count() === 0) return false
48
+
49
+ if ((opts?.accept ?? 'all') === 'all') {
50
+ await page.locator('[data-marketing-consent-all]').click()
51
+ }
52
+ // 'none' leaves every item unchecked and clicks nothing else before saving.
53
+
54
+ await page.locator('[data-marketing-consent-save]').click()
55
+
56
+ const outcome = await Promise.race([
57
+ step.waitFor({ state: 'detached', timeout }).then(() => 'saved' as const),
58
+ page.locator('[data-marketing-consent-error]').waitFor({ state: 'visible', timeout })
59
+ .then(() => 'error' as const)
60
+ ]).catch(() => 'error' as const)
61
+
62
+ if (outcome !== 'saved') {
63
+ const skip = page.locator('[data-marketing-consent-skip]')
64
+ if (await skip.count() > 0) {
65
+ console.warn('[@owlmeans/test-ui] marketing consent save did not complete; using the skip link instead')
66
+ await skip.click()
67
+ }
68
+ }
69
+
70
+ // Answered either way: saved, or skipped past a flaky save. Never leaves the caller blocked.
71
+ return true
72
+ }
package/src/supervisor.ts CHANGED
@@ -9,6 +9,7 @@ import { makeKeyPairModel } from '@owlmeans/basic-keys'
9
9
  import { createIdOfLength } from '@owlmeans/basic-ids'
10
10
  import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope'
11
11
  import { makeBearer } from '@owlmeans/test-auth'
12
+ import { answerMarketingConsent } from './marketing-consent.js'
12
13
 
13
14
  export interface PregenerateAuthTokenOptions {
14
15
  /** Target user id / email the token represents. */
@@ -61,7 +62,15 @@ export const pregenerateAuthToken = async (opts: PregenerateAuthTokenOptions): P
61
62
  */
62
63
  export const loginViaDispatcher = async (
63
64
  page: Page, baseUrl: string, token: string,
64
- opts?: { dispatcherPath?: string, waitUntil?: 'commit' | 'domcontentloaded' | 'load' | 'networkidle' }
65
+ opts?: {
66
+ dispatcherPath?: string, waitUntil?: 'commit' | 'domcontentloaded' | 'load' | 'networkidle'
67
+ /**
68
+ * Answer the marketing-consent step if it is shown right after the dispatcher navigates away.
69
+ * Defaults to `'save'` (select-all and save) — see {@link answerMarketingConsent}. Pass
70
+ * `'ignore'` to skip the call entirely, e.g. in a spec that answers the step itself.
71
+ */
72
+ marketingConsent?: 'save' | 'ignore'
73
+ }
65
74
  ): Promise<void> => {
66
75
  const path = opts?.dispatcherPath ?? '/dispatcher'
67
76
  const url = new URL(path, baseUrl)
@@ -70,6 +79,8 @@ export const loginViaDispatcher = async (
70
79
  await page.goto(url.toString(), { waitUntil: opts?.waitUntil ?? 'domcontentloaded' })
71
80
  // Wait until the dispatcher has navigated away (token consumed).
72
81
  await page.waitForURL(u => !u.pathname.startsWith(path), { timeout: 30_000 })
82
+
83
+ if (opts?.marketingConsent !== 'ignore') await answerMarketingConsent(page, { accept: 'all' })
73
84
  }
74
85
 
75
86
  export interface SupervisorApiAuthOptions {
@@ -187,6 +198,12 @@ export interface SupervisorFormLoginOptions {
187
198
  consent?: 'accept' | 'ignore'
188
199
  /** When set, capture the filled login form (`supervisor-login-form.png`) before submit. */
189
200
  screenshotDir?: string
201
+ /**
202
+ * Answer the marketing-consent step if it is shown right after landing. Defaults to `'save'`
203
+ * (select-all and save) — see {@link answerMarketingConsent}. Pass `'ignore'` to skip the call
204
+ * entirely, e.g. in a spec that answers the step itself.
205
+ */
206
+ marketingConsent?: 'save' | 'ignore'
190
207
  }
191
208
 
192
209
  const DEFAULT_SUPERVISOR_PATH = '/authentication/login/pk-supervisor'
@@ -265,4 +282,6 @@ export const loginViaSupervisorForm = async (
265
282
  } else {
266
283
  await page.waitForURL(url => !url.pathname.startsWith(path), { timeout })
267
284
  }
285
+
286
+ if (opts.marketingConsent !== 'ignore') await answerMarketingConsent(page, { accept: 'all' })
268
287
  }