@itmetsam/samurai-framework 0.15.1 → 0.16.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/dist/api.d.ts +1 -1
- package/dist/browser/browser.js +2 -1
- package/dist/browser/page-network.js +3 -2
- package/dist/browser/page-settings.js +2 -5
- package/dist/browser/page.js +2 -1
- package/dist/browser/session.d.ts +1 -1
- package/dist/browser/session.js +1 -1
- package/dist/browser/viewport.d.ts +0 -5
- package/dist/browser/viewport.js +0 -2
- package/dist/capabilities.d.ts +32 -0
- package/dist/capabilities.js +30 -0
- package/dist/cli/main.js +1 -1
- package/dist/{runner/browsers.js → config/browsers-for.js} +1 -2
- package/dist/config/config.d.ts +3 -1
- package/dist/config/config.js +12 -11
- package/dist/config/defaults.d.ts +41 -0
- package/dist/config/defaults.js +38 -0
- package/dist/config/resolved-config.d.ts +106 -0
- package/dist/config/resolved-config.js +112 -0
- package/dist/config/run-settings.d.ts +2 -0
- package/dist/config/run-settings.js +2 -3
- package/dist/config/timeouts.js +1 -2
- package/dist/{runner → config}/workers-option.js +1 -1
- package/dist/flows/run/project.js +5 -4
- package/dist/network/data-collector.js +1 -2
- package/dist/network/router.js +1 -2
- package/dist/project/files-store.js +2 -1
- package/dist/project/index.d.ts +1 -0
- package/dist/project/index.js +1 -0
- package/dist/recorder/session-browser.js +1 -1
- package/dist/recorder/session.d.ts +5 -2
- package/dist/recorder/session.js +18 -3
- package/dist/runner/groups.d.ts +4 -5
- package/dist/runner/groups.js +2 -5
- package/dist/runner/page-logs-report.js +6 -3
- package/dist/runner/pooled-run.js +3 -3
- package/dist/runner/project.js +2 -2
- package/dist/runner/registry.d.ts +13 -4
- package/dist/runner/registry.js +26 -9
- package/dist/runner/retries-option.js +2 -1
- package/dist/runner/run-test.js +1 -1
- package/dist/runner/run.d.ts +14 -2
- package/dist/runner/run.js +21 -6
- package/dist/runner/select.js +4 -4
- package/dist/runner/skip.d.ts +2 -1
- package/dist/runner/skip.js +3 -2
- package/dist/runner/suite.d.ts +10 -4
- package/dist/runner/suite.js +19 -10
- package/dist/runner/test-dir.js +2 -1
- package/dist/runner/test-runner.d.ts +8 -2
- package/dist/runner/test-runner.js +14 -10
- package/dist/steps/edit.d.ts +10 -0
- package/dist/steps/edit.js +4 -0
- package/dist/steps/index.d.ts +2 -2
- package/dist/steps/index.js +1 -1
- package/dist/steps/model.d.ts +19 -0
- package/dist/steps/parse.d.ts +6 -1
- package/dist/steps/parse.js +89 -19
- package/dist/transport/bidi-connection.d.ts +0 -2
- package/dist/transport/bidi-connection.js +1 -2
- package/dist/types/test.d.ts +10 -0
- package/package.json +6 -2
- /package/dist/{runner/browsers.d.ts → config/browsers-for.d.ts} +0 -0
- /package/dist/{runner → config}/workers-option.d.ts +0 -0
|
@@ -2,12 +2,12 @@ import { glob } from "node:fs/promises";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { ensureWarm } from "../browser/warm-up.js";
|
|
4
4
|
import { projectBrowser } from "../browsers/resolve.js";
|
|
5
|
-
import {
|
|
5
|
+
import { loadRawConfig, projectDir, readConfig } from "../config/config.js";
|
|
6
6
|
import { forbidsOnly } from "../config/forbid-only.js";
|
|
7
7
|
import logger from "../logger/index.js";
|
|
8
8
|
import { AllHooks } from "./all-hooks.js";
|
|
9
9
|
import { assertNoOnly, narrowToOnly } from "./focus.js";
|
|
10
|
-
import { DEFAULT_SRC_DIR, DEFAULT_TEST_MATCH } from "
|
|
10
|
+
import { DEFAULT_SRC_DIR, DEFAULT_TEST_MATCH } from "../config/defaults.js";
|
|
11
11
|
import { DEFAULT_PORT } from "./ports.js";
|
|
12
12
|
import TestReporter from "./reporter.js";
|
|
13
13
|
import { concurrency, planItems, poolMode, runPooled, serialKeyOf, } from "./pooled-run.js";
|
|
@@ -16,7 +16,7 @@ import { staticSkip } from "./skip.js";
|
|
|
16
16
|
import { browsersOfRun, loadSpecs, selectTests } from "./select.js";
|
|
17
17
|
import { resolveRetries } from "./retries-option.js";
|
|
18
18
|
import { runWithRetries } from "./retry.js";
|
|
19
|
-
import { resolveWorkers } from "
|
|
19
|
+
import { resolveWorkers } from "../config/workers-option.js";
|
|
20
20
|
import { WorkerPool } from "./worker-pool.js";
|
|
21
21
|
import { processWorkerFactory } from "./worker-process.js";
|
|
22
22
|
/** Finds the spec files, picks the tests and browsers of a run and runs each test in each browser */
|
|
@@ -48,9 +48,13 @@ export default class TestRunner {
|
|
|
48
48
|
async groups() {
|
|
49
49
|
return (await loadSpecs(this.testFiles)).groups;
|
|
50
50
|
}
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Imports the spec files and returns the tests the options select (by `group`, `testNames` and `grep`)
|
|
53
|
+
* with the real `srcDir` their ids are relative to
|
|
54
|
+
*/
|
|
55
|
+
async list() {
|
|
56
|
+
const loaded = await loadSpecs(this.testFiles);
|
|
57
|
+
return { tests: selectTests(loaded, this.options), srcDir: loaded.srcDir };
|
|
54
58
|
}
|
|
55
59
|
/**
|
|
56
60
|
* Runs the selected tests in every browser of the run, one browser after the other, and returns the summary that
|
|
@@ -60,7 +64,7 @@ export default class TestRunner {
|
|
|
60
64
|
const { reportPath, onEvent, signal } = this.options;
|
|
61
65
|
// The specs are imported once: their top-level code runs once per run
|
|
62
66
|
const loaded = await loadSpecs(this.testFiles);
|
|
63
|
-
const config = await
|
|
67
|
+
const config = await loadRawConfig();
|
|
64
68
|
// A focused test the config refuses stops the run before anything starts; else only the focused ones run
|
|
65
69
|
assertNoOnly(loaded.all, forbidsOnly(config), loaded.srcDir);
|
|
66
70
|
const selected = narrowToOnly(selectTests(loaded, this.options));
|
|
@@ -123,9 +127,9 @@ export default class TestRunner {
|
|
|
123
127
|
try {
|
|
124
128
|
for (const browser of browsers) {
|
|
125
129
|
for (const test of selected) {
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
reporter.onTestSkipped(test, browser,
|
|
130
|
+
const skip = staticSkip(test);
|
|
131
|
+
if (skip) {
|
|
132
|
+
reporter.onTestSkipped(test, browser, skip);
|
|
129
133
|
continue;
|
|
130
134
|
}
|
|
131
135
|
if (signal?.aborted) {
|
package/dist/steps/edit.d.ts
CHANGED
|
@@ -22,6 +22,16 @@ export type StepEdit = {
|
|
|
22
22
|
test: number;
|
|
23
23
|
from: number;
|
|
24
24
|
to: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Removes the whole test, with the comments and the blank line above it. For several tests, apply from the last index to the first.
|
|
28
|
+
* It removes all leading trivia from the end of the previous statement, so comments above the test go with it: a
|
|
29
|
+
* file-header comment when the test is the first statement, and a trailing `// comment` on the previous test's line.
|
|
30
|
+
* Throws for a test that isn't `removable`
|
|
31
|
+
*/
|
|
32
|
+
| {
|
|
33
|
+
op: "remove-test";
|
|
34
|
+
test: number;
|
|
25
35
|
};
|
|
26
36
|
/**
|
|
27
37
|
* Applies one edit and returns the new source. Only the touched statement changes, plus the test's parameters
|
package/dist/steps/edit.js
CHANGED
|
@@ -125,6 +125,10 @@ export function applyEdit(source, edit) {
|
|
|
125
125
|
}
|
|
126
126
|
case "remove":
|
|
127
127
|
return removeStep(source, parsed, edit.index);
|
|
128
|
+
case "remove-test":
|
|
129
|
+
if (!parsed.removable)
|
|
130
|
+
throw new Error(`Cannot remove test "${parsed.name}": it is not a statement of its own`);
|
|
131
|
+
return splice(source, parsed.start, parsed.end, "");
|
|
128
132
|
case "move": {
|
|
129
133
|
const { start, end } = pickStep(parsed, edit.from);
|
|
130
134
|
if (edit.to < 0 || edit.to >= parsed.steps.length)
|
package/dist/steps/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { parseSpec } from "./parse.js";
|
|
1
|
+
export { parseSpec, parseSpecFile } from "./parse.js";
|
|
2
2
|
export { applyEdit, type StepEdit } from "./edit.js";
|
|
3
3
|
export { stepToSource, locatorToSource, callToSource, filesToSource, valueToSource, } from "./emit.js";
|
|
4
4
|
export { formatSize, humanSize, parseSize, sizeFromSource } from "./files.js";
|
|
5
5
|
export { locatorFromSpec } from "./build.js";
|
|
6
|
-
export type { Expectation, FileEntry, GeneratedFileSpec, LocatorCall, LocatorSpec, ParsedStep, ParsedTest, Step, TextMatcher, TextValue, } from "./model.js";
|
|
6
|
+
export type { Expectation, FileEntry, GeneratedFileSpec, LocatorCall, LocatorSpec, ParsedStep, ParsedTest, Step, TextMatcher, TextValue, UnparsedTest, } from "./model.js";
|
package/dist/steps/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { parseSpec } from "./parse.js";
|
|
1
|
+
export { parseSpec, parseSpecFile } from "./parse.js";
|
|
2
2
|
export { applyEdit } from "./edit.js";
|
|
3
3
|
export { stepToSource, locatorToSource, callToSource, filesToSource, valueToSource, } from "./emit.js";
|
|
4
4
|
export { formatSize, humanSize, parseSize, sizeFromSource } from "./files.js";
|
package/dist/steps/model.d.ts
CHANGED
|
@@ -146,6 +146,15 @@ export interface ParsedTest {
|
|
|
146
146
|
/** Offset just after the `{` of the test body, and of its closing `}` */
|
|
147
147
|
bodyStart: number;
|
|
148
148
|
bodyEnd: number;
|
|
149
|
+
/** Where the whole test starts: the full start of its statement, so the comments and blank line above are included */
|
|
150
|
+
start: number;
|
|
151
|
+
/** Where the whole test ends: the end of its statement, after the `;` */
|
|
152
|
+
end: number;
|
|
153
|
+
/**
|
|
154
|
+
* False when the test call isn't a statement of its own (a loop or `if` body without braces, an arrow's
|
|
155
|
+
* expression body), so it can't be removed without breaking the file
|
|
156
|
+
*/
|
|
157
|
+
removable: boolean;
|
|
149
158
|
/**
|
|
150
159
|
* The fixtures the test's callback destructures, and the offset where another one goes: after the last one
|
|
151
160
|
* (`list`), inside an empty `{}` (`empty`) or inside the empty `()` of a callback without parameters (`none`).
|
|
@@ -158,4 +167,14 @@ export interface ParsedTest {
|
|
|
158
167
|
};
|
|
159
168
|
/** `skip` or `fixme` (not run), or `only` (focused), as the runner applies it: a modifier on a `describe` counts */
|
|
160
169
|
modifier?: Modifier;
|
|
170
|
+
/** The `{ reason }` written with the `skip` or `fixme` that applies, when it is a string literal */
|
|
171
|
+
reason?: string;
|
|
172
|
+
}
|
|
173
|
+
/** A `test` or `describe` call the codec can't read: its title isn't a plain string, or its function isn't written inline */
|
|
174
|
+
export interface UnparsedTest {
|
|
175
|
+
kind: "test" | "describe";
|
|
176
|
+
/** The statement's range, as for `ParsedTest` */
|
|
177
|
+
start: number;
|
|
178
|
+
end: number;
|
|
179
|
+
reason: "dynamic-title" | "not-inline";
|
|
161
180
|
}
|
package/dist/steps/parse.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
import type { ParsedTest } from "./model.js";
|
|
1
|
+
import type { ParsedTest, UnparsedTest } from "./model.js";
|
|
2
|
+
/** The tests in a spec file, with their steps and where each statement sits, and the tests and describes it can't read */
|
|
3
|
+
export declare function parseSpecFile(source: string): {
|
|
4
|
+
tests: ParsedTest[];
|
|
5
|
+
unparsed: UnparsedTest[];
|
|
6
|
+
};
|
|
2
7
|
/** The tests in a spec file, with their steps and where each statement sits */
|
|
3
8
|
export declare function parseSpec(source: string): ParsedTest[];
|
package/dist/steps/parse.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
-
import { stringOf } from "./parse/literals.js";
|
|
2
|
+
import { readObject, stringOf } from "./parse/literals.js";
|
|
3
3
|
import { readStep } from "./parse/step.js";
|
|
4
4
|
function parseStatement(source, statement, sourceFile) {
|
|
5
5
|
const start = statement.getStart(sourceFile);
|
|
@@ -57,45 +57,115 @@ function calleeOf(expression) {
|
|
|
57
57
|
};
|
|
58
58
|
return undefined;
|
|
59
59
|
}
|
|
60
|
-
/**
|
|
61
|
-
|
|
60
|
+
/**
|
|
61
|
+
* The callback of `test(title, fn)` and `describe(title, fn)`, and for a skip or fixme also of
|
|
62
|
+
* `(title, { reason }, fn)` with the reason when it is a literal
|
|
63
|
+
*/
|
|
64
|
+
function callbackOf(node, modifier) {
|
|
65
|
+
const [, second, third] = node.arguments;
|
|
66
|
+
if ((modifier === "skip" || modifier === "fixme") &&
|
|
67
|
+
second &&
|
|
68
|
+
ts.isObjectLiteralExpression(second)) {
|
|
69
|
+
const reason = readObject(second, ["reason"])?.reason;
|
|
70
|
+
return {
|
|
71
|
+
callback: third,
|
|
72
|
+
...(typeof reason === "string" && { reason }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { callback: second };
|
|
76
|
+
}
|
|
77
|
+
/** What the runner applies to a test (see `modifierOf` in the runner): the innermost `skip` or `fixme` with its reason, else `only` */
|
|
78
|
+
function effectiveMark(own, describes) {
|
|
62
79
|
const chain = [own, ...[...describes].reverse()];
|
|
63
|
-
|
|
64
|
-
|
|
80
|
+
const skip = chain.find((m) => m.modifier === "skip" || m.modifier === "fixme");
|
|
81
|
+
if (skip)
|
|
82
|
+
return {
|
|
83
|
+
modifier: skip.modifier,
|
|
84
|
+
...(skip.reason !== undefined && { reason: skip.reason }),
|
|
85
|
+
};
|
|
86
|
+
return chain.some((m) => m.modifier === "only") ? { modifier: "only" } : {};
|
|
65
87
|
}
|
|
66
|
-
/** The
|
|
67
|
-
|
|
88
|
+
/** The range of a whole test: its statement with the comments above it, or the call alone when it isn't a statement */
|
|
89
|
+
function wholeRange(call) {
|
|
90
|
+
const statement = ts.isExpressionStatement(call.parent) ? call.parent : call;
|
|
91
|
+
return { start: statement.getFullStart(), end: statement.end };
|
|
92
|
+
}
|
|
93
|
+
/** Whether the call is a statement directly inside a block, a module block or the file, so removing its range leaves valid code */
|
|
94
|
+
function isRemovable(call) {
|
|
95
|
+
const statement = call.parent;
|
|
96
|
+
if (!ts.isExpressionStatement(statement))
|
|
97
|
+
return false;
|
|
98
|
+
const container = statement.parent;
|
|
99
|
+
return (ts.isBlock(container) ||
|
|
100
|
+
ts.isSourceFile(container) ||
|
|
101
|
+
ts.isModuleBlock(container));
|
|
102
|
+
}
|
|
103
|
+
/** A test or describe the codec can't read, with where its statement sits */
|
|
104
|
+
function unreadable(node, kind, reason) {
|
|
105
|
+
return { kind, reason, ...wholeRange(node) };
|
|
106
|
+
}
|
|
107
|
+
/** `test.skip(condition, reason)` inside a body: it takes a condition where a test takes a title, so it is neither a test nor unparsed */
|
|
108
|
+
function isConditionForm(node, callee) {
|
|
109
|
+
const [first] = node.arguments;
|
|
110
|
+
return ((callee.modifier === "skip" || callee.modifier === "fixme") &&
|
|
111
|
+
!(first &&
|
|
112
|
+
(ts.isStringLiteral(first) ||
|
|
113
|
+
ts.isNoSubstitutionTemplateLiteral(first) ||
|
|
114
|
+
ts.isTemplateExpression(first))));
|
|
115
|
+
}
|
|
116
|
+
/** The tests in a spec file, with their steps and where each statement sits, and the tests and describes it can't read */
|
|
117
|
+
export function parseSpecFile(source) {
|
|
68
118
|
const sourceFile = ts.createSourceFile("spec.ts", source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
69
119
|
const tests = [];
|
|
120
|
+
const unparsed = [];
|
|
70
121
|
const visit = (node, titles, describes) => {
|
|
71
122
|
const callee = ts.isCallExpression(node)
|
|
72
123
|
? calleeOf(node.expression)
|
|
73
124
|
: undefined;
|
|
74
|
-
if (ts.isCallExpression(node) &&
|
|
125
|
+
if (ts.isCallExpression(node) &&
|
|
126
|
+
callee &&
|
|
127
|
+
(callee.name === "test" || callee.name === "describe") &&
|
|
128
|
+
!(callee.name === "test" && isConditionForm(node, callee))) {
|
|
129
|
+
const kind = callee.name;
|
|
75
130
|
const title = stringOf(node.arguments[0]);
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
131
|
+
const { callback, reason } = callbackOf(node, callee.modifier);
|
|
132
|
+
const body = callbackBody(callback);
|
|
133
|
+
if (title === undefined) {
|
|
134
|
+
unparsed.push(unreadable(node, kind, "dynamic-title"));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!body) {
|
|
138
|
+
unparsed.push(unreadable(node, kind, "not-inline"));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const mark = {
|
|
142
|
+
...(callee.modifier && { modifier: callee.modifier }),
|
|
143
|
+
...(reason !== undefined && { reason }),
|
|
144
|
+
};
|
|
145
|
+
if (kind === "test") {
|
|
79
146
|
const titlePath = [...titles, title];
|
|
80
|
-
const modifier = effectiveModifier(callee.modifier, describes);
|
|
81
147
|
tests.push({
|
|
82
148
|
titlePath,
|
|
83
149
|
name: titlePath.join(" > "),
|
|
84
150
|
steps: body.statements.map((statement) => parseStatement(source, statement, sourceFile)),
|
|
85
151
|
bodyStart: body.getStart(sourceFile) + 1,
|
|
86
152
|
bodyEnd: body.end - 1,
|
|
87
|
-
|
|
88
|
-
|
|
153
|
+
...wholeRange(node),
|
|
154
|
+
removable: isRemovable(node),
|
|
155
|
+
fixtures: callbackFixtures(callback, sourceFile),
|
|
156
|
+
...effectiveMark(mark, describes),
|
|
89
157
|
});
|
|
90
158
|
return;
|
|
91
159
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
160
|
+
ts.forEachChild(body, (child) => visit(child, [...titles, title], [...describes, mark]));
|
|
161
|
+
return;
|
|
96
162
|
}
|
|
97
163
|
ts.forEachChild(node, (child) => visit(child, titles, describes));
|
|
98
164
|
};
|
|
99
165
|
visit(sourceFile, [], []);
|
|
100
|
-
return tests;
|
|
166
|
+
return { tests, unparsed };
|
|
167
|
+
}
|
|
168
|
+
/** The tests in a spec file, with their steps and where each statement sits */
|
|
169
|
+
export function parseSpec(source) {
|
|
170
|
+
return parseSpecFile(source).tests;
|
|
101
171
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { BiDiCommands, BiDiEvents } from "../types/bidi.js";
|
|
2
2
|
import { type EventName, type Subscription, type SubscribeOptions } from "./subscriptions.js";
|
|
3
|
-
/** Time (ms) a command may wait for its reply before it fails with code "timeout" */
|
|
4
|
-
export declare const DEFAULT_COMMAND_TIMEOUT = 30000;
|
|
5
3
|
export interface ConnectorOptions {
|
|
6
4
|
/** @default DEFAULT_COMMAND_TIMEOUT */
|
|
7
5
|
commandTimeout?: number;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import EventEmitter from "node:events";
|
|
2
|
+
import { DEFAULT_COMMAND_TIMEOUT } from "../config/defaults.js";
|
|
2
3
|
import logger from "../logger/index.js";
|
|
3
4
|
import { WaitTimeoutError } from "../wait/wait-until.js";
|
|
4
5
|
import { BiDiError } from "./bidi-error.js";
|
|
5
6
|
import { forLog } from "./log-redaction.js";
|
|
6
7
|
import { SubscriptionManager, } from "./subscriptions.js";
|
|
7
|
-
/** Time (ms) a command may wait for its reply before it fails with code "timeout" */
|
|
8
|
-
export const DEFAULT_COMMAND_TIMEOUT = 30000;
|
|
9
8
|
/**
|
|
10
9
|
* The connection to the browser is gone (the browser exited or was closed, or the socket dropped). Commands that
|
|
11
10
|
* were waiting fail with it, and so does every command sent afterwards: a closed socket would swallow them silently.
|
package/dist/types/test.d.ts
CHANGED
|
@@ -21,6 +21,12 @@ export type TestCase = TestCaseBase;
|
|
|
21
21
|
/** `skip`: not run. `fixme`: not run, known to be broken. `only`: the only test that runs when any is focused */
|
|
22
22
|
export type Modifier = "skip" | "fixme" | "only";
|
|
23
23
|
|
|
24
|
+
/** The optional second argument of `test.skip`, `test.fixme`, `describe.skip` and `describe.fixme` */
|
|
25
|
+
export interface TestDetails {
|
|
26
|
+
/** Why the tests are not run; shown in the report and by `samurai list` */
|
|
27
|
+
reason?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
24
30
|
/** Runs before or after each test of a suite, in the test's browser, with the test's fixtures */
|
|
25
31
|
export type EachHook = (fixtures: TestFixtures) => Promise<void> | void;
|
|
26
32
|
|
|
@@ -39,6 +45,8 @@ export interface Suite {
|
|
|
39
45
|
title?: string;
|
|
40
46
|
parent?: Suite;
|
|
41
47
|
modifier?: Modifier;
|
|
48
|
+
/** The `{ reason }` of a `describe.skip` or `describe.fixme` */
|
|
49
|
+
reason?: string;
|
|
42
50
|
beforeEach?: EachHook[];
|
|
43
51
|
afterEach?: EachHook[];
|
|
44
52
|
beforeAll?: AllHook[];
|
|
@@ -54,6 +62,8 @@ export interface RegisteredTestCase extends TestCaseBase {
|
|
|
54
62
|
suite: Suite;
|
|
55
63
|
/** What applies to the test: its own modifier, or the one of a suite around it */
|
|
56
64
|
modifier?: Modifier;
|
|
65
|
+
/** The reason given with the `skip` or `fixme` that applies */
|
|
66
|
+
reason?: string;
|
|
57
67
|
}
|
|
58
68
|
|
|
59
69
|
export interface TestCaseBase {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itmetsam/samurai-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
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": {
|
|
@@ -48,6 +48,10 @@
|
|
|
48
48
|
"types": "./dist/project/index.d.ts",
|
|
49
49
|
"default": "./dist/project/index.js"
|
|
50
50
|
},
|
|
51
|
+
"./capabilities": {
|
|
52
|
+
"types": "./dist/capabilities.d.ts",
|
|
53
|
+
"default": "./dist/capabilities.js"
|
|
54
|
+
},
|
|
51
55
|
"./package.json": "./package.json"
|
|
52
56
|
},
|
|
53
57
|
"scripts": {
|
|
@@ -55,7 +59,7 @@
|
|
|
55
59
|
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/copy-types.mjs",
|
|
56
60
|
"prepack": "npm run build",
|
|
57
61
|
"test": "SAMURAI_LOG_LEVEL=${SAMURAI_LOG_LEVEL:-warn} tsx --import ./scripts/test-tmp.mjs --test --test-timeout=10000 \"src/**/*.test.ts\"",
|
|
58
|
-
"test:browser": "SAMURAI_LOG_LEVEL=${SAMURAI_LOG_LEVEL:-warn} tsx --import ./scripts/test-tmp.mjs --test --test-concurrency=1 --test-timeout=60000 \"src/**/*.browser-test.ts\"",
|
|
62
|
+
"test:browser": "SAMURAI_LOG_LEVEL=${SAMURAI_LOG_LEVEL:-warn} tsx --import ./scripts/test-tmp.mjs --test --test-concurrency=1 --test-timeout=60000 ${SAMURAI_TEST_SHARD:+--test-shard=$SAMURAI_TEST_SHARD} \"src/**/*.browser-test.ts\"",
|
|
59
63
|
"test:browser:chrome": "SAMURAI_TEST_BROWSER=chrome npm run test:browser",
|
|
60
64
|
"test:cli": "tsx --import ./scripts/test-tmp.mjs --test --test-concurrency=1 \"src/**/*.cli-test.ts\""
|
|
61
65
|
},
|
|
File without changes
|
|
File without changes
|