@unotest/web 0.44.0 → 0.45.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 +39 -3
- package/dist/config/schema.d.ts +191 -39
- package/dist/config/schema.js +1 -1
- package/dist/driver/index.d.ts +9 -2
- package/dist/driver/index.js +1 -1
- package/dist/dsl/index.d.ts +20 -2
- package/dist/dsl/index.js +1 -1
- package/dist/dsl/web-dsl-language-service.js +1 -1
- package/dist/inspection/page-inject.d.ts +1 -1
- package/dist/{interfaces-DEmGI704.d.ts → interfaces-OvnJKELk.d.ts} +148 -5
- package/dist/mcp/server.js +1 -1
- package/dist/runner/cli.js +1 -1
- package/dist/runner/init/chrome-probe.js +1 -1
- package/dist/runner/init.js +1 -1
- package/dist/runner/install-chromium.js +1 -1
- package/dist/runner/prepare-fix.js +1 -1
- package/dist/runner/scaffold-workspace.js +1 -1
- package/dist/runner/serve-fixture.js +1 -1
- package/dist/runner/web-runner-adapter.js +1 -1
- package/guides/dsl-reference.md +413 -1
- package/package.json +8 -8
- package/types/unotest-dsl.d.ts +150 -3
package/types/unotest-dsl.d.ts
CHANGED
|
@@ -238,6 +238,13 @@ declare function assertJudge(locator: Locator, rubric: string): void;
|
|
|
238
238
|
*/
|
|
239
239
|
declare function assertScreenshot(nameOrLocator: any, nameOrOptions?: any, options?: any): void;
|
|
240
240
|
|
|
241
|
+
/**
|
|
242
|
+
* assertEqual(actual, expected)
|
|
243
|
+
*
|
|
244
|
+
* Deep equality as JSON sees it: key order does not count, a missing key differs from a null one. FAILS naming the first differing path (`chat.labels[0].send`) with both values, plus a line diff of the two sides. The DSL form of toEqual.
|
|
245
|
+
*/
|
|
246
|
+
declare function assertEqual(actual: any, expected: any): void;
|
|
247
|
+
|
|
241
248
|
/**
|
|
242
249
|
* assertTrue(condition, message?)
|
|
243
250
|
*
|
|
@@ -302,11 +309,46 @@ declare function note(label: string, value: any): void;
|
|
|
302
309
|
declare function evaluate(jsBody: string, ...args: unknown[]): any;
|
|
303
310
|
|
|
304
311
|
/**
|
|
305
|
-
*
|
|
312
|
+
* evaluateOnLocator(locator, js, ...args) → any
|
|
313
|
+
*
|
|
314
|
+
* Like evaluate, on the matched element: the body is called with the element, then the extra arguments by the same rule (`(el, x) => …`, two or more → `(el, [a, b]) => …`). Last resort — prefer typed getters.
|
|
315
|
+
*/
|
|
316
|
+
declare function evaluateOnLocator(locator: Locator, jsBody: string, ...args: unknown[]): any;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* setPage(index, options?)
|
|
320
|
+
*
|
|
321
|
+
* Switch the active tab/page by index (0-based) and bring it to front. {activate: false} switches only the tab the steps act on and leaves the visible tab as is.
|
|
322
|
+
*/
|
|
323
|
+
declare function setPage(indexOrTitle: string | number, options?: any): void;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* waitForPage(options?) → number
|
|
327
|
+
*
|
|
328
|
+
* Wait for a tab the scenario has not been handed yet (window.open, target=_blank, an extension), switch to it and return its index. Counts a tab that opened before the call. {timeoutMs} defaults to the navigation timeout.
|
|
329
|
+
*/
|
|
330
|
+
declare function waitForPage(options?: any): number;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* bringToFront(index?)
|
|
334
|
+
*
|
|
335
|
+
* Bring a tab to front — the visible one — without changing the tab the steps act on. No index: the active tab.
|
|
336
|
+
*/
|
|
337
|
+
declare function bringToFront(index?: number): void;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* newPage(url?) → number
|
|
341
|
+
*
|
|
342
|
+
* Open a new tab in the active browser context, make it active and return its index. With a url the tab opens it (relative to the base URL, as goto).
|
|
343
|
+
*/
|
|
344
|
+
declare function newPage(url?: string): number;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* closePage(index?)
|
|
306
348
|
*
|
|
307
|
-
*
|
|
349
|
+
* Close a tab; no index: the active one. Closing the active tab makes the tab that was active before it active again. The only open tab cannot be closed.
|
|
308
350
|
*/
|
|
309
|
-
declare function
|
|
351
|
+
declare function closePage(index?: number): void;
|
|
310
352
|
|
|
311
353
|
/**
|
|
312
354
|
* setViewport({width, height})
|
|
@@ -511,6 +553,27 @@ declare function today(): string;
|
|
|
511
553
|
*/
|
|
512
554
|
declare function daysFromNow(days: number): string;
|
|
513
555
|
|
|
556
|
+
/**
|
|
557
|
+
* textMatches(text, /re/) → false | string[]
|
|
558
|
+
*
|
|
559
|
+
* First match of a regex literal: false on a miss, else `[whole, group1, …]` (a group that took no part is null). The array is truthy, so it also reads as a test: `m = textMatches(url, /room=(\d+)/); id = m[1];`. For a plain substring use textContains.
|
|
560
|
+
*/
|
|
561
|
+
declare function textMatches(text: string, pattern: any): any;
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* parseJson(text) → any
|
|
565
|
+
*
|
|
566
|
+
* Parse a JSON string (an api body, a data attribute, a request's postData) into a value you walk with `.` and `[]`. FAILS on invalid JSON, quoting the input; an empty string is not JSON.
|
|
567
|
+
*/
|
|
568
|
+
declare function parseJson(text: string): any;
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* urlParam(url, key) → string | null
|
|
572
|
+
*
|
|
573
|
+
* A query parameter of a URL, decoded; null when the key is absent, '' when it is empty. A path without a host (`/room?id=7`) works too. The DSL form of `new URL(u).searchParams.get(key)`.
|
|
574
|
+
*/
|
|
575
|
+
declare function urlParam(url: string, key: string): any;
|
|
576
|
+
|
|
514
577
|
/**
|
|
515
578
|
* shell(cmd, ...args, options?) → { stdout, stderr, code }
|
|
516
579
|
*
|
|
@@ -553,6 +616,27 @@ declare function assertNoJsonLine(path: string, filter: any, options?: any): voi
|
|
|
553
616
|
*/
|
|
554
617
|
declare function readJsonLine(path: string, filter: any): any;
|
|
555
618
|
|
|
619
|
+
/**
|
|
620
|
+
* readJson(path) → any
|
|
621
|
+
*
|
|
622
|
+
* A whole JSON file, read once and parsed: app constants a build script exported, fixture objects. Path is relative to config `shellCwd` and must stay inside it. FAILS at once when the path leaves the project, the file is missing or it is not valid JSON. Walk the result with `.` and `[]`.
|
|
623
|
+
*/
|
|
624
|
+
declare function readJson(path: string): any;
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* readFile(path, options?) → string
|
|
628
|
+
*
|
|
629
|
+
* A whole file, read once: its text, or its bytes as base64 with {encoding: 'base64'}. Path is relative to config `shellCwd`, or absolute inside the project or to a file waitForDownload saved (its .path). FAILS at once when the path or a symlink leads out, the file is missing or the encoding is unknown.
|
|
630
|
+
*/
|
|
631
|
+
declare function readFile(path: string, options?: any): string;
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* readFileInfo(path) → object
|
|
635
|
+
*
|
|
636
|
+
* What to assert about a file without reading it: {size} in bytes, plus png: {width, height} for a PNG (from its header). Same path rules and failures as readFile.
|
|
637
|
+
*/
|
|
638
|
+
declare function readFileInfo(path: string): any;
|
|
639
|
+
|
|
556
640
|
/**
|
|
557
641
|
* waitForFileCount(path, pattern, count, options?) → number
|
|
558
642
|
*
|
|
@@ -679,6 +763,13 @@ declare function getInnerText(locator: Locator): string;
|
|
|
679
763
|
*/
|
|
680
764
|
declare function getInputValue(locator: Locator): string;
|
|
681
765
|
|
|
766
|
+
/**
|
|
767
|
+
* boundingBox(locator) → {x, y, width, height} | null
|
|
768
|
+
*
|
|
769
|
+
* Where the element lies in the viewport, CSS pixels; null when it is not rendered (display:none, detached). Does not scroll.
|
|
770
|
+
*/
|
|
771
|
+
declare function boundingBox(locator: Locator): any;
|
|
772
|
+
|
|
682
773
|
/**
|
|
683
774
|
* getTitle() → string
|
|
684
775
|
*
|
|
@@ -756,6 +847,13 @@ declare function waitForCount(locator: Locator, count: number, options?: any): v
|
|
|
756
847
|
*/
|
|
757
848
|
declare function pause(ms: number): void;
|
|
758
849
|
|
|
850
|
+
/**
|
|
851
|
+
* waitForDownload(options?) → { path, name }
|
|
852
|
+
*
|
|
853
|
+
* The first file the page downloaded that the scenario has not taken yet, saved with the run: `path` is absolute (read it with waitForFile), `name` is the name the site suggested. Downloads are recorded from the start, so click first, then call this. options: {timeoutMs} (default: the navigation timeout), {name} (substring or regex of the file name).
|
|
854
|
+
*/
|
|
855
|
+
declare function waitForDownload(options?: any): any;
|
|
856
|
+
|
|
759
857
|
/**
|
|
760
858
|
* clockFreeze(iso)
|
|
761
859
|
*
|
|
@@ -777,6 +875,55 @@ declare function clockTick(ms: number): void;
|
|
|
777
875
|
*/
|
|
778
876
|
declare function clockRun(): void;
|
|
779
877
|
|
|
878
|
+
/**
|
|
879
|
+
* mockRoute(glob, response)
|
|
880
|
+
*
|
|
881
|
+
* From now on, requests matching `glob` (a Playwright URL glob: `**\/api/items*`) get a fixed answer: `{status?, body?, headers?, contentType?}` (an object body goes as JSON), `{abort: true, record?}` or `{continue: true}` (to the network). Where several masks match, the one mocked last answers; mocking a mask again replaces its answer. A response to `**\/*` is refused; the site's own page is never aborted. Mocks last until the scenario ends.
|
|
882
|
+
*/
|
|
883
|
+
declare function mockRoute(glob: string, response: any): void;
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* unmockRoute(glob?)
|
|
887
|
+
*
|
|
888
|
+
* Take off the mock at `glob`, or every mock when called without one.
|
|
889
|
+
*/
|
|
890
|
+
declare function unmockRoute(glob?: string): void;
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* waitForRequest(glob, { timeoutMs? }) → { url, method, headers, postData, postDataJson }
|
|
894
|
+
*
|
|
895
|
+
* Wait for a request matching `glob` and return it; `postDataJson` is the body read as JSON (null when it is not). On a mocked mask it also finds a request sent before the call, each one returned once; on any other mask only requests from the call on. Default timeout 20 s.
|
|
896
|
+
*/
|
|
897
|
+
declare function waitForRequest(glob: string, options?: any): any;
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* assertNoRequest(glob, { since? })
|
|
901
|
+
*
|
|
902
|
+
* FAIL if the recording abort at `glob` — mockRoute(glob, {abort: true, record: true}) — stopped any request; with `since` (epoch ms, from nowMs()) only from then on. A mask without a recording abort is an error, not a pass.
|
|
903
|
+
*/
|
|
904
|
+
declare function assertNoRequest(glob: string, options?: any): void;
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* waitForServiceWorker({ timeoutMs?, url? }) → string
|
|
908
|
+
*
|
|
909
|
+
* Wait for a browser extension's service worker and return its URL (`chrome-extension://<id>/sw.js`); a running one comes back at once. `url` — substring or /regex/ when several extensions run. Extensions load only with `launch.userDataDir`: without it the call fails at once.
|
|
910
|
+
*/
|
|
911
|
+
declare function waitForServiceWorker(options?: any): string;
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* extensionId() → string
|
|
915
|
+
*
|
|
916
|
+
* The id of the extension whose service worker runs — for `goto('chrome-extension://' + extensionId() + '/popup.html')`.
|
|
917
|
+
*/
|
|
918
|
+
declare function extensionId(): string;
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* evaluateInServiceWorker(js, ...args) → any
|
|
922
|
+
*
|
|
923
|
+
* Like evaluate, in the extension's service worker — the way to `chrome.storage`, `chrome.tabs`, `chrome.runtime`. Same argument and JSON-return rules; waits for the worker if none runs. Each call finds the worker anew: MV3 stops an idle one.
|
|
924
|
+
*/
|
|
925
|
+
declare function evaluateInServiceWorker(jsBody: string, ...args: unknown[]): any;
|
|
926
|
+
|
|
780
927
|
/** step(label, [options,] body)
|
|
781
928
|
*
|
|
782
929
|
* Groups statements under a labelled block. Every direct child of a
|