@lingxia/test 0.12.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/expect.d.ts +26 -0
- package/dist/expect.d.ts.map +1 -0
- package/dist/expect.js +220 -0
- package/dist/expect.js.map +1 -0
- package/dist/fixture.d.ts +96 -0
- package/dist/fixture.d.ts.map +1 -0
- package/dist/fixture.js +703 -0
- package/dist/fixture.js.map +1 -0
- package/dist/format.d.ts +14 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +179 -0
- package/dist/format.js.map +1 -0
- package/dist/host.d.ts +29 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +204 -0
- package/dist/host.js.map +1 -0
- package/dist/ids.d.ts +26 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +92 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +24 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +38 -0
- package/dist/inventory.js.map +1 -0
- package/dist/junit.d.ts +8 -0
- package/dist/junit.d.ts.map +1 -0
- package/dist/junit.js +97 -0
- package/dist/junit.js.map +1 -0
- package/dist/locator.d.ts +62 -0
- package/dist/locator.d.ts.map +1 -0
- package/dist/locator.js +124 -0
- package/dist/locator.js.map +1 -0
- package/dist/report.d.ts +15 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +967 -0
- package/dist/report.js.map +1 -0
- package/dist/runtime.d.ts +33 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +487 -0
- package/dist/runtime.js.map +1 -0
- package/dist/spec-api.d.ts +15 -0
- package/dist/spec-api.d.ts.map +1 -0
- package/dist/spec-api.js +2 -0
- package/dist/spec-api.js.map +1 -0
- package/dist/types.d.ts +234 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +21 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +21 -0
- package/dist/version.js.map +1 -0
- package/package.json +56 -0
package/dist/ids.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { spec, expect, run, reset, trackPublicSurface } from "./runtime.js";
|
|
2
|
+
export { AssertionError, logAssertion, setAssertionSink } from "./expect.js";
|
|
3
|
+
export { TimeoutError } from "./fixture.js";
|
|
4
|
+
export { renderJUnit } from "./junit.js";
|
|
5
|
+
export { PUBLIC_CAPABILITIES } from "./inventory.js";
|
|
6
|
+
export type { Capability, CapabilityLayer } from "./inventory.js";
|
|
7
|
+
export { VERSION, PACKAGE_NAME, DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_SPEC_TIMEOUT_MS, } from "./version.js";
|
|
8
|
+
export type { Apps, AssertionRecord, AttachmentRef, CaseRecord, ExpectOptions, Fixture, FixtureExpect, JsonReport, RunMeta, LingxiaTestController, Locator, LocatorMatchers, Matchers, ProtocolReport, RejectExpected, RetryMatchers, SpecBody, SpecOptions, SpecStatus, StepRecord, TestApp, TestPage, } from "./types.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EACL,OAAO,EACP,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,IAAI,EACJ,eAAe,EACf,aAAa,EACb,UAAU,EACV,aAAa,EACb,OAAO,EACP,aAAa,EACb,UAAU,EACV,OAAO,EACP,qBAAqB,EACrB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,cAAc,EACd,cAAc,EACd,aAAa,EACb,QAAQ,EACR,WAAW,EACX,UAAU,EACV,UAAU,EACV,OAAO,EACP,QAAQ,GACT,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { spec, expect, run, reset, trackPublicSurface } from "./runtime.js";
|
|
2
|
+
export { AssertionError, logAssertion, setAssertionSink } from "./expect.js";
|
|
3
|
+
export { TimeoutError } from "./fixture.js";
|
|
4
|
+
export { renderJUnit } from "./junit.js";
|
|
5
|
+
export { PUBLIC_CAPABILITIES } from "./inventory.js";
|
|
6
|
+
export { VERSION, PACKAGE_NAME, DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_SPEC_TIMEOUT_MS, } from "./version.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EACL,OAAO,EACP,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type CapabilityLayer = "logic" | "automation" | "object";
|
|
2
|
+
export interface Capability {
|
|
3
|
+
/** Canonical cover tag, e.g. `lx.fs.readFile` or `DownloadTask.wait`. */
|
|
4
|
+
name: string;
|
|
5
|
+
layer: CapabilityLayer;
|
|
6
|
+
/** Display bucket — the owning surface. */
|
|
7
|
+
group: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const LAYER_TITLE: Record<CapabilityLayer, string>;
|
|
10
|
+
/**
|
|
11
|
+
* The layers a coverage report is about. The automation drivers are the
|
|
12
|
+
* harness — how a suite tests — not the cross-platform API an lxapp calls, so
|
|
13
|
+
* they are deliberately not measured as product coverage.
|
|
14
|
+
*/
|
|
15
|
+
export declare const MEASURED_LAYERS: readonly CapabilityLayer[];
|
|
16
|
+
export declare function isMeasured(layer: CapabilityLayer): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The published public surface, straight from `@lingxia/types`. The report
|
|
19
|
+
* measures a run against this rather than against the tags a suite happens to
|
|
20
|
+
* declare, so a capability nobody wrote a spec for still shows as a hole.
|
|
21
|
+
*/
|
|
22
|
+
export declare const PUBLIC_CAPABILITIES: Capability[];
|
|
23
|
+
export declare const CAPABILITY_INDEX: Map<string, Capability>;
|
|
24
|
+
//# sourceMappingURL=inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEhE,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAIvD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,eAAe,EAAwB,CAAC;AAE/E,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAE1D;AAkBD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAAU,EAAY,CAAC;AAEzD,eAAO,MAAM,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAEpD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LX_RETURNED_OBJECT_SURFACES, LX_RUNTIME_SURFACES, } from "@lingxia/types/testing";
|
|
2
|
+
export const LAYER_TITLE = {
|
|
3
|
+
logic: "Logic API (lx.*)",
|
|
4
|
+
object: "Objects returned by lx APIs",
|
|
5
|
+
automation: "Automation drivers",
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* The layers a coverage report is about. The automation drivers are the
|
|
9
|
+
* harness — how a suite tests — not the cross-platform API an lxapp calls, so
|
|
10
|
+
* they are deliberately not measured as product coverage.
|
|
11
|
+
*/
|
|
12
|
+
export const MEASURED_LAYERS = ["logic", "object"];
|
|
13
|
+
export function isMeasured(layer) {
|
|
14
|
+
return MEASURED_LAYERS.includes(layer);
|
|
15
|
+
}
|
|
16
|
+
function build() {
|
|
17
|
+
const out = [];
|
|
18
|
+
for (const surface of LX_RUNTIME_SURFACES) {
|
|
19
|
+
const layer = surface.layer === "logic" ? "logic" : "automation";
|
|
20
|
+
for (const member of surface.members) {
|
|
21
|
+
out.push({ name: `${surface.name}.${member}`, layer, group: surface.name });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
for (const surface of LX_RETURNED_OBJECT_SURFACES) {
|
|
25
|
+
for (const member of surface.members) {
|
|
26
|
+
out.push({ name: `${surface.name}.${member}`, layer: "object", group: surface.name });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The published public surface, straight from `@lingxia/types`. The report
|
|
33
|
+
* measures a run against this rather than against the tags a suite happens to
|
|
34
|
+
* declare, so a capability nobody wrote a spec for still shows as a hole.
|
|
35
|
+
*/
|
|
36
|
+
export const PUBLIC_CAPABILITIES = build();
|
|
37
|
+
export const CAPABILITY_INDEX = new Map(PUBLIC_CAPABILITIES.map((entry) => [entry.name, entry]));
|
|
38
|
+
//# sourceMappingURL=inventory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAYhC,MAAM,CAAC,MAAM,WAAW,GAAoC;IAC1D,KAAK,EAAE,kBAAkB;IACzB,MAAM,EAAE,6BAA6B;IACrC,UAAU,EAAE,oBAAoB;CACjC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAA+B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAE/E,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,KAAK;IACZ,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAoB,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;QAClF,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,2BAA2B,EAAE,CAAC;QAClD,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB,KAAK,EAAE,CAAC;AAEzD,MAAM,CAAC,MAAM,gBAAgB,GAA4B,IAAI,GAAG,CAC9D,mBAAmB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CACxD,CAAC"}
|
package/dist/junit.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { JsonReport } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* JUnit XML is what CI dashboards (GitHub, GitLab, Jenkins, Azure) ingest, so
|
|
4
|
+
* every run emits one next to the HTML report. `xfail` counts as a pass and
|
|
5
|
+
* `xpass` as a failure, matching how the run itself is graded.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderJUnit(report: JsonReport): string;
|
|
8
|
+
//# sourceMappingURL=junit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"junit.d.ts","sourceRoot":"","sources":["../src/junit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,YAAY,CAAC;AAGzD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAiBtD"}
|
package/dist/junit.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { PACKAGE_NAME } from "./version.js";
|
|
2
|
+
/**
|
|
3
|
+
* JUnit XML is what CI dashboards (GitHub, GitLab, Jenkins, Azure) ingest, so
|
|
4
|
+
* every run emits one next to the HTML report. `xfail` counts as a pass and
|
|
5
|
+
* `xpass` as a failure, matching how the run itself is graded.
|
|
6
|
+
*/
|
|
7
|
+
export function renderJUnit(report) {
|
|
8
|
+
const suites = new Map();
|
|
9
|
+
for (const item of report.cases) {
|
|
10
|
+
const name = item.suite ?? "specs";
|
|
11
|
+
const bucket = suites.get(name) ?? [];
|
|
12
|
+
bucket.push(item);
|
|
13
|
+
suites.set(name, bucket);
|
|
14
|
+
}
|
|
15
|
+
const timestamp = report.meta?.started_at || new Date(0).toISOString();
|
|
16
|
+
const body = [...suites.entries()]
|
|
17
|
+
.map(([name, cases]) => renderSuite(name, cases, timestamp))
|
|
18
|
+
.join("");
|
|
19
|
+
const failures = report.failed + report.timeout + report.xpass;
|
|
20
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
21
|
+
<testsuites name="${attr(PACKAGE_NAME)}" tests="${report.total}" failures="${failures}" errors="0" skipped="${report.skipped}" time="${seconds(report.duration_ms)}">
|
|
22
|
+
${body}</testsuites>
|
|
23
|
+
`;
|
|
24
|
+
}
|
|
25
|
+
function renderSuite(name, cases, timestamp) {
|
|
26
|
+
const failures = cases.filter((item) => graded(item) === "failure").length;
|
|
27
|
+
const skipped = cases.filter((item) => graded(item) === "skipped").length;
|
|
28
|
+
const time = cases.reduce((sum, item) => sum + item.duration_ms, 0);
|
|
29
|
+
const body = cases.map((item) => renderCase(item, name)).join("");
|
|
30
|
+
return ` <testsuite name="${attr(name)}" tests="${cases.length}" failures="${failures}" errors="0" skipped="${skipped}" time="${seconds(time)}" timestamp="${attr(timestamp)}">
|
|
31
|
+
${body} </testsuite>
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
function renderCase(item, suite) {
|
|
35
|
+
const attrs = [
|
|
36
|
+
`name="${attr(item.title)}"`,
|
|
37
|
+
`classname="${attr(suite)}"`,
|
|
38
|
+
`time="${seconds(item.duration_ms)}"`,
|
|
39
|
+
item.file ? `file="${attr(item.file)}"` : "",
|
|
40
|
+
item.line ? `line="${item.line}"` : "",
|
|
41
|
+
].filter(Boolean).join(" ");
|
|
42
|
+
const verdict = graded(item);
|
|
43
|
+
const inner = [];
|
|
44
|
+
if (verdict === "skipped") {
|
|
45
|
+
inner.push(` <skipped message="${attr(item.reason ?? "pending")}"/>\n`);
|
|
46
|
+
}
|
|
47
|
+
else if (verdict === "failure") {
|
|
48
|
+
const error = item.error;
|
|
49
|
+
const detail = error
|
|
50
|
+
? `${error.message}${error.stack ? `\n\n${error.stack}` : ""}`
|
|
51
|
+
: `spec finished as ${item.status}`;
|
|
52
|
+
inner.push(` <failure message="${attr(firstLine(error?.message ?? item.status))}" type="${attr(error?.name ?? "Error")}">${text(detail)}</failure>\n`);
|
|
53
|
+
}
|
|
54
|
+
if (item.status === "xfail") {
|
|
55
|
+
inner.push(` <system-out>${text("spec.fail: failed as declared")}</system-out>\n`);
|
|
56
|
+
}
|
|
57
|
+
if (item.covers.length > 0) {
|
|
58
|
+
inner.push(` <properties>\n <property name="covers" value="${attr(item.covers.join(" "))}"/>\n </properties>\n`);
|
|
59
|
+
}
|
|
60
|
+
return inner.length === 0
|
|
61
|
+
? ` <testcase ${attrs}/>\n`
|
|
62
|
+
: ` <testcase ${attrs}>\n${inner.join("")} </testcase>\n`;
|
|
63
|
+
}
|
|
64
|
+
function graded(item) {
|
|
65
|
+
if (item.status === "skipped")
|
|
66
|
+
return "skipped";
|
|
67
|
+
if (item.status === "passed" || item.status === "xfail")
|
|
68
|
+
return "success";
|
|
69
|
+
return "failure";
|
|
70
|
+
}
|
|
71
|
+
function seconds(ms) {
|
|
72
|
+
return (ms / 1000).toFixed(3);
|
|
73
|
+
}
|
|
74
|
+
function firstLine(value) {
|
|
75
|
+
const cut = value.indexOf("\n");
|
|
76
|
+
return cut === -1 ? value : value.slice(0, cut);
|
|
77
|
+
}
|
|
78
|
+
/** XML 1.0 forbids most control characters outright — drop them, don't escape. */
|
|
79
|
+
function scrub(value) {
|
|
80
|
+
let out = "";
|
|
81
|
+
for (const ch of value) {
|
|
82
|
+
const code = ch.codePointAt(0);
|
|
83
|
+
if (code === 0x09 || code === 0x0a || code === 0x0d || code >= 0x20)
|
|
84
|
+
out += ch;
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
function text(value) {
|
|
89
|
+
return scrub(value)
|
|
90
|
+
.replace(/&/g, "&")
|
|
91
|
+
.replace(/</g, "<")
|
|
92
|
+
.replace(/>/g, ">");
|
|
93
|
+
}
|
|
94
|
+
function attr(value) {
|
|
95
|
+
return text(value).replace(/"/g, """).replace(/\n/g, " ");
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=junit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"junit.js","sourceRoot":"","sources":["../src/junit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ExpectOptions, Locator, SourceLocation } from "./types.js";
|
|
2
|
+
export interface QueryMatch {
|
|
3
|
+
exists: boolean;
|
|
4
|
+
count: number;
|
|
5
|
+
index?: number;
|
|
6
|
+
visible?: boolean;
|
|
7
|
+
text?: string;
|
|
8
|
+
value?: string | null;
|
|
9
|
+
items?: QueryMatch[];
|
|
10
|
+
}
|
|
11
|
+
export interface PageLike {
|
|
12
|
+
query(options: {
|
|
13
|
+
css: string;
|
|
14
|
+
all?: boolean;
|
|
15
|
+
index?: number;
|
|
16
|
+
}): Promise<QueryMatch>;
|
|
17
|
+
click(options: {
|
|
18
|
+
css: string;
|
|
19
|
+
index?: number;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
fill(options: {
|
|
22
|
+
css: string;
|
|
23
|
+
text: string;
|
|
24
|
+
index?: number;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
type(options: {
|
|
27
|
+
css: string;
|
|
28
|
+
text: string;
|
|
29
|
+
index?: number;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export type Guard = <T>(op: () => T | Promise<T>) => Promise<T>;
|
|
33
|
+
/** Records one locator action in the report's trace. */
|
|
34
|
+
export type ActionRecorder = <T>(verb: string, detail: string, op: () => Promise<T>) => Promise<T>;
|
|
35
|
+
export interface LocatorResolve {
|
|
36
|
+
count: number;
|
|
37
|
+
visibleCount: number;
|
|
38
|
+
attached: boolean;
|
|
39
|
+
visible: boolean;
|
|
40
|
+
text: string;
|
|
41
|
+
value: string | null;
|
|
42
|
+
index: number;
|
|
43
|
+
kind: "nothing" | "hidden" | "unique" | "many";
|
|
44
|
+
}
|
|
45
|
+
export declare function testIdSelector(id: string): string;
|
|
46
|
+
export declare class PageLocator implements Locator {
|
|
47
|
+
private readonly page;
|
|
48
|
+
private readonly guard;
|
|
49
|
+
private readonly record;
|
|
50
|
+
private readonly location;
|
|
51
|
+
readonly selector: string;
|
|
52
|
+
constructor(page: PageLike, guard: Guard, record: ActionRecorder, selector: string, location: SourceLocation);
|
|
53
|
+
click(options?: ExpectOptions): Promise<void>;
|
|
54
|
+
fill(text: string, options?: ExpectOptions): Promise<void>;
|
|
55
|
+
type(text: string, options?: ExpectOptions): Promise<void>;
|
|
56
|
+
query(): Promise<QueryMatch>;
|
|
57
|
+
resolve(): Promise<LocatorResolve>;
|
|
58
|
+
missText(resolved: LocatorResolve): string;
|
|
59
|
+
private act;
|
|
60
|
+
}
|
|
61
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
62
|
+
//# sourceMappingURL=locator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locator.d.ts","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"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"}
|
package/dist/locator.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { AssertionError } from "./expect.js";
|
|
2
|
+
import { cssEscape, formatValue } from "./format.js";
|
|
3
|
+
import { displayLocation } from "./ids.js";
|
|
4
|
+
import { DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_POLL_INTERVAL_MS, } from "./version.js";
|
|
5
|
+
export function testIdSelector(id) {
|
|
6
|
+
return `[data-testid="${cssEscape(id)}"]`;
|
|
7
|
+
}
|
|
8
|
+
export class PageLocator {
|
|
9
|
+
constructor(page, guard, record, selector, location) {
|
|
10
|
+
this.page = page;
|
|
11
|
+
this.guard = guard;
|
|
12
|
+
this.record = record;
|
|
13
|
+
this.location = location;
|
|
14
|
+
this.selector = selector;
|
|
15
|
+
}
|
|
16
|
+
async click(options) {
|
|
17
|
+
await this.act("click", options, (css, index) => this.page.click({ css, index }));
|
|
18
|
+
}
|
|
19
|
+
async fill(text, options) {
|
|
20
|
+
await this.act("fill", options, (css, index) => this.page.fill({ css, text, index }));
|
|
21
|
+
}
|
|
22
|
+
async type(text, options) {
|
|
23
|
+
await this.act("type", options, (css, index) => this.page.type({ css, text, index }));
|
|
24
|
+
}
|
|
25
|
+
async query() {
|
|
26
|
+
return this.guard(() => this.page.query({ css: this.selector }));
|
|
27
|
+
}
|
|
28
|
+
async resolve() {
|
|
29
|
+
const all = await this.guard(() => this.page.query({ css: this.selector, all: true }));
|
|
30
|
+
const items = Array.isArray(all.items) ? all.items : all.exists ? [all] : [];
|
|
31
|
+
const count = typeof all.count === "number" ? all.count : items.length;
|
|
32
|
+
const visibleItems = items.filter((item) => item.visible);
|
|
33
|
+
const visibleCount = visibleItems.length;
|
|
34
|
+
if (count === 0) {
|
|
35
|
+
return {
|
|
36
|
+
count: 0,
|
|
37
|
+
visibleCount: 0,
|
|
38
|
+
attached: false,
|
|
39
|
+
visible: false,
|
|
40
|
+
text: "",
|
|
41
|
+
value: null,
|
|
42
|
+
index: 0,
|
|
43
|
+
kind: "nothing",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (visibleCount === 0) {
|
|
47
|
+
return {
|
|
48
|
+
count,
|
|
49
|
+
visibleCount: 0,
|
|
50
|
+
attached: true,
|
|
51
|
+
visible: false,
|
|
52
|
+
text: items[0]?.text ?? "",
|
|
53
|
+
value: items[0]?.value ?? null,
|
|
54
|
+
index: items[0]?.index ?? 0,
|
|
55
|
+
kind: "hidden",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (visibleCount > 1) {
|
|
59
|
+
return {
|
|
60
|
+
count,
|
|
61
|
+
visibleCount,
|
|
62
|
+
attached: true,
|
|
63
|
+
visible: true,
|
|
64
|
+
text: visibleItems.map((item) => item.text ?? "").join("\n"),
|
|
65
|
+
value: visibleItems[0]?.value ?? null,
|
|
66
|
+
index: visibleItems[0]?.index ?? 0,
|
|
67
|
+
kind: "many",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const unique = visibleItems[0];
|
|
71
|
+
return {
|
|
72
|
+
count,
|
|
73
|
+
visibleCount: 1,
|
|
74
|
+
attached: true,
|
|
75
|
+
visible: true,
|
|
76
|
+
text: unique.text ?? "",
|
|
77
|
+
value: unique.value ?? null,
|
|
78
|
+
index: unique.index ?? items.indexOf(unique),
|
|
79
|
+
kind: "unique",
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
missText(resolved) {
|
|
83
|
+
if (resolved.kind === "nothing") {
|
|
84
|
+
return `locator ${formatValue(this.selector)} resolved to nothing`;
|
|
85
|
+
}
|
|
86
|
+
if (resolved.kind === "hidden") {
|
|
87
|
+
return `locator ${formatValue(this.selector)} resolved to hidden`;
|
|
88
|
+
}
|
|
89
|
+
if (resolved.kind === "many") {
|
|
90
|
+
return `locator ${formatValue(this.selector)} resolved to ${resolved.visibleCount} matches`;
|
|
91
|
+
}
|
|
92
|
+
return `locator ${formatValue(this.selector)} resolved to a visible element`;
|
|
93
|
+
}
|
|
94
|
+
async act(verb, options, run) {
|
|
95
|
+
const timeout = options?.timeout ?? DEFAULT_ACTION_TIMEOUT_MS;
|
|
96
|
+
const interval = options?.interval ?? DEFAULT_POLL_INTERVAL_MS;
|
|
97
|
+
const started = Date.now();
|
|
98
|
+
let last;
|
|
99
|
+
while (true) {
|
|
100
|
+
last = await this.resolve();
|
|
101
|
+
if (last.kind === "unique") {
|
|
102
|
+
await this.record(`page.${verb}`, this.selector, () => this.guard(() => run(this.selector, last.index)));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (Date.now() - started >= timeout)
|
|
106
|
+
break;
|
|
107
|
+
await sleep(interval);
|
|
108
|
+
}
|
|
109
|
+
const resolved = last ?? await this.resolve();
|
|
110
|
+
const duration = Date.now() - started;
|
|
111
|
+
const where = displayLocation(this.location.source, this.location.line, this.location.column);
|
|
112
|
+
throw new AssertionError(verb, resolved.kind, "visible unique element", [
|
|
113
|
+
`Timed out after ${duration}ms waiting to ${verb} ${formatValue(this.selector)}.`,
|
|
114
|
+
this.missText(resolved),
|
|
115
|
+
`at ${where}`,
|
|
116
|
+
].join("\n"));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function sleep(ms) {
|
|
120
|
+
return new Promise((resolve) => {
|
|
121
|
+
setTimeout(resolve, ms);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=locator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locator.js","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"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"}
|
package/dist/report.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CaseRecord, JsonReport } from "./types.js";
|
|
2
|
+
export declare function renderHtml(report: JsonReport): string;
|
|
3
|
+
export declare function formatDuration(ms: number): string;
|
|
4
|
+
interface Inlined {
|
|
5
|
+
/** `data:` URL for an image. */
|
|
6
|
+
dataUrl?: string;
|
|
7
|
+
/** Decoded text for a text/JSON attachment. */
|
|
8
|
+
text?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function rememberInline(specId: string, name: string, payload: Inlined): void;
|
|
11
|
+
export declare function clearInline(): void;
|
|
12
|
+
export declare function dataUrl(mimeType: string, base64: string): string;
|
|
13
|
+
export declare function countStatuses(cases: CaseRecord[]): Omit<JsonReport, "framework" | "meta" | "partial" | "filtered" | "duration_ms" | "cases">;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,UAAU,EACV,UAAU,EAGX,MAAM,YAAY,CAAC;AAsDpB,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAmGrD;AA4hBD,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,UAAU,OAAO;IACf,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAOnF;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAMD,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,EAAE,GAClB,IAAI,CAAC,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,GAAG,OAAO,CAAC,CAW3F"}
|