@piwitests/reporter 0.44.0 → 0.46.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/cli/index.js +539 -244
- package/dist/global-setup-module.js +138 -0
- package/dist/index.d.ts +116 -2
- package/dist/index.js +3124 -377
- package/dist/internal/capture/attachments.d.ts +1 -0
- package/dist/internal/capture/attachments.js +2 -1
- package/dist/internal/capture/capture-fixtures.d.ts +374 -5
- package/dist/internal/capture/capture-fixtures.js +1136 -113
- package/dist/internal/capture/locator-healing.js +9 -7
- package/dist/internal/capture/pick-on-failure.js +130 -37
- package/package.json +1 -1
- package/templates/skills/apply-locator-healing/SKILL.md +2 -0
- package/templates/skills/investigate-failure/SKILL.md +5 -1
- package/templates/skills/write-the-missing-test/SKILL.md +9 -2
|
@@ -83,9 +83,12 @@ var DEFAULTS = {
|
|
|
83
83
|
// Off by default: JavaScript coverage slows the page, so a scheduled job opts in.
|
|
84
84
|
captureCodeReach: false,
|
|
85
85
|
captureServerTraces: true,
|
|
86
|
+
captureResources: true,
|
|
87
|
+
leakCheck: "report",
|
|
86
88
|
sampleAriaOnPass: true,
|
|
87
89
|
uploadManifest: true,
|
|
88
90
|
defaultCapture: true,
|
|
91
|
+
checkBaseUrl: false,
|
|
89
92
|
streaming: true,
|
|
90
93
|
streamingBatchSize: 5,
|
|
91
94
|
streamingBatchDelay: 2e3,
|
|
@@ -123,9 +126,12 @@ var PIWI_ENV_KEYS = {
|
|
|
123
126
|
captureCodeReach: "PIWI_CAPTURE_CODE_REACH",
|
|
124
127
|
codeReachRoots: "PIWI_CODE_REACH_ROOTS",
|
|
125
128
|
captureServerTraces: "PIWI_CAPTURE_SERVER_TRACES",
|
|
129
|
+
captureResources: "PIWI_CAPTURE_RESOURCES",
|
|
130
|
+
leakCheck: "PIWI_LEAK_CHECK",
|
|
126
131
|
sampleAriaOnPass: "PIWI_SAMPLE_ARIA_ON_PASS",
|
|
127
132
|
uploadManifest: "PIWI_UPLOAD_MANIFEST",
|
|
128
133
|
defaultCapture: "PIWI_DEFAULT_CAPTURE",
|
|
134
|
+
checkBaseUrl: "PIWI_CHECK_BASE_URL",
|
|
129
135
|
inspectOnFailure: "PIWI_INSPECT_ON_FAIL",
|
|
130
136
|
pickLocatorOnFailure: "PIWI_PICK_LOCATOR_ON_FAIL",
|
|
131
137
|
outputFile: "PIWI_OUTPUT_FILE",
|
|
@@ -168,9 +174,12 @@ var ENV_FALLBACK_SPECS = [
|
|
|
168
174
|
{ option: "capturePageInventory", env: PIWI_ENV_KEYS.capturePageInventory, kind: "bool" },
|
|
169
175
|
{ option: "captureCodeReach", env: PIWI_ENV_KEYS.captureCodeReach, kind: "bool" },
|
|
170
176
|
{ option: "captureServerTraces", env: PIWI_ENV_KEYS.captureServerTraces, kind: "bool" },
|
|
177
|
+
{ option: "captureResources", env: PIWI_ENV_KEYS.captureResources, kind: "bool" },
|
|
178
|
+
{ option: "leakCheck", env: PIWI_ENV_KEYS.leakCheck, kind: "string" },
|
|
171
179
|
{ option: "sampleAriaOnPass", env: PIWI_ENV_KEYS.sampleAriaOnPass, kind: "bool" },
|
|
172
180
|
{ option: "uploadManifest", env: PIWI_ENV_KEYS.uploadManifest, kind: "bool" },
|
|
173
181
|
{ option: "defaultCapture", env: PIWI_ENV_KEYS.defaultCapture, kind: "bool" },
|
|
182
|
+
{ option: "checkBaseUrl", env: PIWI_ENV_KEYS.checkBaseUrl, kind: "bool" },
|
|
174
183
|
{ option: "inspectOnFailure", env: PIWI_ENV_KEYS.inspectOnFailure, kind: "bool" },
|
|
175
184
|
{ option: "pickLocatorOnFailure", env: PIWI_ENV_KEYS.pickLocatorOnFailure, kind: "bool" },
|
|
176
185
|
{ option: "outputFile", env: PIWI_ENV_KEYS.outputFile, kind: "string" }
|
|
@@ -613,6 +622,131 @@ function isListMode(argv = process.argv) {
|
|
|
613
622
|
return rest.some((tok) => PW_LIST_FLAGS.some((flag) => tok === flag || tok.startsWith(`${flag}=`)));
|
|
614
623
|
}
|
|
615
624
|
|
|
625
|
+
// src/internal/support/base-url-check.ts
|
|
626
|
+
var BASE_URL_CHECK_ATTEMPTS = 3;
|
|
627
|
+
var BASE_URL_CHECK_TIMEOUT_MS = 1e4;
|
|
628
|
+
var BASE_URL_CHECK_DELAY_MS = 2e3;
|
|
629
|
+
var GATEWAY_ANSWERS = {
|
|
630
|
+
502: "bad gateway",
|
|
631
|
+
503: "service unavailable",
|
|
632
|
+
504: "gateway timeout"
|
|
633
|
+
};
|
|
634
|
+
function cliProjectNames(argv = process.argv) {
|
|
635
|
+
let names = null;
|
|
636
|
+
for (let i = 0; i < argv.length; i++) {
|
|
637
|
+
const arg = argv[i];
|
|
638
|
+
if (arg.startsWith("--project=")) {
|
|
639
|
+
(names ??= []).push(arg.slice("--project=".length));
|
|
640
|
+
} else if (arg === "--project") {
|
|
641
|
+
names ??= [];
|
|
642
|
+
while (i + 1 < argv.length && !argv[i + 1].startsWith("-")) names.push(argv[++i]);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return names;
|
|
646
|
+
}
|
|
647
|
+
function wildcard(pattern) {
|
|
648
|
+
const escaped = pattern.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
649
|
+
return new RegExp(`^${escaped.join(".*")}$`, "i");
|
|
650
|
+
}
|
|
651
|
+
function selectedProjects(projects, argv = process.argv) {
|
|
652
|
+
const names = cliProjectNames(argv);
|
|
653
|
+
if (!names || names.length === 0) return projects;
|
|
654
|
+
const patterns = names.map(wildcard);
|
|
655
|
+
const chosen = new Set(projects.filter((p) => patterns.some((re) => re.test(p.name ?? ""))));
|
|
656
|
+
if (!argv.includes("--no-deps")) {
|
|
657
|
+
const byName = new Map(projects.map((p) => [p.name ?? "", p]));
|
|
658
|
+
const queue = [...chosen];
|
|
659
|
+
while (queue.length > 0) {
|
|
660
|
+
for (const dep of queue.shift().dependencies ?? []) {
|
|
661
|
+
const project = byName.get(dep);
|
|
662
|
+
if (project && !chosen.has(project)) {
|
|
663
|
+
chosen.add(project);
|
|
664
|
+
queue.push(project);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return projects.filter((p) => chosen.has(p));
|
|
670
|
+
}
|
|
671
|
+
function asProxy(value) {
|
|
672
|
+
const proxy = value;
|
|
673
|
+
return proxy && typeof proxy === "object" && typeof proxy.server === "string" ? proxy : void 0;
|
|
674
|
+
}
|
|
675
|
+
function baseUrlTargets(config, argv = process.argv) {
|
|
676
|
+
const projects = config.projects?.length ? config.projects : [{ name: "", use: config.use }];
|
|
677
|
+
const targets = /* @__PURE__ */ new Map();
|
|
678
|
+
for (const project of selectedProjects(projects, argv)) {
|
|
679
|
+
const url = project.use?.baseURL;
|
|
680
|
+
if (typeof url !== "string" || !/^https?:\/\//i.test(url)) continue;
|
|
681
|
+
const target = targets.get(url);
|
|
682
|
+
if (target) {
|
|
683
|
+
if (project.name) target.projects.push(project.name);
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
targets.set(url, {
|
|
687
|
+
url,
|
|
688
|
+
projects: project.name ? [project.name] : [],
|
|
689
|
+
ignoreHTTPSErrors: project.use?.ignoreHTTPSErrors === true,
|
|
690
|
+
proxy: asProxy(project.use?.proxy)
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
return [...targets.values()];
|
|
694
|
+
}
|
|
695
|
+
function requestError(error) {
|
|
696
|
+
const first = errorMessage(error).split("\n")[0].trim();
|
|
697
|
+
return first.replace(/^apiRequestContext\.\w+:\s*/, "");
|
|
698
|
+
}
|
|
699
|
+
var playwrightProbe = async (target, timeoutMs) => {
|
|
700
|
+
const { request } = await import("@playwright/test");
|
|
701
|
+
const context = await request.newContext({ ignoreHTTPSErrors: target.ignoreHTTPSErrors, proxy: target.proxy });
|
|
702
|
+
try {
|
|
703
|
+
const response = await context.get(target.url, { timeout: timeoutMs, maxRedirects: 0, failOnStatusCode: false });
|
|
704
|
+
return { status: response.status() };
|
|
705
|
+
} catch (error) {
|
|
706
|
+
return { error: requestError(error) };
|
|
707
|
+
} finally {
|
|
708
|
+
await context.dispose().catch(() => {
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
async function checkBaseUrl(target, options = {}) {
|
|
713
|
+
const attempts = Math.max(1, options.attempts ?? BASE_URL_CHECK_ATTEMPTS);
|
|
714
|
+
const timeoutMs = options.timeoutMs ?? BASE_URL_CHECK_TIMEOUT_MS;
|
|
715
|
+
const delayMs = options.delayMs ?? BASE_URL_CHECK_DELAY_MS;
|
|
716
|
+
const probe = options.probe ?? playwrightProbe;
|
|
717
|
+
let reason = "";
|
|
718
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
719
|
+
const outcome = await probe(target, timeoutMs);
|
|
720
|
+
if ("status" in outcome) {
|
|
721
|
+
const gateway = GATEWAY_ANSWERS[outcome.status];
|
|
722
|
+
if (!gateway) return null;
|
|
723
|
+
reason = `${outcome.status} ${gateway}`;
|
|
724
|
+
} else {
|
|
725
|
+
reason = outcome.error;
|
|
726
|
+
}
|
|
727
|
+
if (attempt < attempts) await new Promise((resolve2) => setTimeout(resolve2, delayMs));
|
|
728
|
+
}
|
|
729
|
+
return `${reason} (${attempts} ${attempts === 1 ? "attempt" : "attempts"})`;
|
|
730
|
+
}
|
|
731
|
+
async function checkBaseUrls(config, options = {}) {
|
|
732
|
+
const targets = baseUrlTargets(config, options.argv);
|
|
733
|
+
const reasons = await Promise.all(targets.map((target) => checkBaseUrl(target, options)));
|
|
734
|
+
const down = targets.flatMap((target, i) => reasons[i] ? [{ target, reason: reasons[i] }] : []);
|
|
735
|
+
if (down.length === 0) return targets;
|
|
736
|
+
const lines = down.map(({ target, reason }) => {
|
|
737
|
+
const used = target.projects.length > 0 ? ` (${target.projects.join(", ")})` : "";
|
|
738
|
+
return ` ${target.url}${used}: ${reason}`;
|
|
739
|
+
});
|
|
740
|
+
const message = [
|
|
741
|
+
`[Piwi Dashboard] The app under test did not answer, so no test ran:`,
|
|
742
|
+
...lines,
|
|
743
|
+
`Bring the environment back and run again, or set checkBaseUrl: false (PIWI_CHECK_BASE_URL=false) to run the tests anyway.`
|
|
744
|
+
].join("\n");
|
|
745
|
+
const error = new Error(message);
|
|
746
|
+
error.stack = message;
|
|
747
|
+
throw error;
|
|
748
|
+
}
|
|
749
|
+
|
|
616
750
|
// src/internal/manifest/collect.ts
|
|
617
751
|
var fs4 = __toESM(require("fs"));
|
|
618
752
|
var path4 = __toESM(require("path"));
|
|
@@ -712,6 +846,10 @@ function createGlobalSetup(options, userSetup) {
|
|
|
712
846
|
if (userSetup) return userSetup(config);
|
|
713
847
|
return;
|
|
714
848
|
}
|
|
849
|
+
if (opts.checkBaseUrl === true) {
|
|
850
|
+
const checked = await checkBaseUrls(config ?? {});
|
|
851
|
+
for (const target of checked) logger.debug(`Base URL answered: ${target.url}`);
|
|
852
|
+
}
|
|
715
853
|
if (opts.enabled === false || !opts.serverUrl) {
|
|
716
854
|
logger.info("Not enabled \u2014 set PIWI_DASHBOARD_URL or serverUrl to enable.");
|
|
717
855
|
if (userSetup) return userSetup(config);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
|
|
2
2
|
import { PlaywrightTestConfig, Locator, TestType, Page, Fixtures, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions } from '@playwright/test';
|
|
3
3
|
export { PlaywrightTestConfig } from '@playwright/test';
|
|
4
|
-
export { PiwiFixtures, extendPiwiFixtures, piwiFixtures } from './internal/capture/capture-fixtures.js';
|
|
4
|
+
export { PiwiFixtures, PiwiWorkerFixtures, extendPiwiFixtures, piwiFixtures } from './internal/capture/capture-fixtures.js';
|
|
5
5
|
import '@piwitests/picker-dom';
|
|
6
6
|
import '@piwitests/core/wire';
|
|
7
7
|
import '@piwitests/core/code-reach';
|
|
@@ -100,6 +100,35 @@ interface PiwiDashboardOptions {
|
|
|
100
100
|
* `false`. Can also be forced off with `PIWI_CAPTURE_SERVER_TRACES=false`.
|
|
101
101
|
*/
|
|
102
102
|
captureServerTraces?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Keep a ledger of the browsers, contexts, pages and API request contexts each
|
|
105
|
+
* test opens, and list at the end of the run the ones left open after the
|
|
106
|
+
* scope that created them ended (a context a test never closed, a `beforeAll`
|
|
107
|
+
* context no `afterAll` closes, a browser a test launched itself), the pages
|
|
108
|
+
* opened and never used, and the pages, listeners and route handlers piling up
|
|
109
|
+
* on a page or context that lives across tests. Each finding names the line or
|
|
110
|
+
* the fixture that opened the object. Rides the capture fixtures and costs a
|
|
111
|
+
* few bookkeeping steps per test. Also samples the run's processes and the
|
|
112
|
+
* machine, with or without the fixtures, and prints what the run cost: CPU by
|
|
113
|
+
* process, time spent waiting for a CPU, peak memory and disk. The findings,
|
|
114
|
+
* the run's cost and each test's go to the dashboard with the run, on its
|
|
115
|
+
* Resources tab. Defaults to `true`. Set to `false` (or
|
|
116
|
+
* `PIWI_CAPTURE_RESOURCES=false`) to turn both off.
|
|
117
|
+
*/
|
|
118
|
+
captureResources?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* What the capture fixtures do when a test leaves open a browser, context,
|
|
121
|
+
* page or API request context that the test itself opened (its body or its
|
|
122
|
+
* `beforeEach`/`afterEach` hooks; a fixture's objects are the fixture's):
|
|
123
|
+
* `'report'` lists it in the end-of-run summary, `'fail'` also fails the test
|
|
124
|
+
* with the line that opened it, and `'close'` closes it when the test ends and
|
|
125
|
+
* still lists it. A `beforeAll` object left open is only ever reported. Each
|
|
126
|
+
* test is judged when it ends, so a test that hands what it opened to the next
|
|
127
|
+
* one fails under `'fail'` and loses it under `'close'`: open such objects in
|
|
128
|
+
* `beforeAll` and close them in `afterAll`. Defaults to `'report'`. Can also
|
|
129
|
+
* be set with `PIWI_LEAK_CHECK`.
|
|
130
|
+
*/
|
|
131
|
+
leakCheck?: 'report' | 'fail' | 'close';
|
|
103
132
|
/**
|
|
104
133
|
* Sample the ARIA snapshot at the end of a *passing* test, so a later failure
|
|
105
134
|
* can be diffed against the page as it last looked when green. Rate-limited by
|
|
@@ -136,6 +165,20 @@ interface PiwiDashboardOptions {
|
|
|
136
165
|
* to opt out and let Playwright's own defaults stand.
|
|
137
166
|
*/
|
|
138
167
|
defaultCapture?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Check that each `baseURL` the run's projects use answers before any worker
|
|
170
|
+
* starts, and stop the run with a message naming the ones that do not, so a
|
|
171
|
+
* suite never runs against an environment that is down. Any HTTP answer
|
|
172
|
+
* counts (a redirect or a 404 included) except a 502, 503 or 504 from a
|
|
173
|
+
* gateway; each base URL gets three tries of 10 seconds, 2 seconds apart,
|
|
174
|
+
* sent with the project's `ignoreHTTPSErrors` and `proxy`. A stopped run
|
|
175
|
+
* runs no test and reaches no dashboard. The check runs in the reporter's
|
|
176
|
+
* global setup, after `webServer` has started and before the config's own
|
|
177
|
+
* `globalSetup`, so leave it off when that setup is what starts the app. Only
|
|
178
|
+
* the projects `--project` selects are checked. **Defaults to `false`**. Can
|
|
179
|
+
* also be set with `PIWI_CHECK_BASE_URL=true`.
|
|
180
|
+
*/
|
|
181
|
+
checkBaseUrl?: boolean;
|
|
139
182
|
/**
|
|
140
183
|
* Open Piwi's own failure-time overlay on the failing page — for inspecting
|
|
141
184
|
* the page and picking a locator for any element (click an element → confirm
|
|
@@ -299,6 +342,10 @@ interface PiwiDashboardOptions {
|
|
|
299
342
|
* The server-run ID and a one-time token are written to a temp file so the
|
|
300
343
|
* reporter instance can pick them up during the streaming handshake.
|
|
301
344
|
*
|
|
345
|
+
* With `checkBaseUrl`, every `baseURL` the run's projects use is checked first,
|
|
346
|
+
* and the setup throws, stopping the run before any worker starts, when one
|
|
347
|
+
* does not answer.
|
|
348
|
+
*
|
|
302
349
|
* @param options Piwi Dashboard options (uses `serverUrl`, `projectName`, …).
|
|
303
350
|
* @param userSetup An existing global setup to chain after the Piwi registration.
|
|
304
351
|
*/
|
|
@@ -375,6 +422,20 @@ declare class PiwiDashboardReporter {
|
|
|
375
422
|
private filterDetails;
|
|
376
423
|
/** Configured `maxFailures` (0 = unlimited) — disambiguates an interrupted run's unrun reason. */
|
|
377
424
|
private maxFailures;
|
|
425
|
+
/** The resource censuses the capture fixtures attached, one per test attempt. */
|
|
426
|
+
private resourceCensuses;
|
|
427
|
+
/** Lifecycle steps of the tests that ran without the fixtures. */
|
|
428
|
+
private lifecycleTallies;
|
|
429
|
+
/** The user fixtures set up by the tests that left a page unused, by test id. */
|
|
430
|
+
private fixturesByTest;
|
|
431
|
+
/** The file workers append their shutdown census to, set in `onBegin`. */
|
|
432
|
+
private resourcesFile;
|
|
433
|
+
/** Samples the run's processes and the machine from `onBegin` to `onEnd`. */
|
|
434
|
+
private sampler;
|
|
435
|
+
/** Bytes of the files the tests attached, by kind. */
|
|
436
|
+
private artifactBytes;
|
|
437
|
+
/** The run's resource report for the dashboard, built in `onEnd`. */
|
|
438
|
+
private resourceReport;
|
|
378
439
|
private httpClient;
|
|
379
440
|
private uploader;
|
|
380
441
|
private fileHandler;
|
|
@@ -408,6 +469,17 @@ declare class PiwiDashboardReporter {
|
|
|
408
469
|
onStepEnd(test: TestCase | undefined, _result: TestResult | undefined, step: any): void;
|
|
409
470
|
/** Playwright reporter hook: called when an individual test finishes */
|
|
410
471
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
472
|
+
/**
|
|
473
|
+
* Add up the files a test attached, and keep its resource census; for a test
|
|
474
|
+
* that ran without the capture fixtures, tally the browsers and contexts its
|
|
475
|
+
* steps opened and closed.
|
|
476
|
+
*/
|
|
477
|
+
private collectResources;
|
|
478
|
+
/**
|
|
479
|
+
* Print what the run left open or opened for nothing, from the censuses and
|
|
480
|
+
* the workers' shutdown file, then what the run cost the machine.
|
|
481
|
+
*/
|
|
482
|
+
private reportResources;
|
|
411
483
|
/**
|
|
412
484
|
* Synthesize `didnotrun` cases for tests Playwright planned but never reported
|
|
413
485
|
* (no `onTestEnd`) — typically because `maxFailures` cut the run short. These
|
|
@@ -504,6 +576,48 @@ declare function extendPiwiAi<TestArgs extends FixtureArgs, WorkerArgs extends F
|
|
|
504
576
|
page: Page & PiwiAi;
|
|
505
577
|
}, WorkerArgs>;
|
|
506
578
|
|
|
579
|
+
/** How the code a recording writes looks, for everyone working in the repository. */
|
|
580
|
+
interface PiwiCodegenConfig {
|
|
581
|
+
/**
|
|
582
|
+
* After a step that leads to another page, wait for that page's URL and for the next step's element before going
|
|
583
|
+
* on. `true` by default. A call to one of your own functions waits for its pages itself either way.
|
|
584
|
+
*/
|
|
585
|
+
pageWaits?: boolean;
|
|
586
|
+
/**
|
|
587
|
+
* `literal` (default): typed values are written in the code, and only passwords are read from the environment.
|
|
588
|
+
* `env`: every typed value is read from an environment variable named after its field.
|
|
589
|
+
*/
|
|
590
|
+
values?: 'literal' | 'env';
|
|
591
|
+
/**
|
|
592
|
+
* What those environment variables start with: `E2E_` by default, as in `E2E_PASSWORD`. Upper-case letters, digits
|
|
593
|
+
* and underscores, starting with a letter.
|
|
594
|
+
*/
|
|
595
|
+
envPrefix?: string;
|
|
596
|
+
/**
|
|
597
|
+
* `page` wraps the steps of each page in `await test.step('<path>', …)`, in a test (not in a page object or a
|
|
598
|
+
* helper); `none` (default) does not.
|
|
599
|
+
*/
|
|
600
|
+
testSteps?: 'none' | 'page';
|
|
601
|
+
/** Tags a new test gets, such as `@recorded`; a missing `@` is added. */
|
|
602
|
+
tags?: string[];
|
|
603
|
+
/** Annotations a new test gets, such as `{ type: 'piwi:owner', description: '@shop-team' }`. */
|
|
604
|
+
annotations?: Array<{
|
|
605
|
+
type: string;
|
|
606
|
+
description?: string;
|
|
607
|
+
}>;
|
|
608
|
+
}
|
|
609
|
+
/** Piwi's section of a Playwright config, `'@piwi'`. */
|
|
610
|
+
interface PiwiConfig {
|
|
611
|
+
/** How the code a recording writes looks. */
|
|
612
|
+
codegen?: PiwiCodegenConfig;
|
|
613
|
+
}
|
|
614
|
+
declare module '@playwright/test' {
|
|
615
|
+
interface Config<TestArgs, WorkerArgs> {
|
|
616
|
+
/** Piwi's options, read from the repository by the editor extensions: how the code a recording writes looks. */
|
|
617
|
+
'@piwi'?: PiwiConfig;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
507
621
|
/**
|
|
508
622
|
* Public API of `@piwitests/reporter`.
|
|
509
623
|
*
|
|
@@ -513,4 +627,4 @@ declare function extendPiwiAi<TestArgs extends FixtureArgs, WorkerArgs extends F
|
|
|
513
627
|
* exported from this file, it isn't part of the supported API.
|
|
514
628
|
*/
|
|
515
629
|
|
|
516
|
-
export { type AiMode, type AiOnMiss, type PiwiAi, type PiwiDashboardOptions, PiwiDashboardReporter, type ResolveSelectionOptions, type ResolveSelectionResult, createGlobalSetup, PiwiDashboardReporter as default, extendPiwiAi, piwiAiFixtures, resolveSelection, wrapConfig };
|
|
630
|
+
export { type AiMode, type AiOnMiss, type PiwiAi, type PiwiCodegenConfig, type PiwiConfig, type PiwiDashboardOptions, PiwiDashboardReporter, type ResolveSelectionOptions, type ResolveSelectionResult, createGlobalSetup, PiwiDashboardReporter as default, extendPiwiAi, piwiAiFixtures, resolveSelection, wrapConfig };
|