@itmetsam/samurai-framework 0.21.5 → 0.22.1
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/dist/api.d.ts +8 -3
- package/dist/api.js +1 -0
- package/dist/browser/browser-context.d.ts +18 -6
- package/dist/browser/browser-context.js +25 -7
- package/dist/browser/browser.d.ts +4 -4
- package/dist/browser/browser.js +11 -8
- package/dist/browser/chrome-launch.js +9 -1
- package/dist/browser/context-cookie-store.d.ts +17 -0
- package/dist/browser/context-cookie-store.js +90 -0
- package/dist/browser/index.d.ts +3 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/keyboard.d.ts +35 -0
- package/dist/browser/keyboard.js +83 -0
- package/dist/browser/mouse.d.ts +42 -0
- package/dist/browser/mouse.js +66 -0
- package/dist/browser/page-content.d.ts +4 -0
- package/dist/browser/page-content.js +12 -0
- package/dist/browser/page-events.d.ts +11 -0
- package/dist/browser/page-events.js +23 -0
- package/dist/browser/page-logging.d.ts +24 -0
- package/dist/browser/page-logging.js +43 -0
- package/dist/browser/page-navigation.d.ts +0 -2
- package/dist/browser/page-navigation.js +1 -6
- package/dist/browser/page-settings.d.ts +1 -1
- package/dist/browser/page-viewport.d.ts +21 -0
- package/dist/browser/page-viewport.js +33 -0
- package/dist/browser/page.d.ts +23 -16
- package/dist/browser/page.js +48 -71
- package/dist/browser/screenshot.d.ts +6 -0
- package/dist/browser/screenshot.js +14 -0
- package/dist/browser/storage-state.d.ts +0 -2
- package/dist/browser/storage-state.js +0 -20
- package/dist/browser/use-applier.d.ts +16 -5
- package/dist/browser/use-applier.js +44 -17
- package/dist/browser/use-commands.d.ts +36 -0
- package/dist/browser/use-commands.js +120 -0
- package/dist/cli/args.d.ts +8 -4
- package/dist/cli/args.js +8 -5
- package/dist/cli/console-reporter.js +5 -1
- package/dist/cli/main.js +1 -0
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/usage.js +4 -1
- package/dist/config/base-url.d.ts +4 -0
- package/dist/config/base-url.js +6 -0
- package/dist/config/config.js +7 -0
- package/dist/config/fixture-use.d.ts +19 -0
- package/dist/config/fixture-use.js +44 -0
- package/dist/config/fully-parallel.d.ts +3 -0
- package/dist/config/fully-parallel.js +6 -0
- package/dist/config/group-use.d.ts +10 -0
- package/dist/config/group-use.js +51 -0
- package/dist/config/resolved-config.d.ts +2 -0
- package/dist/config/resolved-config.js +3 -0
- package/dist/config/storage-state-file.d.ts +3 -0
- package/dist/config/storage-state-file.js +20 -0
- package/dist/config/use-options.d.ts +3 -1
- package/dist/config/use-options.js +74 -14
- package/dist/config/web-server-options.d.ts +7 -0
- package/dist/config/web-server-options.js +111 -0
- package/dist/locator/check-actions.js +1 -1
- package/dist/locator/drag-actions.d.ts +17 -0
- package/dist/locator/drag-actions.js +80 -0
- package/dist/locator/element-actions.d.ts +10 -4
- package/dist/locator/element-actions.js +23 -16
- package/dist/locator/element-state.d.ts +5 -0
- package/dist/locator/element-state.js +2 -1
- package/dist/locator/event-actions.d.ts +10 -0
- package/dist/locator/event-actions.js +81 -0
- package/dist/locator/input-actions.d.ts +2 -11
- package/dist/locator/input-actions.js +3 -56
- package/dist/locator/key-actions.d.ts +11 -0
- package/dist/locator/key-actions.js +52 -0
- package/dist/locator/key-map.d.ts +16 -0
- package/dist/locator/key-map.js +76 -0
- package/dist/locator/locator.d.ts +35 -5
- package/dist/locator/locator.js +70 -16
- package/dist/locator/page-scripts.d.ts +2 -0
- package/dist/locator/page-scripts.js +7 -0
- package/dist/locator/pointer-actions.d.ts +44 -0
- package/dist/locator/pointer-actions.js +117 -0
- package/dist/locator/pointer-element-actions.d.ts +21 -0
- package/dist/locator/pointer-element-actions.js +42 -0
- package/dist/request/api-request-context.d.ts +65 -0
- package/dist/request/api-request-context.js +198 -0
- package/dist/request/api-response.d.ts +34 -0
- package/dist/request/api-response.js +57 -0
- package/dist/request/cookie-jar.d.ts +48 -0
- package/dist/request/cookie-jar.js +164 -0
- package/dist/request/http-transport.d.ts +31 -0
- package/dist/request/http-transport.js +113 -0
- package/dist/request/redirect.d.ts +10 -0
- package/dist/request/redirect.js +21 -0
- package/dist/request/request-body.d.ts +27 -0
- package/dist/request/request-body.js +71 -0
- package/dist/request/request.d.ts +16 -0
- package/dist/request/request.js +20 -0
- package/dist/runner/all-hooks.d.ts +7 -1
- package/dist/runner/all-hooks.js +17 -1
- package/dist/runner/fixture-defs.d.ts +2 -1
- package/dist/runner/fixture-defs.js +52 -18
- package/dist/runner/fixture-meta.d.ts +20 -0
- package/dist/runner/fixture-meta.js +109 -0
- package/dist/runner/fixture-options.d.ts +8 -0
- package/dist/runner/fixture-options.js +35 -0
- package/dist/runner/fixture-outputs.d.ts +11 -0
- package/dist/runner/fixture-outputs.js +28 -0
- package/dist/runner/fixture-registry.d.ts +35 -0
- package/dist/runner/fixture-registry.js +73 -0
- package/dist/runner/fixture-scope.d.ts +39 -9
- package/dist/runner/fixture-scope.js +139 -70
- package/dist/runner/fixture-start.d.ts +27 -0
- package/dist/runner/fixture-start.js +76 -0
- package/dist/runner/fixture-use.d.ts +23 -0
- package/dist/runner/fixture-use.js +64 -0
- package/dist/runner/fixture-worker.d.ts +26 -0
- package/dist/runner/fixture-worker.js +46 -0
- package/dist/runner/fixtures.d.ts +4 -1
- package/dist/runner/fixtures.js +3 -2
- package/dist/runner/global-hooks.d.ts +13 -0
- package/dist/runner/global-hooks.js +66 -0
- package/dist/runner/options.d.ts +13 -2
- package/dist/runner/output-tail.d.ts +14 -0
- package/dist/runner/output-tail.js +30 -0
- package/dist/runner/pool-schedule.d.ts +22 -0
- package/dist/runner/pool-schedule.js +55 -0
- package/dist/runner/pool-units.d.ts +34 -0
- package/dist/runner/pool-units.js +85 -0
- package/dist/runner/pooled-run.d.ts +7 -5
- package/dist/runner/pooled-run.js +19 -9
- package/dist/runner/prepare-run.js +5 -0
- package/dist/runner/registry.js +21 -7
- package/dist/runner/reporter.d.ts +13 -1
- package/dist/runner/reporter.js +13 -2
- package/dist/runner/request-fixture.d.ts +14 -0
- package/dist/runner/request-fixture.js +25 -0
- package/dist/runner/run-hooks.d.ts +16 -0
- package/dist/runner/run-hooks.js +52 -0
- package/dist/runner/run-test.d.ts +3 -0
- package/dist/runner/run-test.js +23 -3
- package/dist/runner/run.d.ts +8 -0
- package/dist/runner/run.js +10 -0
- package/dist/runner/select.d.ts +15 -4
- package/dist/runner/select.js +38 -12
- package/dist/runner/serial-run.d.ts +23 -0
- package/dist/runner/serial-run.js +88 -0
- package/dist/runner/serial.d.ts +34 -0
- package/dist/runner/serial.js +63 -0
- package/dist/runner/shard.d.ts +22 -0
- package/dist/runner/shard.js +73 -0
- package/dist/runner/suite.d.ts +3 -3
- package/dist/runner/suite.js +4 -3
- package/dist/runner/test-function.d.ts +15 -3
- package/dist/runner/test-info.js +2 -1
- package/dist/runner/test-runner.d.ts +1 -0
- package/dist/runner/test-runner.js +67 -18
- package/dist/runner/use-options.d.ts +18 -4
- package/dist/runner/use-options.js +33 -6
- package/dist/runner/wait-for-url.d.ts +20 -0
- package/dist/runner/wait-for-url.js +65 -0
- package/dist/runner/web-server.d.ts +16 -0
- package/dist/runner/web-server.js +165 -0
- package/dist/runner/worker-pool.d.ts +13 -5
- package/dist/runner/worker-pool.js +85 -51
- package/dist/runner/worker-protocol.d.ts +8 -0
- package/dist/runner/worker-session.js +9 -1
- package/dist/runner/worker.d.ts +2 -0
- package/dist/runner/worker.js +7 -1
- package/dist/types/config.d.ts +117 -21
- package/dist/types/extend.d.ts +54 -2
- package/dist/types/test.d.ts +42 -0
- package/dist/types/use.d.ts +59 -7
- package/package.json +1 -1
- package/dist/browser/emulation.d.ts +0 -61
- package/dist/browser/emulation.js +0 -180
package/dist/types/config.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { StepDefinition } from "../flows/steps/define.js";
|
|
2
2
|
import type { SupportedBrowser } from "./browser.js";
|
|
3
|
-
import type { UseOptions } from "./use.js";
|
|
3
|
+
import type { FixtureUse, UseOptions } from "./use.js";
|
|
4
|
+
import type { ResolvedConfig } from "../config/resolved-config.js";
|
|
4
5
|
|
|
5
6
|
interface SamuraiTest {
|
|
6
7
|
/** Path relative to srcDir, e.g. 'checkout/coupons.spec.ts' */
|
|
@@ -33,8 +34,67 @@ export interface SamuraiGroup {
|
|
|
33
34
|
* nothing but such a group uses one worker.
|
|
34
35
|
*/
|
|
35
36
|
workers?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Options for this group's tests, over the config's `use` and under the `test.use()` of a spec: the same options
|
|
39
|
+
* as config `use` that make sense per group (`locale`, `isMobile`, `viewport`, ...). They apply when the group is
|
|
40
|
+
* selected (`--group`); a run without `--group` ignores them. The way to port a Playwright project.
|
|
41
|
+
*/
|
|
42
|
+
use?: GroupUse & FixtureUse;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The options of a group's `use`: those of `test.use()`, and the page's `viewport` */
|
|
46
|
+
export interface GroupUse extends UseOptions {
|
|
47
|
+
/** Size of the page's viewport, instead of config `use.viewport`. `null` keeps the browser's own size */
|
|
48
|
+
viewport?: { width: number; height: number } | null;
|
|
36
49
|
}
|
|
37
50
|
|
|
51
|
+
/** One server the run starts before the first test (see `SamuraiTestConfig.webServer`). Give either `url` or `port`. */
|
|
52
|
+
export interface WebServerConfig {
|
|
53
|
+
/** Shell command that starts the server. It leads its own process group, so the whole tree is stopped at the end */
|
|
54
|
+
command: string;
|
|
55
|
+
/** Where the server answers: ready once it responds with a status from 200 to 403 */
|
|
56
|
+
url?: string;
|
|
57
|
+
/** Where the server listens: ready once `localhost` accepts TCP connections on it */
|
|
58
|
+
port?: number;
|
|
59
|
+
/** Working directory of the command, relative to the project folder. @default the project folder */
|
|
60
|
+
cwd?: string;
|
|
61
|
+
/** Extra environment variables for the command, on top of this process's. Never printed in errors */
|
|
62
|
+
env?: Record<string, string>;
|
|
63
|
+
/** Time (ms) the server may take to be ready. @default 60000 */
|
|
64
|
+
timeout?: number;
|
|
65
|
+
/** When `url`/`port` already answers, use that server and start nothing (it is not stopped either). @default false */
|
|
66
|
+
reuseExistingServer?: boolean;
|
|
67
|
+
/** Send the command's stdout to this process's stdout, or drop it. @default "ignore" */
|
|
68
|
+
stdout?: "pipe" | "ignore";
|
|
69
|
+
/** Send the command's stderr to this process's stderr, or drop it. @default "pipe" */
|
|
70
|
+
stderr?: "pipe" | "ignore";
|
|
71
|
+
/** Do not fail on a certificate error while waiting for an `https` `url`. @default false */
|
|
72
|
+
ignoreHTTPSErrors?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* How the server is stopped: `signal` goes to the whole process group, and after `timeout` ms what is left is
|
|
75
|
+
* killed. @default { signal: "SIGTERM", timeout: 5000 }
|
|
76
|
+
*/
|
|
77
|
+
gracefulShutdown?: { signal?: "SIGTERM" | "SIGINT"; timeout?: number };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** What `globalSetup` and `globalTeardown` receive: the project's resolved config, with the run's environment and base URL */
|
|
81
|
+
export type GlobalHookConfig = ResolvedConfig & {
|
|
82
|
+
/** The environment the run uses */
|
|
83
|
+
environment: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** A run-level hook; `globalSetup` may return a function that runs as teardown too */
|
|
87
|
+
export type GlobalSetupFunction = (
|
|
88
|
+
config: GlobalHookConfig,
|
|
89
|
+
) =>
|
|
90
|
+
| void
|
|
91
|
+
| (() => void | Promise<void>)
|
|
92
|
+
| Promise<void | (() => void | Promise<void>)>;
|
|
93
|
+
|
|
94
|
+
export type GlobalTeardownFunction = (
|
|
95
|
+
config: GlobalHookConfig,
|
|
96
|
+
) => void | Promise<void>;
|
|
97
|
+
|
|
38
98
|
export interface SamuraiEnvironment {
|
|
39
99
|
/** Where page.goto('/…') resolves to in this environment, and where recordings start */
|
|
40
100
|
baseURL?: string;
|
|
@@ -45,6 +105,12 @@ export interface SamuraiEnvironment {
|
|
|
45
105
|
headless?: boolean;
|
|
46
106
|
/** Test data, used in steps as ${name}. Never put secrets here. */
|
|
47
107
|
variables?: Record<string, string | number | boolean>;
|
|
108
|
+
/**
|
|
109
|
+
* `use` options for every test run in this environment, over config `use` and under a group's `use` and
|
|
110
|
+
* `test.use()`. `fixtures: { order: false }` turns a fixture off here for good: a test that needs it is skipped,
|
|
111
|
+
* whatever a group or test says.
|
|
112
|
+
*/
|
|
113
|
+
use?: GroupUse & FixtureUse;
|
|
48
114
|
}
|
|
49
115
|
|
|
50
116
|
export interface SamuraiTestConfig {
|
|
@@ -65,6 +131,14 @@ export interface SamuraiTestConfig {
|
|
|
65
131
|
* @default half the CPUs
|
|
66
132
|
*/
|
|
67
133
|
workers?: number | string;
|
|
134
|
+
/**
|
|
135
|
+
* Whether the tests of one file may run on different workers. Not set: they do, one test at a time goes to the
|
|
136
|
+
* next free worker (the same as `true`). `false` keeps the tests of a file together, in order, on one worker;
|
|
137
|
+
* `describe.configure({ mode: 'parallel' })` frees a part of it again. A serial block (`describe.serial`) is
|
|
138
|
+
* never split, whatever this says.
|
|
139
|
+
* @default not set
|
|
140
|
+
*/
|
|
141
|
+
fullyParallel?: boolean;
|
|
68
142
|
/**
|
|
69
143
|
* How many times a failing test is run again, each time with a fresh browser. A test that passes on a retry is
|
|
70
144
|
* reported as flaky and does not fail the run; a run that is aborted is never retried. `--retries` and
|
|
@@ -131,26 +205,27 @@ export interface SamuraiTestConfig {
|
|
|
131
205
|
*/
|
|
132
206
|
filesDir?: string;
|
|
133
207
|
/** How pages are opened, and what the browser pretends: the options of `test.use()` apply to every test */
|
|
134
|
-
use?: UseOptions &
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
208
|
+
use?: UseOptions &
|
|
209
|
+
FixtureUse & {
|
|
210
|
+
/**
|
|
211
|
+
* Size of the page's viewport, so screenshots and layout are the same on every machine.
|
|
212
|
+
* `null` keeps the browser's own size
|
|
213
|
+
* @default { width: 1280, height: 720 }
|
|
214
|
+
*/
|
|
215
|
+
viewport?: { width: number; height: number } | null;
|
|
216
|
+
/**
|
|
217
|
+
* Run the browser without a window. Needed on machines without a display, such as CI runners.
|
|
218
|
+
* Left out, a run is headless when the `CI` environment variable is set and shows a window otherwise
|
|
219
|
+
*/
|
|
220
|
+
headless?: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Make an action or read on a locator that matches several elements throw
|
|
223
|
+
* `name(): strict mode violation, N elements match ...` instead of using the first one. Narrow the locator
|
|
224
|
+
* (`first()`, `nth()`, `filter()`) or turn it off for one locator with `locator.strict(false)`
|
|
225
|
+
* @default false
|
|
226
|
+
*/
|
|
227
|
+
strictSelectors?: boolean;
|
|
228
|
+
};
|
|
154
229
|
/** What to do with the browser's console output and uncaught page exceptions */
|
|
155
230
|
logs?: {
|
|
156
231
|
/**
|
|
@@ -210,6 +285,27 @@ export interface SamuraiTestConfig {
|
|
|
210
285
|
*/
|
|
211
286
|
maxBodySize?: number;
|
|
212
287
|
};
|
|
288
|
+
/**
|
|
289
|
+
* Servers the run starts before the first test and stops after the last. Each waits until its `url` answers or
|
|
290
|
+
* its `port` accepts connections. When no `baseURL` is configured (project or environment), the first server's
|
|
291
|
+
* `url` origin (or `http://localhost:<port>`) becomes the base URL. Only a run (`samurai run`, `runTests`)
|
|
292
|
+
* starts them, not `list` or the recorder.
|
|
293
|
+
*/
|
|
294
|
+
webServer?: WebServerConfig | WebServerConfig[];
|
|
295
|
+
/**
|
|
296
|
+
* Module (path relative to the project folder) whose default export `async (config) => void | teardown` runs once
|
|
297
|
+
* before the tests, after the web servers are up; or the function itself. Variables it sets in `process.env`
|
|
298
|
+
* reach the tests, workers included. A function it returns runs as teardown.
|
|
299
|
+
*/
|
|
300
|
+
globalSetup?: string | GlobalSetupFunction;
|
|
301
|
+
/** Module (path relative to the project folder) whose default export runs once after the tests; or the function itself */
|
|
302
|
+
globalTeardown?: string | GlobalTeardownFunction;
|
|
303
|
+
/**
|
|
304
|
+
* The tests made with `test.extend()` whose fixtures the app, the groups and `use.fixtures` can name. The
|
|
305
|
+
* fixtures are read from the list without running a test; a name defined twice, or not matching
|
|
306
|
+
* `/^[a-z][A-Za-z0-9]*$/`, refuses the run.
|
|
307
|
+
*/
|
|
308
|
+
fixtures?: { extend: (...args: never[]) => unknown }[];
|
|
213
309
|
/** Keyed by name: 'dev', 'staging', 'production' */
|
|
214
310
|
environments?: Record<string, SamuraiEnvironment>;
|
|
215
311
|
/** Used when no environment is chosen with --env or SAMURAI_ENV */
|
package/dist/types/extend.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Field } from "../flows/core/index.js";
|
|
1
2
|
import type { TestFixtures } from "./test.js";
|
|
2
3
|
|
|
3
4
|
/** What a test sees when it is built with `test.extend()`: the built-in fixtures, a custom one of the same name replacing it */
|
|
@@ -6,12 +7,63 @@ export type FixturesOf<X> = Omit<TestFixtures, keyof X> & X;
|
|
|
6
7
|
/** `B` on top of `A`: a key in both takes the type from `B` */
|
|
7
8
|
export type MergeFixtures<A, B> = Omit<A, keyof B> & B;
|
|
8
9
|
|
|
10
|
+
/** One key of the value a fixture sets up, listed for the app and the report */
|
|
11
|
+
export interface FixtureOutput {
|
|
12
|
+
name: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
/** The test gets the key, but the report and the app never do */
|
|
15
|
+
secret?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* One setting of an option fixture, as data for a form: the flows field types, with paths relative to the option
|
|
20
|
+
* object. `secret` stores the name of a secret and `variable` the name of a variable; the fixture receives the
|
|
21
|
+
* resolved value.
|
|
22
|
+
*/
|
|
23
|
+
export type FixtureField =
|
|
24
|
+
| Extract<
|
|
25
|
+
Field,
|
|
26
|
+
{
|
|
27
|
+
type:
|
|
28
|
+
| "text"
|
|
29
|
+
| "code"
|
|
30
|
+
| "expression"
|
|
31
|
+
| "number"
|
|
32
|
+
| "select"
|
|
33
|
+
| "segmented"
|
|
34
|
+
| "switch";
|
|
35
|
+
}
|
|
36
|
+
>
|
|
37
|
+
| {
|
|
38
|
+
path: string;
|
|
39
|
+
label?: string;
|
|
40
|
+
type: "secret" | "variable";
|
|
41
|
+
default?: string;
|
|
42
|
+
};
|
|
43
|
+
|
|
9
44
|
/** The options of a fixture written as `[fixture, options]` */
|
|
10
45
|
export interface FixtureOptions {
|
|
11
46
|
/** Set the fixture up for every test, whether or not the test asks for it */
|
|
12
47
|
auto?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
|
|
48
|
+
/**
|
|
49
|
+
* `"test"`: set up for each test (the default). `"worker"`: set up once per worker for the tests that use it with
|
|
50
|
+
* the same options and environment, and torn down when the worker is done. A worker fixture gets no `page`.
|
|
51
|
+
*/
|
|
52
|
+
scope?: "test" | "worker";
|
|
53
|
+
/** The name in the app's catalog */
|
|
54
|
+
label?: string;
|
|
55
|
+
/** A design-system icon name */
|
|
56
|
+
icon?: string;
|
|
57
|
+
/** One sentence for the catalog */
|
|
58
|
+
description?: string;
|
|
59
|
+
/** The keys of the value the fixture sets up, when it is a flat record of strings, numbers and booleans */
|
|
60
|
+
outputs?: FixtureOutput[];
|
|
61
|
+
/** Milliseconds a setup or a teardown may take. @default the test timeout */
|
|
62
|
+
timeout?: number;
|
|
63
|
+
/** The fixture is the options of the fixture `<name without "Options">`: a value that `use` overrides key by key */
|
|
64
|
+
option?: boolean;
|
|
65
|
+
/** The form of an option fixture */
|
|
66
|
+
fields?: FixtureField[];
|
|
15
67
|
}
|
|
16
68
|
|
|
17
69
|
/** A value, or a function that sets the value up, calls `use(value)` and cleans up once `use` returns */
|
package/dist/types/test.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Browser } from "../browser/browser.js";
|
|
|
2
2
|
import type Page from "../browser/page.js";
|
|
3
3
|
import type { BrowserContext } from "../browser/browser-context.js";
|
|
4
4
|
import type Locator from "../locator/locator.js";
|
|
5
|
+
import type { APIRequestContext } from "../request/api-request-context.js";
|
|
5
6
|
import type { SupportedBrowser } from "./browser.js";
|
|
6
7
|
import type { UseOptions } from "./use.js";
|
|
7
8
|
|
|
@@ -25,6 +26,11 @@ export interface TestFixtures {
|
|
|
25
26
|
context: BrowserContext;
|
|
26
27
|
/** The run's `baseURL` (the environment's, else the project's); `undefined` when none is set */
|
|
27
28
|
baseURL: string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Makes HTTP requests without a browser: its own cookies, the run's `baseURL`, `use.extraHTTPHeaders` and
|
|
31
|
+
* `use.acceptInsecureCerts`. For requests that share the page's cookies use `page.request`.
|
|
32
|
+
*/
|
|
33
|
+
request: APIRequestContext;
|
|
28
34
|
/** About the running test: its title, retry, attachments; same as `test.info()` */
|
|
29
35
|
testInfo: TestInfo;
|
|
30
36
|
/** Whether the page runs as a phone (`use.isMobile`); always false on Firefox, which cannot do it */
|
|
@@ -68,6 +74,26 @@ export interface TestStepEntry {
|
|
|
68
74
|
steps?: TestStepEntry[];
|
|
69
75
|
}
|
|
70
76
|
|
|
77
|
+
/** How a fixture's setup or teardown went in one test */
|
|
78
|
+
export interface TestFixturePhase {
|
|
79
|
+
/** `"skipped"`: a worker fixture another test of this worker already set up */
|
|
80
|
+
status: "passed" | "failed" | "skipped";
|
|
81
|
+
/** Milliseconds */
|
|
82
|
+
durationMs: number;
|
|
83
|
+
error?: TestError;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** A fixture that set up for a test (hand-written `test.extend` ones too), as the report lists it */
|
|
87
|
+
export interface TestFixtureEntry {
|
|
88
|
+
name: string;
|
|
89
|
+
scope: "test" | "worker";
|
|
90
|
+
setup: TestFixturePhase;
|
|
91
|
+
/** Absent for a worker fixture: it is torn down when the worker is done, after the test's result is written */
|
|
92
|
+
teardown?: Omit<TestFixturePhase, "status"> & { status: "passed" | "failed" };
|
|
93
|
+
/** The declared outputs that are not secret */
|
|
94
|
+
outputs?: Record<string, string | number | boolean>;
|
|
95
|
+
}
|
|
96
|
+
|
|
71
97
|
/** What `testInfo` and `test.info()` tell about the running test (hooks included) */
|
|
72
98
|
export interface TestInfo {
|
|
73
99
|
/** The test's own title */
|
|
@@ -174,8 +200,13 @@ export interface Suite {
|
|
|
174
200
|
marks?: { type: "fail" | "slow"; description?: string }[];
|
|
175
201
|
/** The `test.use()` calls written in this scope, in order; they apply to every test below */
|
|
176
202
|
use?: UseOptions[];
|
|
203
|
+
/** Set by `describe.configure({ mode })`, `describe.serial` or `describe.parallel`; absent: `"default"` */
|
|
204
|
+
mode?: SuiteMode;
|
|
177
205
|
}
|
|
178
206
|
|
|
207
|
+
/** How the tests of a suite run: `"serial"` in order on one worker, the rest stops at the first failure */
|
|
208
|
+
export type SuiteMode = "default" | "parallel" | "serial";
|
|
209
|
+
|
|
179
210
|
export interface RegisteredTestCase extends TestCaseBase {
|
|
180
211
|
/** Path of the spec file that registered the test */
|
|
181
212
|
file: string;
|
|
@@ -198,6 +229,8 @@ export interface RegisteredTestCase extends TestCaseBase {
|
|
|
198
229
|
expectedFail?: { description?: string };
|
|
199
230
|
/** The custom fixtures of the `test` it was written with (`test.extend()`); absent for the plain `test` */
|
|
200
231
|
extension?: ReadonlyMap<string, readonly unknown[]>;
|
|
232
|
+
/** The group this run of the test is for, when groups were selected; the same test runs once per selected group */
|
|
233
|
+
group?: string;
|
|
201
234
|
}
|
|
202
235
|
|
|
203
236
|
export interface TestCaseBase {
|
|
@@ -232,6 +265,8 @@ interface TestResultSuccess extends TestResultIdentity, TestRetries {
|
|
|
232
265
|
annotations?: TestAnnotation[];
|
|
233
266
|
/** The steps the test ran with `test.step`; absent when it ran none */
|
|
234
267
|
steps?: TestStepEntry[];
|
|
268
|
+
/** The fixtures the test set up and how each went; absent when it used none */
|
|
269
|
+
fixtures?: TestFixtureEntry[];
|
|
235
270
|
}
|
|
236
271
|
|
|
237
272
|
/** The error sits flat on the entry, as in the report: `message`, `type`, `stack`, and for assertions `expected` and `actual` */
|
|
@@ -252,6 +287,8 @@ interface TestResultFailed extends TestResultIdentity, TestError, TestRetries {
|
|
|
252
287
|
annotations?: TestAnnotation[];
|
|
253
288
|
/** The steps the test ran with `test.step`; absent when it ran none */
|
|
254
289
|
steps?: TestStepEntry[];
|
|
290
|
+
/** The fixtures the test set up and how each went; absent when it used none */
|
|
291
|
+
fixtures?: TestFixtureEntry[];
|
|
255
292
|
}
|
|
256
293
|
|
|
257
294
|
/** What a result says about the retries of its test; absent when it passed or failed on the first attempt */
|
|
@@ -288,6 +325,8 @@ interface TestResultIdentity {
|
|
|
288
325
|
file: string;
|
|
289
326
|
/** The browser the test ran in */
|
|
290
327
|
browser: SupportedBrowser;
|
|
328
|
+
/** The group the test ran for, when the run selected groups (`--group`); absent otherwise */
|
|
329
|
+
group?: string;
|
|
291
330
|
/** The worker process that ran the test; absent when the test ran in the main process */
|
|
292
331
|
worker?: number;
|
|
293
332
|
startTime: number;
|
|
@@ -297,6 +336,7 @@ interface TestResultBase {
|
|
|
297
336
|
name: string;
|
|
298
337
|
file: string;
|
|
299
338
|
browser: SupportedBrowser;
|
|
339
|
+
group?: string;
|
|
300
340
|
worker?: number;
|
|
301
341
|
startTime: number;
|
|
302
342
|
status: "started";
|
|
@@ -331,4 +371,6 @@ interface TestSummaryBase {
|
|
|
331
371
|
environment: string;
|
|
332
372
|
/** The browsers the run used, in the order they ran */
|
|
333
373
|
browsers: SupportedBrowser[];
|
|
374
|
+
/** The slice of the selected tests the run held (`--shard`); absent for a whole run */
|
|
375
|
+
shard?: { current: number; total: number };
|
|
334
376
|
}
|
package/dist/types/use.d.ts
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* How the page looks to the site, and what the browser starts with. One vocabulary for every level: config `use`,
|
|
3
|
+
* a group's `use`, `test.use()` (fixed before the test starts) and `page.use()` / `context.use()` (applied now).
|
|
4
|
+
* At run time `null` puts the real value back; in config a later layer's `null` cancels an earlier value.
|
|
5
|
+
*/
|
|
2
6
|
export interface UseOptions {
|
|
3
7
|
/** A BCP 47 tag, e.g. "nl-NL": `navigator.language`, `Intl` formatting and the `Accept-Language` header */
|
|
4
|
-
locale?: string;
|
|
8
|
+
locale?: string | null;
|
|
5
9
|
/** An IANA timezone, e.g. "Europe/Amsterdam" */
|
|
6
|
-
|
|
10
|
+
timezone?: string | null;
|
|
7
11
|
/** The `User-Agent` header and `navigator.userAgent` */
|
|
8
|
-
userAgent?: string;
|
|
12
|
+
userAgent?: string | null;
|
|
13
|
+
/** Needs the geolocation permission: see `page.grantPermission("geolocation")` */
|
|
14
|
+
geolocation?: {
|
|
15
|
+
latitude: number;
|
|
16
|
+
longitude: number;
|
|
17
|
+
accuracy?: number;
|
|
18
|
+
} | null;
|
|
19
|
+
/** `true`: no network (`navigator.onLine` is false and requests fail); `false`: back online */
|
|
20
|
+
offline?: boolean | null;
|
|
21
|
+
/** "portrait" and "landscape" mean the primary orientation of that kind */
|
|
22
|
+
orientation?: Orientation | null;
|
|
23
|
+
/** The size `screen.width` and `screen.height` report */
|
|
24
|
+
screen?: { width: number; height: number } | null;
|
|
9
25
|
/** `false` runs pages without JavaScript */
|
|
10
|
-
javaScriptEnabled?: boolean;
|
|
26
|
+
javaScriptEnabled?: boolean | null;
|
|
27
|
+
/** Touch input: `navigator.maxTouchPoints` is 1. Chrome only. */
|
|
28
|
+
hasTouch?: boolean | null;
|
|
11
29
|
/** Accept certificates that are self-signed, expired or for another host. Fixed when the browser starts. */
|
|
12
30
|
acceptInsecureCerts?: boolean;
|
|
13
|
-
/** Touch input: `navigator.maxTouchPoints` is 1. Chrome only. */
|
|
14
|
-
hasTouch?: boolean;
|
|
15
31
|
/** A phone-like browser (the layout viewport follows the page's `<meta name="viewport">`). Chrome only. */
|
|
16
32
|
isMobile?: boolean;
|
|
17
33
|
/** Cookies and local storage to start with: a JSON file (relative to the project folder) or the object itself */
|
|
@@ -22,6 +38,42 @@ export interface UseOptions {
|
|
|
22
38
|
colorScheme?: ColorScheme;
|
|
23
39
|
}
|
|
24
40
|
|
|
41
|
+
/**
|
|
42
|
+
* What a `use` that is layered over config, environment, group and `test.use()` can also say about fixtures. Not
|
|
43
|
+
* part of `UseOptions`: `page.use()` and the browser know nothing of fixtures.
|
|
44
|
+
*/
|
|
45
|
+
export interface FixtureUse {
|
|
46
|
+
/**
|
|
47
|
+
* Fixtures to attach by name (`true`: set up before `beforeEach`, like an `auto` fixture) or to remove (`false`).
|
|
48
|
+
* An environment's `false` wins over a group's or test's `true`.
|
|
49
|
+
*/
|
|
50
|
+
fixtures?: Record<string, boolean>;
|
|
51
|
+
/** The values of an option fixture (`orderOptions: { items: 2 }`), merged key by key with the other layers */
|
|
52
|
+
[option: `${string}Options`]: Record<string, unknown> | undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The options `page.use()` and `context.use()` take: those that can change while the browser runs */
|
|
56
|
+
export type RuntimeUseOptions = Pick<
|
|
57
|
+
UseOptions,
|
|
58
|
+
| "locale"
|
|
59
|
+
| "timezone"
|
|
60
|
+
| "userAgent"
|
|
61
|
+
| "geolocation"
|
|
62
|
+
| "offline"
|
|
63
|
+
| "orientation"
|
|
64
|
+
| "screen"
|
|
65
|
+
| "javaScriptEnabled"
|
|
66
|
+
| "hasTouch"
|
|
67
|
+
>;
|
|
68
|
+
|
|
69
|
+
export type Orientation =
|
|
70
|
+
| "portrait"
|
|
71
|
+
| "landscape"
|
|
72
|
+
| "portrait-primary"
|
|
73
|
+
| "portrait-secondary"
|
|
74
|
+
| "landscape-primary"
|
|
75
|
+
| "landscape-secondary";
|
|
76
|
+
|
|
25
77
|
export type ColorScheme = "light" | "dark" | "no-preference";
|
|
26
78
|
|
|
27
79
|
/** Cookies and local storage, in the format Playwright's `storageState` files use */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itmetsam/samurai-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"description": "Browser test framework over WebDriver BiDi: auto-waiting locators, environments and secrets, a recorder, and a command line.",
|
|
5
5
|
"main": "dist/api.js",
|
|
6
6
|
"exports": {
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { UnsupportedOperationError } from "../transport/unsupported.js";
|
|
2
|
-
import type { BiDiConnector } from "../transport/bidi-connection.js";
|
|
3
|
-
declare const ORIENTATIONS: readonly ["portrait-primary", "portrait-secondary", "landscape-primary", "landscape-secondary"];
|
|
4
|
-
type OrientationType = (typeof ORIENTATIONS)[number];
|
|
5
|
-
/**
|
|
6
|
-
* What to pretend about the browser. `undefined` leaves an option as it is, `null` puts the real value back.
|
|
7
|
-
* Which options a browser supports differs: an unsupported one throws UnsupportedOperationError.
|
|
8
|
-
*/
|
|
9
|
-
export interface EmulationOptions {
|
|
10
|
-
/** A BCP 47 tag, e.g. "nl-NL": `navigator.language`, `Intl` formatting */
|
|
11
|
-
locale?: string | null;
|
|
12
|
-
/** An IANA timezone, e.g. "Europe/Amsterdam" */
|
|
13
|
-
timezone?: string | null;
|
|
14
|
-
userAgent?: string | null;
|
|
15
|
-
/** Needs the geolocation permission: see `page.grantPermission("geolocation")` */
|
|
16
|
-
geolocation?: {
|
|
17
|
-
latitude: number;
|
|
18
|
-
longitude: number;
|
|
19
|
-
accuracy?: number;
|
|
20
|
-
} | null;
|
|
21
|
-
/** `true`: no network (`navigator.onLine` is false and requests fail); `false` or `null`: back online */
|
|
22
|
-
offline?: boolean | null;
|
|
23
|
-
/** "portrait" and "landscape" mean the primary orientation of that kind */
|
|
24
|
-
orientation?: "portrait" | "landscape" | OrientationType | null;
|
|
25
|
-
/** The size `screen.width` and `screen.height` report */
|
|
26
|
-
screen?: {
|
|
27
|
-
width: number;
|
|
28
|
-
height: number;
|
|
29
|
-
} | null;
|
|
30
|
-
/** How many touch points `navigator.maxTouchPoints` reports */
|
|
31
|
-
touch?: number | null;
|
|
32
|
-
/** `false` turns JavaScript off; `true` or `null` on again */
|
|
33
|
-
javaScriptEnabled?: boolean | null;
|
|
34
|
-
}
|
|
35
|
-
export type EmulationTarget = {
|
|
36
|
-
contexts: string[];
|
|
37
|
-
} | {
|
|
38
|
-
userContexts: string[];
|
|
39
|
-
};
|
|
40
|
-
/** A part of the options could not be applied; what was applied before it stays applied */
|
|
41
|
-
export declare class EmulationError extends Error {
|
|
42
|
-
/** The options that were applied before the failure, in the order they were applied */
|
|
43
|
-
readonly applied: string[];
|
|
44
|
-
readonly failed: string;
|
|
45
|
-
readonly cause: unknown;
|
|
46
|
-
constructor(failed: string, applied: string[], cause: unknown);
|
|
47
|
-
}
|
|
48
|
-
/** The browser does not implement an emulation command */
|
|
49
|
-
export declare class EmulationUnsupportedError extends UnsupportedOperationError {
|
|
50
|
-
readonly option: string;
|
|
51
|
-
readonly applied: string[];
|
|
52
|
-
constructor(option: string, applied: string[]);
|
|
53
|
-
}
|
|
54
|
-
/** Throws RangeError when a value is invalid, without sending anything */
|
|
55
|
-
export declare function validateEmulation(options: EmulationOptions): void;
|
|
56
|
-
/**
|
|
57
|
-
* Applies the options to `target`, one command after the other. Nothing is rolled back when one fails:
|
|
58
|
-
* the error says what was applied.
|
|
59
|
-
*/
|
|
60
|
-
export declare function applyEmulation(connector: BiDiConnector, target: EmulationTarget, options: EmulationOptions): Promise<void>;
|
|
61
|
-
export {};
|