🚀 Auto-deploy: BotVPS atualizado em 02/05/2026 15:37:40
This commit is contained in:
171
node_modules/playwright-core/lib/tools/trace/SKILL.md
generated
vendored
Normal file
171
node_modules/playwright-core/lib/tools/trace/SKILL.md
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
---
|
||||
name: playwright-trace
|
||||
description: Inspect Playwright trace files from the command line — list actions, view requests, console, errors, snapshots and screenshots.
|
||||
allowed-tools: Bash(npx:*)
|
||||
---
|
||||
|
||||
# Playwright Trace CLI
|
||||
|
||||
Inspect `.zip` trace files produced by Playwright tests without opening a browser.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Start with `trace open <trace.zip>` to extract the trace and see its metadata.
|
||||
2. Use `trace actions` to see all actions with their action IDs.
|
||||
3. Use `trace action <action-id>` to drill into a specific action — see parameters, logs, source location, and available snapshots.
|
||||
4. Use `trace requests`, `trace console`, or `trace errors` for cross-cutting views.
|
||||
5. Use `trace snapshot <action-id>` to get the DOM snapshot, or run a browser command against it.
|
||||
6. Use `trace close` to remove the extracted trace data when done.
|
||||
|
||||
All commands after `open` operate on the currently opened trace — no need to pass the trace file again. Opening a new trace replaces the previous one.
|
||||
|
||||
## Commands
|
||||
|
||||
### Open a trace
|
||||
|
||||
```bash
|
||||
# Extract trace and show metadata: browser, viewport, duration, action/error counts
|
||||
npx playwright trace open <trace.zip>
|
||||
```
|
||||
|
||||
### Close a trace
|
||||
|
||||
```bash
|
||||
# Remove extracted trace data
|
||||
npx playwright trace close
|
||||
```
|
||||
|
||||
### Actions
|
||||
|
||||
```bash
|
||||
# List all actions as a tree with action IDs and timing
|
||||
npx playwright trace actions
|
||||
|
||||
# Filter by action title (regex, case-insensitive)
|
||||
npx playwright trace actions --grep "click"
|
||||
|
||||
# Only failed actions
|
||||
npx playwright trace actions --errors-only
|
||||
```
|
||||
|
||||
### Action details
|
||||
|
||||
```bash
|
||||
# Show full details for one action: params, result, logs, source, snapshots
|
||||
npx playwright trace action <action-id>
|
||||
```
|
||||
|
||||
The `action` command displays available snapshot phases (before, input, after) and the exact command to extract them.
|
||||
|
||||
### Requests
|
||||
|
||||
```bash
|
||||
# All network requests: method, status, URL, duration, size
|
||||
npx playwright trace requests
|
||||
|
||||
# Filter by URL pattern
|
||||
npx playwright trace requests --grep "api"
|
||||
|
||||
# Filter by HTTP method
|
||||
npx playwright trace requests --method POST
|
||||
|
||||
# Only failed requests (status >= 400)
|
||||
npx playwright trace requests --failed
|
||||
```
|
||||
|
||||
### Request details
|
||||
|
||||
```bash
|
||||
# Show full details for one request: headers, body, security
|
||||
npx playwright trace request <request-id>
|
||||
```
|
||||
|
||||
### Console
|
||||
|
||||
```bash
|
||||
# All console messages and stdout/stderr
|
||||
npx playwright trace console
|
||||
|
||||
# Only errors
|
||||
npx playwright trace console --errors-only
|
||||
|
||||
# Only browser console (no stdout/stderr)
|
||||
npx playwright trace console --browser
|
||||
|
||||
# Only stdout/stderr (no browser console)
|
||||
npx playwright trace console --stdio
|
||||
```
|
||||
|
||||
### Errors
|
||||
|
||||
```bash
|
||||
# All errors with stack traces and associated actions
|
||||
npx playwright trace errors
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
The `snapshot` command loads the DOM snapshot for an action into a headless browser and runs a single browser command against it. Without a browser command, it returns the accessibility snapshot.
|
||||
|
||||
```bash
|
||||
# Get the accessibility snapshot (default)
|
||||
npx playwright trace snapshot <action-id>
|
||||
|
||||
# Use a specific phase
|
||||
npx playwright trace snapshot <action-id> --name before
|
||||
|
||||
# Run eval to query the DOM
|
||||
npx playwright trace snapshot <action-id> -- eval "document.title"
|
||||
npx playwright trace snapshot <action-id> -- eval "document.querySelector('#error').textContent"
|
||||
|
||||
# Eval on a specific element ref (from the snapshot)
|
||||
npx playwright trace snapshot <action-id> -- eval "el => el.getAttribute('data-testid')" e5
|
||||
|
||||
# Take a screenshot of the snapshot
|
||||
npx playwright trace snapshot <action-id> -- screenshot
|
||||
|
||||
# Redirect output to a file
|
||||
npx playwright trace snapshot <action-id> -- eval "document.body.outerHTML" --filename=page.html
|
||||
npx playwright trace snapshot <action-id> -- screenshot --filename=screenshot.png
|
||||
```
|
||||
|
||||
Only three browser commands are useful on a frozen snapshot: `snapshot`, `eval`, and `screenshot`.
|
||||
|
||||
### Attachments
|
||||
|
||||
```bash
|
||||
# List all trace attachments
|
||||
npx playwright trace attachments
|
||||
|
||||
# Extract an attachment by its number
|
||||
npx playwright trace attachment 1
|
||||
npx playwright trace attachment 1 -o out.png
|
||||
```
|
||||
|
||||
## Typical investigation
|
||||
|
||||
```bash
|
||||
# 1. Open the trace and see what's inside
|
||||
npx playwright trace open test-results/my-test/trace.zip
|
||||
|
||||
# 2. What actions ran?
|
||||
npx playwright trace actions
|
||||
|
||||
# 3. Which action failed?
|
||||
npx playwright trace actions --errors-only
|
||||
|
||||
# 4. What went wrong?
|
||||
npx playwright trace action 12
|
||||
|
||||
# 5. What did the page look like at that moment?
|
||||
npx playwright trace snapshot 12
|
||||
|
||||
# 6. Query the DOM for more detail
|
||||
npx playwright trace snapshot 12 -- eval "document.querySelector('.error-message').textContent"
|
||||
|
||||
# 7. Any relevant network failures?
|
||||
npx playwright trace requests --failed
|
||||
|
||||
# 8. Any console errors?
|
||||
npx playwright trace console --errors-only
|
||||
```
|
||||
48
node_modules/playwright-core/lib/tools/trace/installSkill.js
generated
vendored
Normal file
48
node_modules/playwright-core/lib/tools/trace/installSkill.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var installSkill_exports = {};
|
||||
__export(installSkill_exports, {
|
||||
installSkill: () => installSkill
|
||||
});
|
||||
module.exports = __toCommonJS(installSkill_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
async function installSkill() {
|
||||
const cwd = process.cwd();
|
||||
const skillSource = import_path.default.join(__dirname, "SKILL.md");
|
||||
const destDir = import_path.default.join(cwd, ".claude", "skills", "playwright-trace");
|
||||
await import_fs.default.promises.mkdir(destDir, { recursive: true });
|
||||
const destFile = import_path.default.join(destDir, "SKILL.md");
|
||||
await import_fs.default.promises.copyFile(skillSource, destFile);
|
||||
console.log(`\u2705 Skill installed to \`${import_path.default.relative(cwd, destFile)}\`.`);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
installSkill
|
||||
});
|
||||
142
node_modules/playwright-core/lib/tools/trace/traceActions.js
generated
vendored
Normal file
142
node_modules/playwright-core/lib/tools/trace/traceActions.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceActions_exports = {};
|
||||
__export(traceActions_exports, {
|
||||
traceAction: () => traceAction,
|
||||
traceActions: () => traceActions
|
||||
});
|
||||
module.exports = __toCommonJS(traceActions_exports);
|
||||
var import_traceModel = require("../../utils/isomorphic/trace/traceModel");
|
||||
var import_locatorGenerators = require("../../utils/isomorphic/locatorGenerators");
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
var import_formatUtils = require("../../utils/isomorphic/formatUtils");
|
||||
async function traceActions(options) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const actions = filterActions(trace.model.actions, options);
|
||||
const { rootItem } = (0, import_traceModel.buildActionTree)(actions);
|
||||
console.log(` ${"#".padStart(4)} ${"Time".padEnd(9)} ${"Action".padEnd(55)} ${"Duration".padStart(8)}`);
|
||||
console.log(` ${"\u2500".repeat(4)} ${"\u2500".repeat(9)} ${"\u2500".repeat(55)} ${"\u2500".repeat(8)}`);
|
||||
const visit = (item, indent) => {
|
||||
const action = item.action;
|
||||
const ordinal = trace.callIdToOrdinal.get(action.callId) ?? "?";
|
||||
const ts = (0, import_traceUtils.formatTimestamp)(action.startTime, trace.model.startTime);
|
||||
const duration = action.endTime ? (0, import_formatUtils.msToString)(action.endTime - action.startTime) : "running";
|
||||
const title = (0, import_traceUtils.actionTitle)(action);
|
||||
const locator = actionLocator(action);
|
||||
const error = action.error ? " \u2717" : "";
|
||||
const prefix = ` ${(ordinal + ".").padStart(4)} ${ts} ${indent}`;
|
||||
console.log(`${prefix}${title.padEnd(Math.max(1, 55 - indent.length))} ${duration.padStart(8)}${error}`);
|
||||
if (locator)
|
||||
console.log(`${" ".repeat(prefix.length)}${locator}`);
|
||||
for (const child of item.children)
|
||||
visit(child, indent + " ");
|
||||
};
|
||||
for (const child of rootItem.children)
|
||||
visit(child, "");
|
||||
}
|
||||
function filterActions(actions, options) {
|
||||
let result = actions.filter((a) => a.group !== "configuration");
|
||||
if (options.grep) {
|
||||
const pattern = new RegExp(options.grep, "i");
|
||||
result = result.filter((a) => pattern.test((0, import_traceUtils.actionTitle)(a)) || pattern.test(actionLocator(a) || ""));
|
||||
}
|
||||
if (options.errorsOnly)
|
||||
result = result.filter((a) => !!a.error);
|
||||
return result;
|
||||
}
|
||||
function actionLocator(action, sdkLanguage) {
|
||||
return action.params.selector ? (0, import_locatorGenerators.asLocatorDescription)(sdkLanguage || "javascript", action.params.selector) : void 0;
|
||||
}
|
||||
async function traceAction(actionId) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const action = trace.resolveActionId(actionId);
|
||||
if (!action) {
|
||||
console.error(`Action '${actionId}' not found. Use 'trace actions' to see available action IDs.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const title = (0, import_traceUtils.actionTitle)(action);
|
||||
console.log(`
|
||||
${title}
|
||||
`);
|
||||
console.log(" Time");
|
||||
console.log(` start: ${(0, import_traceUtils.formatTimestamp)(action.startTime, trace.model.startTime)}`);
|
||||
const duration = action.endTime ? (0, import_formatUtils.msToString)(action.endTime - action.startTime) : action.error ? "Timed Out" : "Running";
|
||||
console.log(` duration: ${duration}`);
|
||||
const paramKeys = Object.keys(action.params).filter((name) => name !== "info");
|
||||
if (paramKeys.length) {
|
||||
console.log("\n Parameters");
|
||||
for (const key of paramKeys) {
|
||||
const value = formatParamValue(action.params[key]);
|
||||
console.log(` ${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
if (action.result) {
|
||||
console.log("\n Return value");
|
||||
for (const [key, value] of Object.entries(action.result))
|
||||
console.log(` ${key}: ${formatParamValue(value)}`);
|
||||
}
|
||||
if (action.error) {
|
||||
console.log("\n Error");
|
||||
console.log(` ${action.error.message}`);
|
||||
}
|
||||
if (action.log.length) {
|
||||
console.log("\n Log");
|
||||
for (const entry of action.log) {
|
||||
const time = entry.time !== -1 ? (0, import_traceUtils.formatTimestamp)(entry.time, trace.model.startTime) : "";
|
||||
console.log(` ${time.padEnd(12)} ${entry.message}`);
|
||||
}
|
||||
}
|
||||
if (action.stack?.length) {
|
||||
console.log("\n Source");
|
||||
for (const frame of action.stack.slice(0, 5)) {
|
||||
const file = frame.file.replace(/.*[/\\](.*)/, "$1");
|
||||
console.log(` ${file}:${frame.line}:${frame.column}`);
|
||||
}
|
||||
}
|
||||
const snapshots = [];
|
||||
if (action.beforeSnapshot)
|
||||
snapshots.push("before");
|
||||
if (action.inputSnapshot)
|
||||
snapshots.push("input");
|
||||
if (action.afterSnapshot)
|
||||
snapshots.push("after");
|
||||
if (snapshots.length) {
|
||||
console.log("\n Snapshots");
|
||||
console.log(` available: ${snapshots.join(", ")}`);
|
||||
console.log(` usage: npx playwright trace snapshot ${actionId} --name <${snapshots.join("|")}>`);
|
||||
}
|
||||
console.log("");
|
||||
}
|
||||
function formatParamValue(value) {
|
||||
if (value === void 0 || value === null)
|
||||
return String(value);
|
||||
if (typeof value === "string")
|
||||
return `"${value}"`;
|
||||
if (typeof value !== "object")
|
||||
return String(value);
|
||||
if (value.guid)
|
||||
return "<handle>";
|
||||
return JSON.stringify(value).slice(0, 1e3);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceAction,
|
||||
traceActions
|
||||
});
|
||||
69
node_modules/playwright-core/lib/tools/trace/traceAttachments.js
generated
vendored
Normal file
69
node_modules/playwright-core/lib/tools/trace/traceAttachments.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceAttachments_exports = {};
|
||||
__export(traceAttachments_exports, {
|
||||
traceAttachment: () => traceAttachment,
|
||||
traceAttachments: () => traceAttachments
|
||||
});
|
||||
module.exports = __toCommonJS(traceAttachments_exports);
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
async function traceAttachments() {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
if (!trace.model.attachments.length) {
|
||||
console.log(" No attachments");
|
||||
return;
|
||||
}
|
||||
console.log(` ${"#".padStart(4)} ${"Name".padEnd(40)} ${"Content-Type".padEnd(30)} ${"Action".padEnd(8)}`);
|
||||
console.log(` ${"\u2500".repeat(4)} ${"\u2500".repeat(40)} ${"\u2500".repeat(30)} ${"\u2500".repeat(8)}`);
|
||||
for (let i = 0; i < trace.model.attachments.length; i++) {
|
||||
const a = trace.model.attachments[i];
|
||||
const actionOrdinal = trace.callIdToOrdinal.get(a.callId);
|
||||
console.log(` ${(i + 1 + ".").padStart(4)} ${a.name.padEnd(40)} ${a.contentType.padEnd(30)} ${(actionOrdinal !== void 0 ? String(actionOrdinal) : a.callId).padEnd(8)}`);
|
||||
}
|
||||
}
|
||||
async function traceAttachment(attachmentId, options) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const ordinal = parseInt(attachmentId, 10);
|
||||
const attachment = !isNaN(ordinal) && ordinal >= 1 && ordinal <= trace.model.attachments.length ? trace.model.attachments[ordinal - 1] : void 0;
|
||||
if (!attachment) {
|
||||
console.error(`Attachment '${attachmentId}' not found. Use 'trace attachments' to see available attachments.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
let content;
|
||||
if (attachment.sha1) {
|
||||
const blob = await trace.loader.resourceForSha1(attachment.sha1);
|
||||
if (blob)
|
||||
content = Buffer.from(await blob.arrayBuffer());
|
||||
} else if (attachment.base64) {
|
||||
content = Buffer.from(attachment.base64, "base64");
|
||||
}
|
||||
if (!content) {
|
||||
console.error(`Could not extract attachment content.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const outFile = await (0, import_traceUtils.saveOutputFile)(attachment.name, content, options.output);
|
||||
console.log(` Attachment saved to ${outFile}`);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceAttachment,
|
||||
traceAttachments
|
||||
});
|
||||
87
node_modules/playwright-core/lib/tools/trace/traceCli.js
generated
vendored
Normal file
87
node_modules/playwright-core/lib/tools/trace/traceCli.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceCli_exports = {};
|
||||
__export(traceCli_exports, {
|
||||
addTraceCommands: () => addTraceCommands
|
||||
});
|
||||
module.exports = __toCommonJS(traceCli_exports);
|
||||
function addTraceCommands(program, logErrorAndExit) {
|
||||
const traceCommand = program.command("trace").description("inspect trace files from the command line");
|
||||
traceCommand.command("open <trace>").description("extract trace file for inspection").action(async (trace) => {
|
||||
const { traceOpen } = require("./traceOpen");
|
||||
traceOpen(trace).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("close").description("remove extracted trace data").action(async () => {
|
||||
const { closeTrace } = require("./traceUtils");
|
||||
closeTrace().catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("actions").description("list actions in the trace").option("--grep <pattern>", "filter actions by title pattern").option("--errors-only", "only show failed actions").action(async (options) => {
|
||||
const { traceActions } = require("./traceActions");
|
||||
traceActions(options).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("action <action-id>").description("show details of a specific action").action(async (actionId) => {
|
||||
const { traceAction } = require("./traceActions");
|
||||
traceAction(actionId).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("requests").description("show network requests").option("--grep <pattern>", "filter by URL pattern").option("--method <method>", "filter by HTTP method").option("--status <code>", "filter by status code").option("--failed", "only show failed requests (status >= 400)").action(async (options) => {
|
||||
const { traceRequests } = require("./traceRequests");
|
||||
traceRequests(options).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("request <request-id>").description("show details of a specific network request").action(async (requestId) => {
|
||||
const { traceRequest } = require("./traceRequests");
|
||||
traceRequest(requestId).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("console").description("show console messages").option("--errors-only", "only show errors").option("--warnings", "show errors and warnings").option("--browser", "only browser console messages").option("--stdio", "only stdout/stderr").action(async (options) => {
|
||||
const { traceConsole } = require("./traceConsole");
|
||||
traceConsole(options).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("errors").description("show errors with stack traces").action(async () => {
|
||||
const { traceErrors } = require("./traceErrors");
|
||||
traceErrors().catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("snapshot <action-id>").description("run a playwright-cli command against a DOM snapshot").option("--name <name>", "snapshot phase: before, input, or after").option("--serve", "serve snapshot on localhost and keep running").allowUnknownOption(true).allowExcessArguments(true).action(async (actionId, options, cmd) => {
|
||||
try {
|
||||
const { traceSnapshot } = require("./traceSnapshot");
|
||||
const browserArgs = cmd.args.slice(1);
|
||||
await traceSnapshot(actionId, { ...options, browserArgs });
|
||||
} catch (e) {
|
||||
logErrorAndExit(e);
|
||||
}
|
||||
});
|
||||
traceCommand.command("screenshot <action-id>").description("save screencast screenshot for an action").option("-o, --output <path>", "output file path").action(async (actionId, options) => {
|
||||
const { traceScreenshot } = require("./traceScreenshot");
|
||||
traceScreenshot(actionId, options).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("attachments").description("list trace attachments").action(async () => {
|
||||
const { traceAttachments } = require("./traceAttachments");
|
||||
traceAttachments().catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("attachment <attachment-id>").description("extract a trace attachment by its number").option("-o, --output <path>", "output file path").action(async (attachmentId, options) => {
|
||||
const { traceAttachment } = require("./traceAttachments");
|
||||
traceAttachment(attachmentId, options).catch(logErrorAndExit);
|
||||
});
|
||||
traceCommand.command("install-skill").description("install SKILL.md for LLM integration").action(async () => {
|
||||
const { installSkill } = require("./installSkill");
|
||||
installSkill().catch(logErrorAndExit);
|
||||
});
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
addTraceCommands
|
||||
});
|
||||
97
node_modules/playwright-core/lib/tools/trace/traceConsole.js
generated
vendored
Normal file
97
node_modules/playwright-core/lib/tools/trace/traceConsole.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceConsole_exports = {};
|
||||
__export(traceConsole_exports, {
|
||||
traceConsole: () => traceConsole
|
||||
});
|
||||
module.exports = __toCommonJS(traceConsole_exports);
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
async function traceConsole(options) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const model = trace.model;
|
||||
const items = [];
|
||||
for (const event of model.events) {
|
||||
if (event.type === "console") {
|
||||
if (options.stdio)
|
||||
continue;
|
||||
const level = event.messageType;
|
||||
if (options.errorsOnly && level !== "error")
|
||||
continue;
|
||||
if (options.warnings && level !== "error" && level !== "warning")
|
||||
continue;
|
||||
const url = event.location.url;
|
||||
const filename = url ? url.substring(url.lastIndexOf("/") + 1) : "<anonymous>";
|
||||
items.push({
|
||||
type: "browser",
|
||||
level,
|
||||
text: event.text,
|
||||
location: `${filename}:${event.location.lineNumber}`,
|
||||
timestamp: event.time
|
||||
});
|
||||
}
|
||||
if (event.type === "event" && event.method === "pageError") {
|
||||
if (options.stdio)
|
||||
continue;
|
||||
const error = event.params.error;
|
||||
items.push({
|
||||
type: "browser",
|
||||
level: "error",
|
||||
text: error?.error?.message || String(error?.value || ""),
|
||||
timestamp: event.time
|
||||
});
|
||||
}
|
||||
}
|
||||
for (const event of model.stdio) {
|
||||
if (options.browser)
|
||||
continue;
|
||||
if (options.errorsOnly && event.type !== "stderr")
|
||||
continue;
|
||||
if (options.warnings && event.type !== "stderr")
|
||||
continue;
|
||||
let text = "";
|
||||
if (event.text)
|
||||
text = event.text.trim();
|
||||
if (event.base64)
|
||||
text = Buffer.from(event.base64, "base64").toString("utf-8").trim();
|
||||
if (!text)
|
||||
continue;
|
||||
items.push({
|
||||
type: event.type,
|
||||
level: event.type === "stderr" ? "error" : "info",
|
||||
text,
|
||||
timestamp: event.timestamp
|
||||
});
|
||||
}
|
||||
items.sort((a, b) => a.timestamp - b.timestamp);
|
||||
if (!items.length) {
|
||||
console.log(" No console entries");
|
||||
return;
|
||||
}
|
||||
for (const item of items) {
|
||||
const ts = (0, import_traceUtils.formatTimestamp)(item.timestamp, model.startTime);
|
||||
const source = item.type === "browser" ? "[browser]" : `[${item.type}]`;
|
||||
const level = item.level.padEnd(8);
|
||||
const location = item.location ? ` ${item.location}` : "";
|
||||
console.log(` ${ts} ${source.padEnd(10)} ${level} ${item.text}${location}`);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceConsole
|
||||
});
|
||||
55
node_modules/playwright-core/lib/tools/trace/traceErrors.js
generated
vendored
Normal file
55
node_modules/playwright-core/lib/tools/trace/traceErrors.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceErrors_exports = {};
|
||||
__export(traceErrors_exports, {
|
||||
traceErrors: () => traceErrors
|
||||
});
|
||||
module.exports = __toCommonJS(traceErrors_exports);
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
async function traceErrors() {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const model = trace.model;
|
||||
if (!model.errorDescriptors.length) {
|
||||
console.log(" No errors");
|
||||
return;
|
||||
}
|
||||
for (const error of model.errorDescriptors) {
|
||||
if (error.action) {
|
||||
const title = (0, import_traceUtils.actionTitle)(error.action);
|
||||
console.log(`
|
||||
\u2717 ${title}`);
|
||||
} else {
|
||||
console.log(`
|
||||
\u2717 Error`);
|
||||
}
|
||||
if (error.stack?.length) {
|
||||
const frame = error.stack[0];
|
||||
const file = frame.file.replace(/.*[/\\](.*)/, "$1");
|
||||
console.log(` at ${file}:${frame.line}:${frame.column}`);
|
||||
}
|
||||
console.log("");
|
||||
const indented = error.message.split("\n").map((l) => ` ${l}`).join("\n");
|
||||
console.log(indented);
|
||||
}
|
||||
console.log("");
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceErrors
|
||||
});
|
||||
69
node_modules/playwright-core/lib/tools/trace/traceOpen.js
generated
vendored
Normal file
69
node_modules/playwright-core/lib/tools/trace/traceOpen.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceOpen_exports = {};
|
||||
__export(traceOpen_exports, {
|
||||
traceOpen: () => traceOpen
|
||||
});
|
||||
module.exports = __toCommonJS(traceOpen_exports);
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
var import_formatUtils = require("../../utils/isomorphic/formatUtils");
|
||||
async function traceOpen(traceFile) {
|
||||
await (0, import_traceUtils.openTrace)(traceFile);
|
||||
await traceInfo();
|
||||
}
|
||||
async function traceInfo() {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const model = trace.model;
|
||||
const info = {
|
||||
browser: model.browserName || "unknown",
|
||||
platform: model.platform || "unknown",
|
||||
playwrightVersion: model.playwrightVersion || "unknown",
|
||||
title: model.title || "",
|
||||
duration: (0, import_formatUtils.msToString)(model.endTime - model.startTime),
|
||||
durationMs: model.endTime - model.startTime,
|
||||
startTime: model.wallTime ? new Date(model.wallTime).toISOString() : "unknown",
|
||||
viewport: model.options.viewport ? `${model.options.viewport.width}x${model.options.viewport.height}` : "default",
|
||||
actions: model.actions.length,
|
||||
pages: model.pages.length,
|
||||
network: model.resources.length,
|
||||
errors: model.errorDescriptors.length,
|
||||
attachments: model.attachments.length,
|
||||
consoleMessages: model.events.filter((e) => e.type === "console").length
|
||||
};
|
||||
console.log("");
|
||||
console.log(` Browser: ${info.browser}`);
|
||||
console.log(` Platform: ${info.platform}`);
|
||||
console.log(` Playwright: ${info.playwrightVersion}`);
|
||||
if (info.title)
|
||||
console.log(` Title: ${info.title}`);
|
||||
console.log(` Duration: ${info.duration}`);
|
||||
console.log(` Start time: ${info.startTime}`);
|
||||
console.log(` Viewport: ${info.viewport}`);
|
||||
console.log(` Actions: ${info.actions}`);
|
||||
console.log(` Pages: ${info.pages}`);
|
||||
console.log(` Network: ${info.network} requests`);
|
||||
console.log(` Errors: ${info.errors}`);
|
||||
console.log(` Attachments: ${info.attachments}`);
|
||||
console.log(` Console: ${info.consoleMessages} messages`);
|
||||
console.log("");
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceOpen
|
||||
});
|
||||
96
node_modules/playwright-core/lib/tools/trace/traceParser.js
generated
vendored
Normal file
96
node_modules/playwright-core/lib/tools/trace/traceParser.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceParser_exports = {};
|
||||
__export(traceParser_exports, {
|
||||
DirTraceLoaderBackend: () => DirTraceLoaderBackend,
|
||||
extractTrace: () => extractTrace
|
||||
});
|
||||
module.exports = __toCommonJS(traceParser_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_zipFile = require("../../server/utils/zipFile");
|
||||
class DirTraceLoaderBackend {
|
||||
constructor(dir) {
|
||||
this._dir = dir;
|
||||
}
|
||||
isLive() {
|
||||
return false;
|
||||
}
|
||||
async entryNames() {
|
||||
const entries = [];
|
||||
const walk = async (dir, prefix) => {
|
||||
const items = await import_fs.default.promises.readdir(dir, { withFileTypes: true });
|
||||
for (const item of items) {
|
||||
if (item.isDirectory())
|
||||
await walk(import_path.default.join(dir, item.name), prefix ? `${prefix}/${item.name}` : item.name);
|
||||
else
|
||||
entries.push(prefix ? `${prefix}/${item.name}` : item.name);
|
||||
}
|
||||
};
|
||||
await walk(this._dir, "");
|
||||
return entries;
|
||||
}
|
||||
async hasEntry(entryName) {
|
||||
try {
|
||||
await import_fs.default.promises.access(import_path.default.join(this._dir, entryName));
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async readText(entryName) {
|
||||
try {
|
||||
return await import_fs.default.promises.readFile(import_path.default.join(this._dir, entryName), "utf-8");
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
async readBlob(entryName) {
|
||||
try {
|
||||
const buffer = await import_fs.default.promises.readFile(import_path.default.join(this._dir, entryName));
|
||||
return new Blob([new Uint8Array(buffer)]);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
async function extractTrace(traceFile, outDir) {
|
||||
const zipFile = new import_zipFile.ZipFile(traceFile);
|
||||
const entries = await zipFile.entries();
|
||||
for (const entry of entries) {
|
||||
const outPath = import_path.default.join(outDir, entry);
|
||||
await import_fs.default.promises.mkdir(import_path.default.dirname(outPath), { recursive: true });
|
||||
const buffer = await zipFile.read(entry);
|
||||
await import_fs.default.promises.writeFile(outPath, buffer);
|
||||
}
|
||||
zipFile.close();
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
DirTraceLoaderBackend,
|
||||
extractTrace
|
||||
});
|
||||
182
node_modules/playwright-core/lib/tools/trace/traceRequests.js
generated
vendored
Normal file
182
node_modules/playwright-core/lib/tools/trace/traceRequests.js
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceRequests_exports = {};
|
||||
__export(traceRequests_exports, {
|
||||
traceRequest: () => traceRequest,
|
||||
traceRequests: () => traceRequests
|
||||
});
|
||||
module.exports = __toCommonJS(traceRequests_exports);
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
var import_formatUtils = require("../../utils/isomorphic/formatUtils");
|
||||
async function traceRequests(options) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const model = trace.model;
|
||||
let indexed = model.resources.map((r, i) => ({ resource: r, ordinal: i + 1 }));
|
||||
if (options.grep) {
|
||||
const pattern = new RegExp(options.grep, "i");
|
||||
indexed = indexed.filter(({ resource: r }) => pattern.test(r.request.url));
|
||||
}
|
||||
if (options.method)
|
||||
indexed = indexed.filter(({ resource: r }) => r.request.method.toLowerCase() === options.method.toLowerCase());
|
||||
if (options.status) {
|
||||
const code = parseInt(options.status, 10);
|
||||
indexed = indexed.filter(({ resource: r }) => r.response.status === code);
|
||||
}
|
||||
if (options.failed)
|
||||
indexed = indexed.filter(({ resource: r }) => r.response.status >= 400 || r.response.status === -1);
|
||||
if (!indexed.length) {
|
||||
console.log(" No network requests");
|
||||
return;
|
||||
}
|
||||
console.log(` ${"#".padStart(4)} ${"Method".padEnd(8)} ${"Status".padEnd(8)} ${"Name".padEnd(45)} ${"Duration".padStart(10)} ${"Size".padStart(8)} ${"Route".padEnd(10)}`);
|
||||
console.log(` ${"\u2500".repeat(4)} ${"\u2500".repeat(8)} ${"\u2500".repeat(8)} ${"\u2500".repeat(45)} ${"\u2500".repeat(10)} ${"\u2500".repeat(8)} ${"\u2500".repeat(10)}`);
|
||||
for (const { resource: r, ordinal } of indexed) {
|
||||
let name;
|
||||
try {
|
||||
const url = new URL(r.request.url);
|
||||
name = url.pathname.substring(url.pathname.lastIndexOf("/") + 1);
|
||||
if (!name)
|
||||
name = url.host;
|
||||
if (url.search)
|
||||
name += url.search;
|
||||
} catch {
|
||||
name = r.request.url;
|
||||
}
|
||||
if (name.length > 45)
|
||||
name = name.substring(0, 42) + "...";
|
||||
const status = r.response.status > 0 ? String(r.response.status) : "ERR";
|
||||
const size = r.response._transferSize > 0 ? r.response._transferSize : r.response.bodySize;
|
||||
const route = formatRouteStatus(r);
|
||||
console.log(` ${(ordinal + ".").padStart(4)} ${r.request.method.padEnd(8)} ${status.padEnd(8)} ${name.padEnd(45)} ${(0, import_formatUtils.msToString)(r.time).padStart(10)} ${bytesToString(size).padStart(8)} ${route.padEnd(10)}`);
|
||||
}
|
||||
}
|
||||
async function traceRequest(requestId) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const model = trace.model;
|
||||
const ordinal = parseInt(requestId, 10);
|
||||
const resource = !isNaN(ordinal) && ordinal >= 1 && ordinal <= model.resources.length ? model.resources[ordinal - 1] : void 0;
|
||||
if (!resource) {
|
||||
console.error(`Request '${requestId}' not found. Use 'trace requests' to see available request IDs.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const r = resource;
|
||||
const status = r.response.status > 0 ? `${r.response.status} ${r.response.statusText}` : "ERR";
|
||||
const size = r.response._transferSize > 0 ? r.response._transferSize : r.response.bodySize;
|
||||
console.log(`
|
||||
${r.request.method} ${r.request.url}
|
||||
`);
|
||||
console.log(" General");
|
||||
console.log(` status: ${status}`);
|
||||
console.log(` duration: ${(0, import_formatUtils.msToString)(r.time)}`);
|
||||
console.log(` size: ${bytesToString(size)}`);
|
||||
if (r.response.content.mimeType)
|
||||
console.log(` type: ${r.response.content.mimeType}`);
|
||||
const route = formatRouteStatus(r);
|
||||
if (route)
|
||||
console.log(` route: ${route}`);
|
||||
if (r.serverIPAddress)
|
||||
console.log(` server: ${r.serverIPAddress}${r._serverPort ? ":" + r._serverPort : ""}`);
|
||||
if (r.response._failureText)
|
||||
console.log(` error: ${r.response._failureText}`);
|
||||
if (r.request.headers.length) {
|
||||
console.log("\n Request headers");
|
||||
for (const h of r.request.headers)
|
||||
console.log(` ${h.name}: ${h.value}`);
|
||||
}
|
||||
if (r.request.postData) {
|
||||
console.log("\n Request body");
|
||||
const resource2 = r.request.postData._sha1 ?? r.request.postData._file;
|
||||
if (resource2) {
|
||||
console.log(` ${import_path.default.relative(process.cwd(), import_path.default.join(trace.model.traceUri, "resources", resource2))}`);
|
||||
} else {
|
||||
const text = r.request.postData.text.length > 2e3 ? r.request.postData.text.substring(0, 2e3) + "..." : r.request.postData.text;
|
||||
console.log(` ${text}`);
|
||||
}
|
||||
}
|
||||
if (r.response.headers.length) {
|
||||
console.log("\n Response headers");
|
||||
for (const h of r.response.headers)
|
||||
console.log(` ${h.name}: ${h.value}`);
|
||||
}
|
||||
if (r.response.bodySize > 0) {
|
||||
const resource2 = r.response.content._sha1 ?? r.response.content._file;
|
||||
if (resource2) {
|
||||
console.log("\n Response body");
|
||||
console.log(` ${import_path.default.relative(process.cwd(), import_path.default.join(trace.model.traceUri, "resources", resource2))}`);
|
||||
} else if (r.response.content.text) {
|
||||
const text = r.response.content.text.length > 2e3 ? r.response.content.text.substring(0, 2e3) + "..." : r.response.content.text;
|
||||
console.log("\n Response body");
|
||||
console.log(` ${text}`);
|
||||
}
|
||||
}
|
||||
if (r._securityDetails) {
|
||||
console.log("\n Security");
|
||||
if (r._securityDetails.protocol)
|
||||
console.log(` protocol: ${r._securityDetails.protocol}`);
|
||||
if (r._securityDetails.subjectName)
|
||||
console.log(` subject: ${r._securityDetails.subjectName}`);
|
||||
if (r._securityDetails.issuer)
|
||||
console.log(` issuer: ${r._securityDetails.issuer}`);
|
||||
}
|
||||
console.log("");
|
||||
}
|
||||
function bytesToString(bytes) {
|
||||
if (bytes < 0 || !isFinite(bytes))
|
||||
return "-";
|
||||
if (bytes === 0)
|
||||
return "0";
|
||||
if (bytes < 1e3)
|
||||
return bytes.toFixed(0);
|
||||
const kb = bytes / 1024;
|
||||
if (kb < 1e3)
|
||||
return kb.toFixed(1) + "K";
|
||||
const mb = kb / 1024;
|
||||
if (mb < 1e3)
|
||||
return mb.toFixed(1) + "M";
|
||||
const gb = mb / 1024;
|
||||
return gb.toFixed(1) + "G";
|
||||
}
|
||||
function formatRouteStatus(r) {
|
||||
if (r._wasAborted)
|
||||
return "aborted";
|
||||
if (r._wasContinued)
|
||||
return "continued";
|
||||
if (r._wasFulfilled)
|
||||
return "fulfilled";
|
||||
if (r._apiRequest)
|
||||
return "api";
|
||||
return "";
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceRequest,
|
||||
traceRequests
|
||||
});
|
||||
68
node_modules/playwright-core/lib/tools/trace/traceScreenshot.js
generated
vendored
Normal file
68
node_modules/playwright-core/lib/tools/trace/traceScreenshot.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceScreenshot_exports = {};
|
||||
__export(traceScreenshot_exports, {
|
||||
traceScreenshot: () => traceScreenshot
|
||||
});
|
||||
module.exports = __toCommonJS(traceScreenshot_exports);
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
async function traceScreenshot(actionId, options) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const action = trace.resolveActionId(actionId);
|
||||
if (!action) {
|
||||
console.error(`Action '${actionId}' not found.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const pageId = action.pageId;
|
||||
if (!pageId) {
|
||||
console.error(`Action '${actionId}' has no associated page.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const callId = action.callId;
|
||||
const storage = trace.loader.storage();
|
||||
const snapshotNames = ["input", "before", "after"];
|
||||
let sha1;
|
||||
for (const name of snapshotNames) {
|
||||
const renderer = storage.snapshotByName(pageId, `${name}@${callId}`);
|
||||
sha1 = renderer?.closestScreenshot();
|
||||
if (sha1)
|
||||
break;
|
||||
}
|
||||
if (!sha1) {
|
||||
console.error(`No screenshot found for action '${actionId}'.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const blob = await trace.loader.resourceForSha1(sha1);
|
||||
if (!blob) {
|
||||
console.error(`Screenshot resource not found.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const defaultName = `screenshot-${actionId}.png`;
|
||||
const buffer = Buffer.from(await blob.arrayBuffer());
|
||||
const outFile = await (0, import_traceUtils.saveOutputFile)(defaultName, buffer, options.output);
|
||||
console.log(` Screenshot saved to ${outFile}`);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceScreenshot
|
||||
});
|
||||
149
node_modules/playwright-core/lib/tools/trace/traceSnapshot.js
generated
vendored
Normal file
149
node_modules/playwright-core/lib/tools/trace/traceSnapshot.js
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceSnapshot_exports = {};
|
||||
__export(traceSnapshot_exports, {
|
||||
traceSnapshot: () => traceSnapshot
|
||||
});
|
||||
module.exports = __toCommonJS(traceSnapshot_exports);
|
||||
var import_browserBackend = require("../backend/browserBackend");
|
||||
var import_tools = require("../backend/tools");
|
||||
var playwright = __toESM(require("../../.."));
|
||||
var import_utils = require("../../utils");
|
||||
var import_command = require("../cli-daemon/command");
|
||||
var import_minimist = require("../cli-client/minimist");
|
||||
var import_commands = require("../cli-daemon/commands");
|
||||
var import_traceUtils = require("./traceUtils");
|
||||
async function traceSnapshot(actionId, options) {
|
||||
const trace = await (0, import_traceUtils.loadTrace)();
|
||||
const action = trace.resolveActionId(actionId);
|
||||
if (!action) {
|
||||
console.error(`Action '${actionId}' not found.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const pageId = action.pageId;
|
||||
if (!pageId) {
|
||||
console.error(`Action '${actionId}' has no associated page.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const callId = action.callId;
|
||||
const storage = trace.loader.storage();
|
||||
let snapshotName;
|
||||
let renderer;
|
||||
if (options.name) {
|
||||
snapshotName = options.name;
|
||||
renderer = storage.snapshotByName(pageId, `${snapshotName}@${callId}`);
|
||||
} else {
|
||||
for (const candidate of ["input", "before", "after"]) {
|
||||
renderer = storage.snapshotByName(pageId, `${candidate}@${callId}`);
|
||||
if (renderer) {
|
||||
snapshotName = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!renderer || !snapshotName) {
|
||||
console.error(`No snapshot found for action '${actionId}'.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const snapshotKey = `${snapshotName}@${callId}`;
|
||||
const server = await serveTraceSnapshot(storage, trace.loader, pageId, snapshotKey);
|
||||
if (options.serve) {
|
||||
console.log(`Serving snapshot at ${server.url}`);
|
||||
await new Promise(() => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
await runCommandOnSnapshot(server, options.browserArgs || []);
|
||||
}
|
||||
async function serveTraceSnapshot(storage, loader, pageId, snapshotKey) {
|
||||
const { SnapshotServer } = require("../../utils/isomorphic/trace/snapshotServer");
|
||||
const { HttpServer } = require("../../server/utils/httpServer");
|
||||
const snapshotServer = new SnapshotServer(storage, (sha1) => loader.resourceForSha1(sha1));
|
||||
const httpServer = new HttpServer();
|
||||
httpServer.routePrefix("/snapshot", (request, response) => {
|
||||
const url = new URL("http://localhost" + request.url);
|
||||
const searchParams = url.searchParams;
|
||||
searchParams.set("name", snapshotKey);
|
||||
const snapshotResponse = snapshotServer.serveSnapshot(pageId, searchParams, "/snapshot");
|
||||
response.statusCode = snapshotResponse.status;
|
||||
snapshotResponse.headers.forEach((value, key) => response.setHeader(key, value));
|
||||
snapshotResponse.text().then((text) => response.end(text));
|
||||
return true;
|
||||
});
|
||||
httpServer.routePrefix("/", (_request, response) => {
|
||||
response.statusCode = 302;
|
||||
response.setHeader("Location", "/snapshot");
|
||||
response.end();
|
||||
return true;
|
||||
});
|
||||
await httpServer.start({ preferredPort: 0 });
|
||||
return { url: httpServer.urlPrefix("human-readable"), stop: () => httpServer.stop() };
|
||||
}
|
||||
async function runCommandOnSnapshot(server, browserArgs) {
|
||||
const browser = await playwright.chromium.launch({ headless: true });
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.url);
|
||||
const backend = new import_browserBackend.BrowserBackend({
|
||||
snapshot: { mode: "full" },
|
||||
outputMode: "file",
|
||||
skillMode: true
|
||||
}, context, import_tools.browserTools);
|
||||
await backend.initialize({ cwd: process.cwd() });
|
||||
try {
|
||||
if (!browserArgs.length)
|
||||
browserArgs = ["snapshot"];
|
||||
const args = (0, import_minimist.minimist)(browserArgs, { string: ["_"] });
|
||||
const command = import_commands.commands[args._[0]];
|
||||
if (!command)
|
||||
throw new Error(`Unknown command: ${args._[0]}`);
|
||||
const { toolName, toolParams } = (0, import_command.parseCommand)(command, args);
|
||||
const result = await backend.callTool(toolName, toolParams);
|
||||
const text = result.content[0]?.type === "text" ? result.content[0].text : void 0;
|
||||
if (text)
|
||||
console.log(text);
|
||||
if (result.isError) {
|
||||
console.error("Command failed.");
|
||||
process.exitCode = 1;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
await server.stop().catch((e) => console.error(e));
|
||||
await (0, import_utils.gracefullyCloseAll)();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
traceSnapshot
|
||||
});
|
||||
153
node_modules/playwright-core/lib/tools/trace/traceUtils.js
generated
vendored
Normal file
153
node_modules/playwright-core/lib/tools/trace/traceUtils.js
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var traceUtils_exports = {};
|
||||
__export(traceUtils_exports, {
|
||||
LoadedTrace: () => LoadedTrace,
|
||||
actionTitle: () => actionTitle,
|
||||
closeTrace: () => closeTrace,
|
||||
formatTimestamp: () => formatTimestamp,
|
||||
loadTrace: () => loadTrace,
|
||||
openTrace: () => openTrace,
|
||||
saveOutputFile: () => saveOutputFile
|
||||
});
|
||||
module.exports = __toCommonJS(traceUtils_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_traceModel = require("../../utils/isomorphic/trace/traceModel");
|
||||
var import_traceLoader = require("../../utils/isomorphic/trace/traceLoader");
|
||||
var import_protocolFormatter = require("../../utils/isomorphic/protocolFormatter");
|
||||
var import_traceParser = require("./traceParser");
|
||||
const traceDir = import_path.default.join(".playwright-cli", "trace");
|
||||
const cliOutputDir = ".playwright-cli";
|
||||
class LoadedTrace {
|
||||
constructor(model, loader, ordinals) {
|
||||
this.model = model;
|
||||
this.loader = loader;
|
||||
this.ordinalToCallId = ordinals.ordinalToCallId;
|
||||
this.callIdToOrdinal = ordinals.callIdToOrdinal;
|
||||
}
|
||||
resolveActionId(actionId) {
|
||||
const ordinal = parseInt(actionId, 10);
|
||||
if (!isNaN(ordinal)) {
|
||||
const callId = this.ordinalToCallId.get(ordinal);
|
||||
if (callId)
|
||||
return this.model.actions.find((a) => a.callId === callId);
|
||||
}
|
||||
return this.model.actions.find((a) => a.callId === actionId);
|
||||
}
|
||||
}
|
||||
function ensureTraceOpen() {
|
||||
if (!import_fs.default.existsSync(traceDir))
|
||||
throw new Error(`No trace opened. Run 'npx playwright trace open <file>' first.`);
|
||||
return traceDir;
|
||||
}
|
||||
async function closeTrace() {
|
||||
if (import_fs.default.existsSync(traceDir))
|
||||
await import_fs.default.promises.rm(traceDir, { recursive: true });
|
||||
}
|
||||
async function openTrace(traceFile) {
|
||||
const filePath = import_path.default.resolve(traceFile);
|
||||
if (!import_fs.default.existsSync(filePath))
|
||||
throw new Error(`Trace file not found: ${filePath}`);
|
||||
await closeTrace();
|
||||
await import_fs.default.promises.mkdir(traceDir, { recursive: true });
|
||||
if (filePath.endsWith(".zip"))
|
||||
await (0, import_traceParser.extractTrace)(filePath, traceDir);
|
||||
else
|
||||
await import_fs.default.promises.writeFile(import_path.default.join(traceDir, ".link"), filePath, "utf-8");
|
||||
}
|
||||
async function loadTrace() {
|
||||
const dir = ensureTraceOpen();
|
||||
const linkFile = import_path.default.join(dir, ".link");
|
||||
let traceDir2;
|
||||
let traceFile;
|
||||
if (import_fs.default.existsSync(linkFile)) {
|
||||
const tracePath = await import_fs.default.promises.readFile(linkFile, "utf-8");
|
||||
traceDir2 = import_path.default.dirname(tracePath);
|
||||
traceFile = import_path.default.basename(tracePath);
|
||||
} else {
|
||||
traceDir2 = dir;
|
||||
}
|
||||
const backend = new import_traceParser.DirTraceLoaderBackend(traceDir2);
|
||||
const loader = new import_traceLoader.TraceLoader();
|
||||
await loader.load(backend, traceFile);
|
||||
const model = new import_traceModel.TraceModel(traceDir2, loader.contextEntries);
|
||||
return new LoadedTrace(model, loader, buildOrdinalMap(model));
|
||||
}
|
||||
function formatTimestamp(ms, base) {
|
||||
const relative = ms - base;
|
||||
if (relative < 0)
|
||||
return "0:00.000";
|
||||
const totalMs = Math.floor(relative);
|
||||
const minutes = Math.floor(totalMs / 6e4);
|
||||
const seconds = Math.floor(totalMs % 6e4 / 1e3);
|
||||
const millis = totalMs % 1e3;
|
||||
return `${minutes}:${seconds.toString().padStart(2, "0")}.${millis.toString().padStart(3, "0")}`;
|
||||
}
|
||||
function actionTitle(action) {
|
||||
return (0, import_protocolFormatter.renderTitleForCall)({ ...action, type: action.class }) || `${action.class}.${action.method}`;
|
||||
}
|
||||
async function saveOutputFile(fileName, content, explicitOutput) {
|
||||
let outFile;
|
||||
if (explicitOutput) {
|
||||
outFile = explicitOutput;
|
||||
} else {
|
||||
await import_fs.default.promises.mkdir(cliOutputDir, { recursive: true });
|
||||
outFile = import_path.default.join(cliOutputDir, fileName);
|
||||
}
|
||||
await import_fs.default.promises.writeFile(outFile, content);
|
||||
return outFile;
|
||||
}
|
||||
function buildOrdinalMap(model) {
|
||||
const actions = model.actions.filter((a) => a.group !== "configuration");
|
||||
const { rootItem } = (0, import_traceModel.buildActionTree)(actions);
|
||||
const ordinalToCallId = /* @__PURE__ */ new Map();
|
||||
const callIdToOrdinal = /* @__PURE__ */ new Map();
|
||||
let ordinal = 1;
|
||||
const visit = (item) => {
|
||||
ordinalToCallId.set(ordinal, item.action.callId);
|
||||
callIdToOrdinal.set(item.action.callId, ordinal);
|
||||
ordinal++;
|
||||
for (const child of item.children)
|
||||
visit(child);
|
||||
};
|
||||
for (const child of rootItem.children)
|
||||
visit(child);
|
||||
return { ordinalToCallId, callIdToOrdinal };
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
LoadedTrace,
|
||||
actionTitle,
|
||||
closeTrace,
|
||||
formatTimestamp,
|
||||
loadTrace,
|
||||
openTrace,
|
||||
saveOutputFile
|
||||
});
|
||||
Reference in New Issue
Block a user