@piwitests/reporter 0.13.0 → 0.15.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/README.md +46 -0
- package/dist/global-setup-module.js +4 -2
- package/dist/index.d.ts +9 -0
- package/dist/index.js +128 -29
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,7 @@ export default defineConfig({
|
|
|
92
92
|
| `collectScmInfo` | boolean | `true` | Auto-collect git commit, branch, author |
|
|
93
93
|
| `collectCiInfo` | boolean | `true` | Auto-collect CI environment info |
|
|
94
94
|
| `collectPerformanceMetrics` | boolean | `true` | Collect step timings, network requests and web vitals from the fixture |
|
|
95
|
+
| `outputFile` | string | — | Write a JSON file with the run URL/id/status so CI can consume it (see below) |
|
|
95
96
|
| `apiKey` | string | — | API key for authentication (preferred for CI) |
|
|
96
97
|
| `username` | string | — | Username for dashboard login (use `apiKey` instead when possible) |
|
|
97
98
|
| `password` | string | — | Password for dashboard login (used with `username`) |
|
|
@@ -209,6 +210,51 @@ When `collectCiInfo` is enabled (default), the reporter auto-detects:
|
|
|
209
210
|
- **Travis CI** — build number/URL, job number
|
|
210
211
|
- **Azure Pipelines** — build number, build ID/URL, job name
|
|
211
212
|
|
|
213
|
+
## Publishing the run URL to CI
|
|
214
|
+
|
|
215
|
+
After a run is submitted, the reporter surfaces the dashboard run URL so a later
|
|
216
|
+
CI step (a custom email, a Slack message, a deploy gate) can pick it up without
|
|
217
|
+
scraping the log. The URL is always printed as `View run: <url>`, and in
|
|
218
|
+
addition:
|
|
219
|
+
|
|
220
|
+
- **Any CI — JSON output file.** Set `outputFile` (or `PIWI_OUTPUT_FILE`) and the
|
|
221
|
+
reporter writes a small JSON file when the run lands:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{ "runUrl": "https://piwi.example.com/test-runs/1234", "runId": 1234, "projectId": 5, "projectName": "checkout", "status": "passed", "ciBuildUrl": "https://ci.example.com/build/9" }
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Read it from any pipeline, e.g. `node -e "console.log(require('./piwi-run.json').runUrl)"`
|
|
228
|
+
(portable) or `cat piwi-run.json` and parse it in your email step. In Jenkins,
|
|
229
|
+
`def run = readJSON file: 'piwi-run.json'` then use `run.runUrl`.
|
|
230
|
+
|
|
231
|
+
- **GitHub Actions (automatic).** When `GITHUB_ACTIONS` is set, the reporter
|
|
232
|
+
appends step outputs to `$GITHUB_OUTPUT` (`piwi_run_url`, `piwi_run_id`,
|
|
233
|
+
`piwi_project_id`, `piwi_run_status`), writes a markdown link to the job
|
|
234
|
+
summary, and prints a `::notice::` annotation. Give the test step an `id` and a
|
|
235
|
+
downstream step can read it:
|
|
236
|
+
|
|
237
|
+
```yaml
|
|
238
|
+
- id: tests
|
|
239
|
+
run: npx playwright test
|
|
240
|
+
- run: echo "Results at ${{ steps.tests.outputs.piwi_run_url }}"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- **GitLab CI (automatic).** When `GITLAB_CI` is set, the reporter writes a
|
|
244
|
+
dotenv report (`piwi.env` by default, override with `PIWI_DOTENV_FILE`).
|
|
245
|
+
Declare it so later jobs inherit `$PIWI_RUN_URL`:
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
test:
|
|
249
|
+
script: npx playwright test
|
|
250
|
+
artifacts:
|
|
251
|
+
reports:
|
|
252
|
+
dotenv: piwi.env
|
|
253
|
+
email:
|
|
254
|
+
needs: [test]
|
|
255
|
+
script: ./send-email.sh "$PIWI_RUN_URL"
|
|
256
|
+
```
|
|
257
|
+
|
|
212
258
|
## How It Works
|
|
213
259
|
|
|
214
260
|
1. When tests start, the reporter creates a run on the server (streaming mode) or collects results locally (batch mode)
|
|
@@ -84,7 +84,8 @@ var PIWI_ENV_KEYS = {
|
|
|
84
84
|
captureLocators: "PIWI_CAPTURE_LOCATORS",
|
|
85
85
|
capturePageState: "PIWI_CAPTURE_PAGE_STATE",
|
|
86
86
|
inspectOnFailure: "PIWI_INSPECT_ON_FAIL",
|
|
87
|
-
pickLocatorOnFailure: "PIWI_PICK_LOCATOR_ON_FAIL"
|
|
87
|
+
pickLocatorOnFailure: "PIWI_PICK_LOCATOR_ON_FAIL",
|
|
88
|
+
outputFile: "PIWI_OUTPUT_FILE"
|
|
88
89
|
};
|
|
89
90
|
function readBool(val) {
|
|
90
91
|
if (val === void 0) return void 0;
|
|
@@ -108,7 +109,8 @@ var ENV_FALLBACK_SPECS = [
|
|
|
108
109
|
{ option: "captureLocators", env: PIWI_ENV_KEYS.captureLocators, kind: "bool" },
|
|
109
110
|
{ option: "capturePageState", env: PIWI_ENV_KEYS.capturePageState, kind: "bool" },
|
|
110
111
|
{ option: "inspectOnFailure", env: PIWI_ENV_KEYS.inspectOnFailure, kind: "bool" },
|
|
111
|
-
{ option: "pickLocatorOnFailure", env: PIWI_ENV_KEYS.pickLocatorOnFailure, kind: "bool" }
|
|
112
|
+
{ option: "pickLocatorOnFailure", env: PIWI_ENV_KEYS.pickLocatorOnFailure, kind: "bool" },
|
|
113
|
+
{ option: "outputFile", env: PIWI_ENV_KEYS.outputFile, kind: "string" }
|
|
112
114
|
];
|
|
113
115
|
function resolveOptions(raw) {
|
|
114
116
|
const env = process.env;
|
package/dist/index.d.ts
CHANGED
|
@@ -97,6 +97,15 @@ interface PiwiDashboardOptions extends PlaywrightTestConfig {
|
|
|
97
97
|
tags?: string[];
|
|
98
98
|
/** Additional custom metadata as key-value pairs */
|
|
99
99
|
customData?: Record<string, unknown>;
|
|
100
|
+
/**
|
|
101
|
+
* Write a JSON file with the submitted run's dashboard URL, id, project id and
|
|
102
|
+
* status after the run lands, so a CI pipeline can consume it (e.g. feed the
|
|
103
|
+
* run URL into a custom email step). Any CI can read the file. GitHub Actions
|
|
104
|
+
* step outputs / job summary and GitLab dotenv reports are emitted
|
|
105
|
+
* automatically when running under those systems, regardless of this option.
|
|
106
|
+
* Can also be set with `PIWI_OUTPUT_FILE`.
|
|
107
|
+
*/
|
|
108
|
+
outputFile?: string;
|
|
100
109
|
/** Enable verbose logging for debugging. Defaults to `false`. */
|
|
101
110
|
verbose?: boolean;
|
|
102
111
|
}
|
package/dist/index.js
CHANGED
|
@@ -40,7 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
module.exports = __toCommonJS(index_exports);
|
|
41
41
|
|
|
42
42
|
// src/public/reporter.ts
|
|
43
|
-
var
|
|
43
|
+
var path13 = __toESM(require("path"));
|
|
44
44
|
|
|
45
45
|
// src/internal/config/env.ts
|
|
46
46
|
var DEFAULTS = {
|
|
@@ -80,7 +80,8 @@ var PIWI_ENV_KEYS = {
|
|
|
80
80
|
captureLocators: "PIWI_CAPTURE_LOCATORS",
|
|
81
81
|
capturePageState: "PIWI_CAPTURE_PAGE_STATE",
|
|
82
82
|
inspectOnFailure: "PIWI_INSPECT_ON_FAIL",
|
|
83
|
-
pickLocatorOnFailure: "PIWI_PICK_LOCATOR_ON_FAIL"
|
|
83
|
+
pickLocatorOnFailure: "PIWI_PICK_LOCATOR_ON_FAIL",
|
|
84
|
+
outputFile: "PIWI_OUTPUT_FILE"
|
|
84
85
|
};
|
|
85
86
|
function readBool(val) {
|
|
86
87
|
if (val === void 0) return void 0;
|
|
@@ -104,7 +105,8 @@ var ENV_FALLBACK_SPECS = [
|
|
|
104
105
|
{ option: "captureLocators", env: PIWI_ENV_KEYS.captureLocators, kind: "bool" },
|
|
105
106
|
{ option: "capturePageState", env: PIWI_ENV_KEYS.capturePageState, kind: "bool" },
|
|
106
107
|
{ option: "inspectOnFailure", env: PIWI_ENV_KEYS.inspectOnFailure, kind: "bool" },
|
|
107
|
-
{ option: "pickLocatorOnFailure", env: PIWI_ENV_KEYS.pickLocatorOnFailure, kind: "bool" }
|
|
108
|
+
{ option: "pickLocatorOnFailure", env: PIWI_ENV_KEYS.pickLocatorOnFailure, kind: "bool" },
|
|
109
|
+
{ option: "outputFile", env: PIWI_ENV_KEYS.outputFile, kind: "string" }
|
|
108
110
|
];
|
|
109
111
|
function resolveOptions(raw) {
|
|
110
112
|
const env = process.env;
|
|
@@ -407,11 +409,6 @@ function serializeRun(payload, opts) {
|
|
|
407
409
|
return body;
|
|
408
410
|
}
|
|
409
411
|
|
|
410
|
-
// src/internal/support/run-url.ts
|
|
411
|
-
function runUrl(serverUrl, runId) {
|
|
412
|
-
return `${serverUrl.replace(/\/+$/, "")}/test-runs/${runId}`;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
412
|
// src/internal/submit/uploader.ts
|
|
416
413
|
var Uploader = class {
|
|
417
414
|
/**
|
|
@@ -434,7 +431,6 @@ var Uploader = class {
|
|
|
434
431
|
this.logger.info(`Successfully uploaded test results`);
|
|
435
432
|
if (response.testRunId) {
|
|
436
433
|
this.logger.info(`Test Run ID: ${response.testRunId}, Project ID: ${response.projectId}`);
|
|
437
|
-
this.logger.info(`View run: ${runUrl(this.httpClient.baseUrl, response.testRunId)}`);
|
|
438
434
|
}
|
|
439
435
|
return response;
|
|
440
436
|
}
|
|
@@ -450,7 +446,6 @@ var Uploader = class {
|
|
|
450
446
|
this.logger.info(`Successfully uploaded test results with files`);
|
|
451
447
|
if (response.testRunId) {
|
|
452
448
|
this.logger.info(`Test Run ID: ${response.testRunId}, Project ID: ${response.projectId}`);
|
|
453
|
-
this.logger.info(`View run: ${runUrl(this.httpClient.baseUrl, response.testRunId)}`);
|
|
454
449
|
}
|
|
455
450
|
if (response.reports) {
|
|
456
451
|
for (const r of response.reports) this.logger.info(`${r.label}: ${r.path}`);
|
|
@@ -1157,6 +1152,11 @@ function readSetupInfo(projectName) {
|
|
|
1157
1152
|
return null;
|
|
1158
1153
|
}
|
|
1159
1154
|
|
|
1155
|
+
// src/internal/support/run-url.ts
|
|
1156
|
+
function runUrl(serverUrl, runId) {
|
|
1157
|
+
return `${serverUrl.replace(/\/+$/, "")}/test-runs/${runId}`;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
1160
|
// src/internal/streaming/stream-manager.ts
|
|
1161
1161
|
var StreamManager = class {
|
|
1162
1162
|
/**
|
|
@@ -2001,6 +2001,90 @@ function buildErrorText(result) {
|
|
|
2001
2001
|
return text;
|
|
2002
2002
|
}
|
|
2003
2003
|
|
|
2004
|
+
// src/internal/support/ci-output.ts
|
|
2005
|
+
var fs12 = __toESM(require("fs"));
|
|
2006
|
+
var path12 = __toESM(require("path"));
|
|
2007
|
+
function emitRunOutputs(output, logger, outputFile, env = process.env) {
|
|
2008
|
+
logger.info(`View run: ${output.runUrl}`);
|
|
2009
|
+
if (outputFile) writeOutputFile(outputFile, output, logger);
|
|
2010
|
+
if (env.GITHUB_ACTIONS) emitGitHubActions(output, env, logger);
|
|
2011
|
+
if (env.GITLAB_CI) emitGitLabDotenv(output, env, logger);
|
|
2012
|
+
}
|
|
2013
|
+
function writeOutputFile(file, output, logger) {
|
|
2014
|
+
try {
|
|
2015
|
+
const dir = path12.dirname(file);
|
|
2016
|
+
if (dir && dir !== ".") fs12.mkdirSync(dir, { recursive: true });
|
|
2017
|
+
fs12.writeFileSync(
|
|
2018
|
+
file,
|
|
2019
|
+
JSON.stringify(
|
|
2020
|
+
{
|
|
2021
|
+
runUrl: output.runUrl,
|
|
2022
|
+
runId: output.runId,
|
|
2023
|
+
projectId: output.projectId ?? null,
|
|
2024
|
+
projectName: output.projectName,
|
|
2025
|
+
status: output.status,
|
|
2026
|
+
ciBuildUrl: output.ciBuildUrl ?? null
|
|
2027
|
+
},
|
|
2028
|
+
null,
|
|
2029
|
+
2
|
|
2030
|
+
) + "\n"
|
|
2031
|
+
);
|
|
2032
|
+
logger.info(`Wrote run output to ${file}`);
|
|
2033
|
+
} catch (error) {
|
|
2034
|
+
logger.warn(`Failed to write run output file '${file}': ${errorMessage(error)}`);
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
function emitGitHubActions(output, env, logger) {
|
|
2038
|
+
const pairs = [
|
|
2039
|
+
["piwi_run_url", output.runUrl],
|
|
2040
|
+
["piwi_run_id", String(output.runId)],
|
|
2041
|
+
["piwi_run_status", output.status]
|
|
2042
|
+
];
|
|
2043
|
+
if (output.projectId != null) pairs.push(["piwi_project_id", String(output.projectId)]);
|
|
2044
|
+
if (env.GITHUB_OUTPUT) {
|
|
2045
|
+
appendFileLines(
|
|
2046
|
+
env.GITHUB_OUTPUT,
|
|
2047
|
+
pairs.map(([k, v]) => `${k}=${v}`),
|
|
2048
|
+
logger,
|
|
2049
|
+
"step output"
|
|
2050
|
+
);
|
|
2051
|
+
}
|
|
2052
|
+
if (env.GITHUB_STEP_SUMMARY) {
|
|
2053
|
+
appendFileLines(
|
|
2054
|
+
env.GITHUB_STEP_SUMMARY,
|
|
2055
|
+
["### Piwi test run", "", `[View run](${output.runUrl}) \u2014 **${output.status}**`, ""],
|
|
2056
|
+
logger,
|
|
2057
|
+
"step summary"
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
process.stdout.write(`::notice title=Piwi test run::${output.runUrl}
|
|
2061
|
+
`);
|
|
2062
|
+
}
|
|
2063
|
+
function emitGitLabDotenv(output, env, logger) {
|
|
2064
|
+
const file = env.PIWI_DOTENV_FILE || "piwi.env";
|
|
2065
|
+
const lines = [`PIWI_RUN_URL=${output.runUrl}`, `PIWI_RUN_ID=${output.runId}`, `PIWI_RUN_STATUS=${output.status}`];
|
|
2066
|
+
if (output.projectId != null) lines.push(`PIWI_PROJECT_ID=${output.projectId}`);
|
|
2067
|
+
if (output.ciBuildUrl) lines.push(`PIWI_CI_BUILD_URL=${output.ciBuildUrl}`);
|
|
2068
|
+
try {
|
|
2069
|
+
fs12.writeFileSync(file, lines.join("\n") + "\n");
|
|
2070
|
+
logger.info(`Wrote GitLab dotenv report to ${file} (declare it as artifacts:reports:dotenv)`);
|
|
2071
|
+
} catch (error) {
|
|
2072
|
+
logger.warn(`Failed to write GitLab dotenv file '${file}': ${errorMessage(error)}`);
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
function appendFileLines(file, lines, logger, label) {
|
|
2076
|
+
try {
|
|
2077
|
+
fs12.appendFileSync(file, lines.join("\n") + "\n");
|
|
2078
|
+
} catch (error) {
|
|
2079
|
+
logger.warn(`Failed to write GitHub Actions ${label}: ${errorMessage(error)}`);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
function ciBuildUrlFromMetadata(metadata) {
|
|
2083
|
+
const ci = metadata?.ci;
|
|
2084
|
+
if (!ci) return void 0;
|
|
2085
|
+
return ci.buildUrl || ci.pipelineUrl || ci.jobUrl || void 0;
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2004
2088
|
// src/internal/submit/run-submitter.ts
|
|
2005
2089
|
var RunSubmitter = class {
|
|
2006
2090
|
/**
|
|
@@ -2045,13 +2129,29 @@ var RunSubmitter = class {
|
|
|
2045
2129
|
this.logger.error(`Authentication failed: ${errorMessage(error)}`);
|
|
2046
2130
|
throw error;
|
|
2047
2131
|
}
|
|
2132
|
+
let outcome = { done: false, output: null };
|
|
2048
2133
|
if (sm?.enabled && sm?.runId != null) {
|
|
2049
|
-
|
|
2134
|
+
outcome = await this.tryFinishStreaming(run, overallStatus, duration, auth);
|
|
2135
|
+
}
|
|
2136
|
+
if (!outcome.done && (this.hasReports(run) || run.options.uploadTraces)) {
|
|
2137
|
+
outcome = await this.tryUploadWithFiles(run, overallStatus, duration, auth);
|
|
2050
2138
|
}
|
|
2051
|
-
if (
|
|
2052
|
-
|
|
2139
|
+
if (!outcome.done) {
|
|
2140
|
+
outcome = await this.tryUploadJSON(run, overallStatus, duration, auth);
|
|
2053
2141
|
}
|
|
2054
|
-
|
|
2142
|
+
if (outcome.output) emitRunOutputs(outcome.output, this.logger, run.options.outputFile);
|
|
2143
|
+
}
|
|
2144
|
+
/** Assemble a CI-facing run output, or `null` when the server returned no run id. */
|
|
2145
|
+
buildOutput(runId, projectId, run, status) {
|
|
2146
|
+
if (runId == null) return null;
|
|
2147
|
+
return {
|
|
2148
|
+
runUrl: runUrl(this.httpClient.baseUrl, runId),
|
|
2149
|
+
runId,
|
|
2150
|
+
projectId,
|
|
2151
|
+
projectName: run.options.projectName,
|
|
2152
|
+
status,
|
|
2153
|
+
ciBuildUrl: ciBuildUrlFromMetadata(run.metadata)
|
|
2154
|
+
};
|
|
2055
2155
|
}
|
|
2056
2156
|
hasReports(run) {
|
|
2057
2157
|
return !!run.options.uploadReport || (run.options.reports?.length ?? 0) > 0;
|
|
@@ -2122,9 +2222,6 @@ var RunSubmitter = class {
|
|
|
2122
2222
|
}
|
|
2123
2223
|
await this.httpClient.postJSON(`/api/test-runs/${sm.runId}/finish`, finishBody, auth);
|
|
2124
2224
|
this.logger.info(`Successfully finalized streaming run #${sm.runId}`);
|
|
2125
|
-
if (run.options.serverUrl) {
|
|
2126
|
-
this.logger.info(`View run: ${runUrl(run.options.serverUrl, sm.runId)}`);
|
|
2127
|
-
}
|
|
2128
2225
|
this.recovery.clear();
|
|
2129
2226
|
if (this.hasReports(run)) {
|
|
2130
2227
|
try {
|
|
@@ -2139,22 +2236,22 @@ var RunSubmitter = class {
|
|
|
2139
2236
|
this.logger.warn(`Failed to upload reports for streaming run: ${errorMessage(error)}`);
|
|
2140
2237
|
}
|
|
2141
2238
|
}
|
|
2142
|
-
return true;
|
|
2239
|
+
return { done: true, output: this.buildOutput(sm.runId, void 0, run, overallStatus) };
|
|
2143
2240
|
} catch (error) {
|
|
2144
2241
|
this.logger.warn(`Failed to finalize streaming run: ${errorMessage(error)}`);
|
|
2145
2242
|
this.logger.info("Falling back to batch upload...");
|
|
2146
|
-
return false;
|
|
2243
|
+
return { done: false, output: null };
|
|
2147
2244
|
}
|
|
2148
2245
|
}
|
|
2149
2246
|
async tryUploadWithFiles(run, overallStatus, duration, auth) {
|
|
2150
2247
|
try {
|
|
2151
|
-
await this.uploader.uploadWithFiles(
|
|
2248
|
+
const response = await this.uploader.uploadWithFiles(
|
|
2152
2249
|
this.buildRunPayload(run, overallStatus, duration),
|
|
2153
2250
|
this.reportOptions(run),
|
|
2154
2251
|
auth
|
|
2155
2252
|
);
|
|
2156
2253
|
this.recovery.clear();
|
|
2157
|
-
return true;
|
|
2254
|
+
return { done: true, output: this.buildOutput(response?.testRunId, response?.projectId, run, overallStatus) };
|
|
2158
2255
|
} catch (error) {
|
|
2159
2256
|
if (error instanceof HttpError && error.status === 401 && !auth) {
|
|
2160
2257
|
this.logAuthRequired(run.options.serverUrl);
|
|
@@ -2162,14 +2259,15 @@ var RunSubmitter = class {
|
|
|
2162
2259
|
}
|
|
2163
2260
|
this.logger.warn(`Failed to upload with files: ${errorMessage(error)}`);
|
|
2164
2261
|
this.logger.info("Falling back to JSON upload...");
|
|
2165
|
-
return false;
|
|
2262
|
+
return { done: false, output: null };
|
|
2166
2263
|
}
|
|
2167
2264
|
}
|
|
2168
2265
|
async tryUploadJSON(run, overallStatus, duration, auth) {
|
|
2169
2266
|
const payload = this.buildRunPayload(run, overallStatus, duration);
|
|
2170
2267
|
try {
|
|
2171
|
-
await this.uploader.uploadJSON(payload, auth);
|
|
2268
|
+
const response = await this.uploader.uploadJSON(payload, auth);
|
|
2172
2269
|
this.recovery.clear();
|
|
2270
|
+
return { done: true, output: this.buildOutput(response?.testRunId, response?.projectId, run, overallStatus) };
|
|
2173
2271
|
} catch (error) {
|
|
2174
2272
|
if (error instanceof HttpError && error.status === 401 && !auth) {
|
|
2175
2273
|
this.logAuthRequired(run.options.serverUrl);
|
|
@@ -2180,6 +2278,7 @@ var RunSubmitter = class {
|
|
|
2180
2278
|
`Saved a local recovery copy \u2014 it will be uploaded automatically on your next test run. If this keeps happening, check that serverUrl (${run.options.serverUrl ?? "not set"}) is correct and reachable.`
|
|
2181
2279
|
);
|
|
2182
2280
|
this.recovery.save(serializeRun(payload, { includeTestCases: true }));
|
|
2281
|
+
return { done: true, output: null };
|
|
2183
2282
|
}
|
|
2184
2283
|
}
|
|
2185
2284
|
/** Log one actionable line explaining how to fix a 401 caused by a missing credential. */
|
|
@@ -2192,7 +2291,7 @@ var RunSubmitter = class {
|
|
|
2192
2291
|
|
|
2193
2292
|
// src/public/reporter.ts
|
|
2194
2293
|
function testLocation(test) {
|
|
2195
|
-
const relativeFilePath =
|
|
2294
|
+
const relativeFilePath = path13.relative(process.cwd(), test.location.file).split(path13.sep).join("/");
|
|
2196
2295
|
return `${relativeFilePath}:${test.location.line}:${test.location.column}`;
|
|
2197
2296
|
}
|
|
2198
2297
|
var PiwiDashboardReporter = class {
|
|
@@ -2500,7 +2599,7 @@ var PiwiDashboardReporter = class {
|
|
|
2500
2599
|
var import_node_zlib = require("zlib");
|
|
2501
2600
|
|
|
2502
2601
|
// src/internal/capture/locator-healing.ts
|
|
2503
|
-
var
|
|
2602
|
+
var path14 = __toESM(require("path"));
|
|
2504
2603
|
|
|
2505
2604
|
// ../packages/core/src/locator-fingerprint.ts
|
|
2506
2605
|
var PRESENT_SIMILARITY = 0.8;
|
|
@@ -3057,10 +3156,10 @@ function captureCallerLocation(stack = new Error().stack ?? "") {
|
|
|
3057
3156
|
}
|
|
3058
3157
|
let rel = file;
|
|
3059
3158
|
try {
|
|
3060
|
-
rel =
|
|
3159
|
+
rel = path14.relative(process.cwd(), file);
|
|
3061
3160
|
} catch {
|
|
3062
3161
|
}
|
|
3063
|
-
rel = rel.split(
|
|
3162
|
+
rel = rel.split(path14.sep).join("/");
|
|
3064
3163
|
if (rel.startsWith("./")) rel = rel.slice(2);
|
|
3065
3164
|
return `${rel}:${m[3]}:${m[4]}`;
|
|
3066
3165
|
}
|
|
@@ -3103,7 +3202,7 @@ function inspectionGateFromTestInfo(testInfo, enabled = process.env.PIWI_INSPECT
|
|
|
3103
3202
|
}
|
|
3104
3203
|
|
|
3105
3204
|
// src/internal/capture/pick-on-failure.ts
|
|
3106
|
-
var
|
|
3205
|
+
var path15 = __toESM(require("path"));
|
|
3107
3206
|
var ANSI_RE = /\[[0-9;]*m/g;
|
|
3108
3207
|
function endOfString(s, start) {
|
|
3109
3208
|
const q = s[start];
|
|
@@ -3197,7 +3296,7 @@ ${err.stack ?? ""}`.replace(ANSI_RE, "");
|
|
|
3197
3296
|
const parsed = parseLeafLocatorExpression(line[1].trim());
|
|
3198
3297
|
if (!parsed) continue;
|
|
3199
3298
|
const loc = err.location;
|
|
3200
|
-
const location = loc ? `${
|
|
3299
|
+
const location = loc ? `${path15.relative(process.cwd(), loc.file).split(path15.sep).join("/")}:${loc.line}:${loc.column}` : null;
|
|
3201
3300
|
return { method: parsed.method, args: parsed.args, location };
|
|
3202
3301
|
}
|
|
3203
3302
|
return null;
|
package/package.json
CHANGED