You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* Playwright codegen headed 录制 Priority1 公开询价演示路径(跨平台)
*/
import { spawn } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
const ROOT = process.cwd();
const OUTPUT_DIR = path.join(ROOT, ".rpa", "recordings");
const STORAGE_PATH =
process.env.PRIORITY1_STORAGE_STATE_PATH?.trim() ||
path.join(ROOT, ".rpa", "priority1-storage.json");
/** 公开即时询价页Feathery 两步表单) */
export const DEFAULT_PRIORITY1_QUOTE_URL =
"https://www.priority1.com/instant-freight-quotes/";
const FORBIDDEN_QUOTE_URL_PATTERNS: RegExp[] = [
/dashboard\.priority1\.com/i,
/api\.priority1\.com/i,
];
export function isForbiddenPriority1QuoteUrl(url: string): boolean {
return FORBIDDEN_QUOTE_URL_PATTERNS.some((pattern) => pattern.test(url));
}
function printHelp(): void {
console.log(`
用法: npm run record:priority1 [-- 起始URL]
启动 Playwright codegenheaded录制 Priority1 公开询价完整路径。
默认起始页:
${DEFAULT_PRIORITY1_QUOTE_URL}
禁止入口:
- dashboard.priority1.comCabo TMS 登录后台)
- api.priority1.comAPI 文档门户,非 UI
产出:
.rpa/recordings/priority1-<时间戳>.js
.rpa/priority1-storage.json若会话可持久化
推荐演示样例(与截图一致):
Step 1: LTL | 10118 → 90017 | One Time Shipment | 取货日 | 邮箱 | 电话
Step 2: 48×40×48 in | 21 lbs | Pallet×1 | Class 70
Pickup: Residence + Liftgate + Residential
Delivery: Residence + Liftgate + Residential
提交后等待承运商报价列表出现再结束录制
也可从首页开始录制:
npm run record:priority1 -- https://www.priority1.com/
`);
}
function formatTimestamp(): string {
const d = new Date();
const pad = (n: number) => String(n).padStart(2, "0");
return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
}
function main(): void {
const rawArg = process.argv[2];
const startUrl =
rawArg && rawArg !== "-h" && rawArg !== "--help"
? rawArg
: DEFAULT_PRIORITY1_QUOTE_URL;
if (rawArg === "-h" || rawArg === "--help") {
printHelp();
process.exit(0);
}
if (isForbiddenPriority1QuoteUrl(startUrl)) {
console.error("错误:禁止使用入口 URL");
console.error("请使用公开询价页或首页,勿使用 Cabo 后台 / API 门户");
process.exit(1);
}
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
fs.mkdirSync(path.dirname(STORAGE_PATH), { recursive: true });
const outputFile = path.join(OUTPUT_DIR, `priority1-${formatTimestamp()}.js`);
const args = [
"playwright",
"codegen",
"--target=javascript",
"-o",
outputFile,
`--save-storage=${STORAGE_PATH}`,
];
if (fs.existsSync(STORAGE_PATH)) {
args.push(`--load-storage=${STORAGE_PATH}`);
console.log(`已加载已有 storageState: ${STORAGE_PATH}`);
}
args.push(startUrl);
console.log("=== Priority1 RPA 录制headed===");
console.log("RPA_HEADLESS=false");
console.log("禁止入口: dashboard.priority1.com / api.priority1.com");
console.log(`起始 URL: ${startUrl}`);
console.log(`脚本产出: ${outputFile}`);
console.log(`storageState: ${STORAGE_PATH}`);
console.log("");
const child = spawn("npx", args, {
stdio: "inherit",
shell: true,
cwd: ROOT,
env: { ...process.env, RPA_HEADLESS: "false" },
});
child.on("error", (error) => {
console.error("启动 playwright codegen 失败:", error);
process.exit(1);
});
child.on("exit", (code) => {
process.exit(code ?? 0);
});
}
const isDirectRun =
typeof process.argv[1] === "string" &&
path.resolve(process.argv[1]) === path.resolve(__filename);
if (isDirectRun) {
main();
}