@browsermation/test 0.0.52 → 0.0.53
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/bin/cli.js +4 -2
- package/dist/bin/hook.d.ts +1 -0
- package/dist/bin/hook.js +325 -0
- package/dist/index.js +1 -1
- package/package.json +4 -2
package/dist/bin/cli.js
CHANGED
|
@@ -42258,7 +42258,7 @@ var {
|
|
|
42258
42258
|
// package.json
|
|
42259
42259
|
var package_default = {
|
|
42260
42260
|
name: "@browsermation/test",
|
|
42261
|
-
version: "0.0.
|
|
42261
|
+
version: "0.0.53",
|
|
42262
42262
|
description: "The testing platform for Playwright by Browsermation.",
|
|
42263
42263
|
main: "./dist/index.js",
|
|
42264
42264
|
types: "./dist/index.d.ts",
|
|
@@ -42285,10 +42285,11 @@ var package_default = {
|
|
|
42285
42285
|
],
|
|
42286
42286
|
scripts: {
|
|
42287
42287
|
"build:cli": "esbuild src/bin/cli.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/bin/cli.js",
|
|
42288
|
+
"build:hook": "esbuild src/bin/hook.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/bin/hook.js",
|
|
42288
42289
|
"build:reporter": "esbuild src/reporter/reporter.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/reporter.js",
|
|
42289
42290
|
"build:index": "esbuild src/index.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/index.js",
|
|
42290
42291
|
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
42291
|
-
build: "rm -rf dist && npm run build:cli && npm run build:index && npm run build:reporter && npm run build:types",
|
|
42292
|
+
build: "rm -rf dist && npm run build:cli && npm run build:hook && npm run build:index && npm run build:reporter && npm run build:types",
|
|
42292
42293
|
start: "node dist/bin/cli.js",
|
|
42293
42294
|
"build:start": "npm run build && npm start",
|
|
42294
42295
|
publishPackage: "npm run build && npm publish --access public"
|
|
@@ -42315,6 +42316,7 @@ var package_default = {
|
|
|
42315
42316
|
chalk: "^5.4.1",
|
|
42316
42317
|
commander: "^14.0.0",
|
|
42317
42318
|
"form-data": "^4.0.3",
|
|
42319
|
+
"import-in-the-middle": "^1.14.2",
|
|
42318
42320
|
ora: "^8.2.0",
|
|
42319
42321
|
"tiny-invariant": "^1.3.3",
|
|
42320
42322
|
"ts-morph": "^26.0.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/bin/hook.js
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
26
|
+
|
|
27
|
+
// node_modules/module-details-from-path/index.js
|
|
28
|
+
var require_module_details_from_path = __commonJS({
|
|
29
|
+
"node_modules/module-details-from-path/index.js"(exports2, module2) {
|
|
30
|
+
"use strict";
|
|
31
|
+
var sep = require("path").sep;
|
|
32
|
+
module2.exports = function(file) {
|
|
33
|
+
var segments = file.split(sep);
|
|
34
|
+
var index = segments.lastIndexOf("node_modules");
|
|
35
|
+
if (index === -1) return;
|
|
36
|
+
if (!segments[index + 1]) return;
|
|
37
|
+
var scoped = segments[index + 1][0] === "@";
|
|
38
|
+
var name = scoped ? segments[index + 1] + "/" + segments[index + 2] : segments[index + 1];
|
|
39
|
+
var offset = scoped ? 3 : 2;
|
|
40
|
+
var basedir = "";
|
|
41
|
+
var lastBaseDirSegmentIndex = index + offset - 1;
|
|
42
|
+
for (var i = 0; i <= lastBaseDirSegmentIndex; i++) {
|
|
43
|
+
if (i === lastBaseDirSegmentIndex) {
|
|
44
|
+
basedir += segments[i];
|
|
45
|
+
} else {
|
|
46
|
+
basedir += segments[i] + sep;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
var path = "";
|
|
50
|
+
var lastSegmentIndex = segments.length - 1;
|
|
51
|
+
for (var i2 = index + offset; i2 <= lastSegmentIndex; i2++) {
|
|
52
|
+
if (i2 === lastSegmentIndex) {
|
|
53
|
+
path += segments[i2];
|
|
54
|
+
} else {
|
|
55
|
+
path += segments[i2] + sep;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
name,
|
|
60
|
+
basedir,
|
|
61
|
+
path
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// node_modules/import-in-the-middle/lib/register.js
|
|
68
|
+
var require_register = __commonJS({
|
|
69
|
+
"node_modules/import-in-the-middle/lib/register.js"(exports2) {
|
|
70
|
+
var importHooks = [];
|
|
71
|
+
var setters = /* @__PURE__ */ new WeakMap();
|
|
72
|
+
var getters = /* @__PURE__ */ new WeakMap();
|
|
73
|
+
var specifiers = /* @__PURE__ */ new Map();
|
|
74
|
+
var toHook = [];
|
|
75
|
+
var proxyHandler = {
|
|
76
|
+
set(target, name, value) {
|
|
77
|
+
return setters.get(target)[name](value);
|
|
78
|
+
},
|
|
79
|
+
get(target, name) {
|
|
80
|
+
if (name === Symbol.toStringTag) {
|
|
81
|
+
return "Module";
|
|
82
|
+
}
|
|
83
|
+
const getter = getters.get(target)[name];
|
|
84
|
+
if (typeof getter === "function") {
|
|
85
|
+
return getter();
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
defineProperty(target, property, descriptor) {
|
|
89
|
+
if (!("value" in descriptor)) {
|
|
90
|
+
throw new Error("Getters/setters are not supported for exports property descriptors.");
|
|
91
|
+
}
|
|
92
|
+
return setters.get(target)[property](descriptor.value);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
function register2(name, namespace, set, get, specifier) {
|
|
96
|
+
specifiers.set(name, specifier);
|
|
97
|
+
setters.set(namespace, set);
|
|
98
|
+
getters.set(namespace, get);
|
|
99
|
+
const proxy = new Proxy(namespace, proxyHandler);
|
|
100
|
+
importHooks.forEach((hook) => hook(name, proxy));
|
|
101
|
+
toHook.push([name, proxy]);
|
|
102
|
+
}
|
|
103
|
+
var experimentalPatchInternals = false;
|
|
104
|
+
function getExperimentalPatchInternals() {
|
|
105
|
+
return experimentalPatchInternals;
|
|
106
|
+
}
|
|
107
|
+
function setExperimentalPatchInternals(value) {
|
|
108
|
+
experimentalPatchInternals = value;
|
|
109
|
+
}
|
|
110
|
+
exports2.register = register2;
|
|
111
|
+
exports2.importHooks = importHooks;
|
|
112
|
+
exports2.specifiers = specifiers;
|
|
113
|
+
exports2.toHook = toHook;
|
|
114
|
+
exports2.getExperimentalPatchInternals = getExperimentalPatchInternals;
|
|
115
|
+
exports2.setExperimentalPatchInternals = setExperimentalPatchInternals;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// node_modules/import-in-the-middle/index.js
|
|
120
|
+
var require_import_in_the_middle = __commonJS({
|
|
121
|
+
"node_modules/import-in-the-middle/index.js"(exports2, module2) {
|
|
122
|
+
var path = require("path");
|
|
123
|
+
var parse = require_module_details_from_path();
|
|
124
|
+
var { fileURLToPath } = require("url");
|
|
125
|
+
var { MessageChannel } = require("worker_threads");
|
|
126
|
+
var {
|
|
127
|
+
importHooks,
|
|
128
|
+
specifiers,
|
|
129
|
+
toHook,
|
|
130
|
+
getExperimentalPatchInternals
|
|
131
|
+
} = require_register();
|
|
132
|
+
function addHook(hook) {
|
|
133
|
+
importHooks.push(hook);
|
|
134
|
+
toHook.forEach(([name, namespace]) => hook(name, namespace));
|
|
135
|
+
}
|
|
136
|
+
function removeHook(hook) {
|
|
137
|
+
const index = importHooks.indexOf(hook);
|
|
138
|
+
if (index > -1) {
|
|
139
|
+
importHooks.splice(index, 1);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function callHookFn(hookFn, namespace, name, baseDir) {
|
|
143
|
+
const newDefault = hookFn(namespace, name, baseDir);
|
|
144
|
+
if (newDefault && newDefault !== namespace) {
|
|
145
|
+
namespace.default = newDefault;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
var sendModulesToLoader;
|
|
149
|
+
function createAddHookMessageChannel2() {
|
|
150
|
+
const { port1, port2 } = new MessageChannel();
|
|
151
|
+
let pendingAckCount = 0;
|
|
152
|
+
let resolveFn;
|
|
153
|
+
sendModulesToLoader = (modules) => {
|
|
154
|
+
pendingAckCount++;
|
|
155
|
+
port1.postMessage(modules);
|
|
156
|
+
};
|
|
157
|
+
port1.on("message", () => {
|
|
158
|
+
pendingAckCount--;
|
|
159
|
+
if (resolveFn && pendingAckCount <= 0) {
|
|
160
|
+
resolveFn();
|
|
161
|
+
}
|
|
162
|
+
}).unref();
|
|
163
|
+
function waitForAllMessagesAcknowledged() {
|
|
164
|
+
const timer = setInterval(() => {
|
|
165
|
+
}, 1e3);
|
|
166
|
+
const promise = new Promise((resolve) => {
|
|
167
|
+
resolveFn = resolve;
|
|
168
|
+
}).then(() => {
|
|
169
|
+
clearInterval(timer);
|
|
170
|
+
});
|
|
171
|
+
if (pendingAckCount === 0) {
|
|
172
|
+
resolveFn();
|
|
173
|
+
}
|
|
174
|
+
return promise;
|
|
175
|
+
}
|
|
176
|
+
const addHookMessagePort = port2;
|
|
177
|
+
const registerOptions2 = { data: { addHookMessagePort, include: [] }, transferList: [addHookMessagePort] };
|
|
178
|
+
return { registerOptions: registerOptions2, addHookMessagePort, waitForAllMessagesAcknowledged };
|
|
179
|
+
}
|
|
180
|
+
function Hook2(modules, options, hookFn) {
|
|
181
|
+
if (this instanceof Hook2 === false) return new Hook2(modules, options, hookFn);
|
|
182
|
+
if (typeof modules === "function") {
|
|
183
|
+
hookFn = modules;
|
|
184
|
+
modules = null;
|
|
185
|
+
options = null;
|
|
186
|
+
} else if (typeof options === "function") {
|
|
187
|
+
hookFn = options;
|
|
188
|
+
options = null;
|
|
189
|
+
}
|
|
190
|
+
const internals = options ? options.internals === true : false;
|
|
191
|
+
if (sendModulesToLoader && Array.isArray(modules)) {
|
|
192
|
+
sendModulesToLoader(modules);
|
|
193
|
+
}
|
|
194
|
+
this._iitmHook = (name, namespace) => {
|
|
195
|
+
const filename = name;
|
|
196
|
+
const isBuiltin = name.startsWith("node:");
|
|
197
|
+
let baseDir;
|
|
198
|
+
if (isBuiltin) {
|
|
199
|
+
name = name.replace(/^node:/, "");
|
|
200
|
+
} else {
|
|
201
|
+
if (name.startsWith("file://")) {
|
|
202
|
+
try {
|
|
203
|
+
name = fileURLToPath(name);
|
|
204
|
+
} catch (e) {
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const details = parse(name);
|
|
208
|
+
if (details) {
|
|
209
|
+
name = details.name;
|
|
210
|
+
baseDir = details.basedir;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (modules) {
|
|
214
|
+
for (const moduleName of modules) {
|
|
215
|
+
if (moduleName === name) {
|
|
216
|
+
if (baseDir) {
|
|
217
|
+
if (internals) {
|
|
218
|
+
name = name + path.sep + path.relative(baseDir, fileURLToPath(filename));
|
|
219
|
+
} else {
|
|
220
|
+
if (!getExperimentalPatchInternals() && !baseDir.endsWith(specifiers.get(filename))) continue;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
callHookFn(hookFn, namespace, name, baseDir);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
callHookFn(hookFn, namespace, name, baseDir);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
addHook(this._iitmHook);
|
|
231
|
+
}
|
|
232
|
+
Hook2.prototype.unhook = function() {
|
|
233
|
+
removeHook(this._iitmHook);
|
|
234
|
+
};
|
|
235
|
+
module2.exports = Hook2;
|
|
236
|
+
module2.exports.Hook = Hook2;
|
|
237
|
+
module2.exports.addHook = addHook;
|
|
238
|
+
module2.exports.removeHook = removeHook;
|
|
239
|
+
module2.exports.createAddHookMessageChannel = createAddHookMessageChannel2;
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// src/bin/hook.ts
|
|
244
|
+
var import_module = require("module");
|
|
245
|
+
var import_import_in_the_middle = __toESM(require_import_in_the_middle());
|
|
246
|
+
var import_meta = {};
|
|
247
|
+
var { registerOptions } = (0, import_import_in_the_middle.createAddHookMessageChannel)();
|
|
248
|
+
(0, import_module.register)("import-in-the-middle/hook.mjs", import_meta.url, registerOptions);
|
|
249
|
+
var HOP_BY_HOP = /* @__PURE__ */ new Set([
|
|
250
|
+
"connection",
|
|
251
|
+
"proxy-connection",
|
|
252
|
+
"keep-alive",
|
|
253
|
+
"te",
|
|
254
|
+
"trailer",
|
|
255
|
+
"transfer-encoding",
|
|
256
|
+
"upgrade",
|
|
257
|
+
"proxy-authorization",
|
|
258
|
+
"proxy-authenticate",
|
|
259
|
+
"host"
|
|
260
|
+
]);
|
|
261
|
+
function sanitizeReqHeaders(h, hasBody) {
|
|
262
|
+
const out = {};
|
|
263
|
+
for (const [k, v] of Object.entries(h ?? {})) {
|
|
264
|
+
const key = k.toLowerCase();
|
|
265
|
+
if (HOP_BY_HOP.has(key)) continue;
|
|
266
|
+
if (key === "content-length" && !hasBody) continue;
|
|
267
|
+
if (typeof v === "string") out[key] = v;
|
|
268
|
+
}
|
|
269
|
+
delete out["accept-encoding"];
|
|
270
|
+
return out;
|
|
271
|
+
}
|
|
272
|
+
async function loopbackProxy(route) {
|
|
273
|
+
const req = route.request();
|
|
274
|
+
const url = new URL(req.url());
|
|
275
|
+
const isHttps = url.protocol === "https:";
|
|
276
|
+
const port = url.port ? Number(url.port) : isHttps ? 443 : 80;
|
|
277
|
+
const target = `${isHttps ? "https" : "http"}://127.0.0.1:${port}${url.pathname}${url.search}`;
|
|
278
|
+
const method = req.method();
|
|
279
|
+
const isHead = method === "HEAD";
|
|
280
|
+
const isGet = method === "GET";
|
|
281
|
+
const postBuf = req.postDataBuffer();
|
|
282
|
+
const body = !isGet && !isHead && postBuf && postBuf.length ? new Blob([postBuf]) : void 0;
|
|
283
|
+
const headers = sanitizeReqHeaders(await req.headers(), !!body);
|
|
284
|
+
const init = {
|
|
285
|
+
method,
|
|
286
|
+
headers,
|
|
287
|
+
...body ? { body } : {},
|
|
288
|
+
// only include body when valid
|
|
289
|
+
// If you ever switch to a Readable stream body, also add: duplex: 'half'
|
|
290
|
+
signal: AbortSignal.timeout(3e4)
|
|
291
|
+
};
|
|
292
|
+
const upstream = await fetch(target, init);
|
|
293
|
+
const status = upstream.status;
|
|
294
|
+
const respHeadersRaw = Object.fromEntries(upstream.headers);
|
|
295
|
+
const buf = isHead ? Buffer.alloc(0) : Buffer.from(await upstream.arrayBuffer());
|
|
296
|
+
const respHeaders = {};
|
|
297
|
+
for (const [k, v] of Object.entries(respHeadersRaw)) {
|
|
298
|
+
const key = k.toLowerCase();
|
|
299
|
+
if (HOP_BY_HOP.has(key)) continue;
|
|
300
|
+
if (key === "content-length") continue;
|
|
301
|
+
respHeaders[key] = v;
|
|
302
|
+
}
|
|
303
|
+
if (!isHead) respHeaders["content-length"] = String(buf.length);
|
|
304
|
+
await route.fulfill({
|
|
305
|
+
status,
|
|
306
|
+
headers: respHeaders,
|
|
307
|
+
...isHead ? {} : { body: buf }
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
new import_import_in_the_middle.Hook(["@playwright/test"], (exported, name, baseDir) => {
|
|
311
|
+
const base = exported;
|
|
312
|
+
const routedTest = base.test.extend({
|
|
313
|
+
routeSetup: [
|
|
314
|
+
async ({ context }, use) => {
|
|
315
|
+
const regex = /^https?:\/\/(?:127\.0\.0\.1|\[::1\]|(?:[\w-]+\.)*localhost)(?::\d+)?/i;
|
|
316
|
+
await context.route(regex, loopbackProxy);
|
|
317
|
+
await use();
|
|
318
|
+
await context.unroute(regex, loopbackProxy);
|
|
319
|
+
},
|
|
320
|
+
{ auto: true }
|
|
321
|
+
]
|
|
322
|
+
});
|
|
323
|
+
exported.test = routedTest;
|
|
324
|
+
return exported;
|
|
325
|
+
});
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browsermation/test",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.53",
|
|
4
4
|
"description": "The testing platform for Playwright by Browsermation.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -27,10 +27,11 @@
|
|
|
27
27
|
],
|
|
28
28
|
"scripts": {
|
|
29
29
|
"build:cli": "esbuild src/bin/cli.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/bin/cli.js",
|
|
30
|
+
"build:hook": "esbuild src/bin/hook.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/bin/hook.js",
|
|
30
31
|
"build:reporter": "esbuild src/reporter/reporter.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/reporter.js",
|
|
31
32
|
"build:index": "esbuild src/index.ts --bundle --platform=node --external:playwright --target=node22 --outfile=dist/index.js",
|
|
32
33
|
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
33
|
-
"build": "rm -rf dist && npm run build:cli && npm run build:index && npm run build:reporter && npm run build:types",
|
|
34
|
+
"build": "rm -rf dist && npm run build:cli && npm run build:hook && npm run build:index && npm run build:reporter && npm run build:types",
|
|
34
35
|
"start": "node dist/bin/cli.js",
|
|
35
36
|
"build:start": "npm run build && npm start",
|
|
36
37
|
"publishPackage": "npm run build && npm publish --access public"
|
|
@@ -57,6 +58,7 @@
|
|
|
57
58
|
"chalk": "^5.4.1",
|
|
58
59
|
"commander": "^14.0.0",
|
|
59
60
|
"form-data": "^4.0.3",
|
|
61
|
+
"import-in-the-middle": "^1.14.2",
|
|
60
62
|
"ora": "^8.2.0",
|
|
61
63
|
"tiny-invariant": "^1.3.3",
|
|
62
64
|
"ts-morph": "^26.0.0",
|