@lvce-editor/test-with-playwright-worker 22.36.2 → 22.36.4
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/workerMain.js +173 -7
- package/package.json +1 -1
package/dist/workerMain.js
CHANGED
|
@@ -1198,6 +1198,162 @@ const get = id => {
|
|
|
1198
1198
|
return rpcs[id];
|
|
1199
1199
|
};
|
|
1200
1200
|
|
|
1201
|
+
// This function is serialized by Playwright and must not close over module bindings.
|
|
1202
|
+
const install = () => {
|
|
1203
|
+
const limit = 5000;
|
|
1204
|
+
const payloadLimit = 8192;
|
|
1205
|
+
const entries = [];
|
|
1206
|
+
let sequence = 0;
|
|
1207
|
+
const channels = new WeakMap();
|
|
1208
|
+
let nextChannel = 0;
|
|
1209
|
+
const originalAdd = Object.getOwnPropertyDescriptor(EventTarget.prototype, 'addEventListener').value;
|
|
1210
|
+
const record = (kind, data) => {
|
|
1211
|
+
const entry = {
|
|
1212
|
+
...data,
|
|
1213
|
+
kind,
|
|
1214
|
+
sequence: sequence++,
|
|
1215
|
+
timestamp: performance.now()
|
|
1216
|
+
};
|
|
1217
|
+
entries[entry.sequence % limit] = entry;
|
|
1218
|
+
};
|
|
1219
|
+
const describe = target => {
|
|
1220
|
+
if (!(target instanceof Element)) {
|
|
1221
|
+
if (!(target instanceof Node)) return 'unknown';
|
|
1222
|
+
return `${target.nodeName}:${target.nodeValue || ''}`.slice(0, 200);
|
|
1223
|
+
}
|
|
1224
|
+
return `${target.tagName}#${target.id}.${target.getAttribute('class') || ''}`.slice(0, 200);
|
|
1225
|
+
};
|
|
1226
|
+
const serialize = value => {
|
|
1227
|
+
let truncated = false;
|
|
1228
|
+
const seen = new WeakSet();
|
|
1229
|
+
try {
|
|
1230
|
+
const text = JSON.stringify(value, (_key, item) => {
|
|
1231
|
+
if (typeof item === 'bigint') return `${item}n`;
|
|
1232
|
+
if (typeof item === 'string') {
|
|
1233
|
+
truncated ||= item.length > 2048;
|
|
1234
|
+
return item.slice(0, 2048);
|
|
1235
|
+
}
|
|
1236
|
+
if (typeof item !== 'object' || item === null) return item;
|
|
1237
|
+
if (seen.has(item)) return '[Circular]';
|
|
1238
|
+
seen.add(item);
|
|
1239
|
+
if (item instanceof MessagePort) return '[MessagePort]';
|
|
1240
|
+
if (item instanceof ArrayBuffer) return `[ArrayBuffer ${item.byteLength}]`;
|
|
1241
|
+
if (ArrayBuffer.isView(item)) return `[${item.constructor.name} ${item.byteLength}]`;
|
|
1242
|
+
return item;
|
|
1243
|
+
}) || '';
|
|
1244
|
+
return {
|
|
1245
|
+
payload: text.slice(0, payloadLimit),
|
|
1246
|
+
truncated: truncated || text.length > payloadLimit
|
|
1247
|
+
};
|
|
1248
|
+
} catch {
|
|
1249
|
+
return {
|
|
1250
|
+
payload: '[Unserializable]',
|
|
1251
|
+
truncated: true
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
const observe = target => {
|
|
1256
|
+
const existing = channels.get(target);
|
|
1257
|
+
if (existing !== undefined) return existing;
|
|
1258
|
+
const channel = nextChannel++;
|
|
1259
|
+
channels.set(target, channel);
|
|
1260
|
+
Reflect.apply(originalAdd, target, ['message', event => {
|
|
1261
|
+
record('rpc-received', {
|
|
1262
|
+
channel,
|
|
1263
|
+
...serialize(event.data)
|
|
1264
|
+
});
|
|
1265
|
+
}]);
|
|
1266
|
+
return channel;
|
|
1267
|
+
};
|
|
1268
|
+
class EventHooks {
|
|
1269
|
+
addEventListener(...args) {
|
|
1270
|
+
if (args[0] === 'message' && (this instanceof MessagePort || this instanceof Worker)) observe(this);
|
|
1271
|
+
return Reflect.apply(originalAdd, this, args);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
Object.defineProperty(EventTarget.prototype, 'addEventListener', {
|
|
1275
|
+
...Object.getOwnPropertyDescriptor(EventTarget.prototype, 'addEventListener'),
|
|
1276
|
+
value: Object.getOwnPropertyDescriptor(EventHooks.prototype, 'addEventListener').value
|
|
1277
|
+
});
|
|
1278
|
+
for (const prototype of [MessagePort.prototype, Worker.prototype]) {
|
|
1279
|
+
const postDescriptor = Object.getOwnPropertyDescriptor(prototype, 'postMessage');
|
|
1280
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'onmessage');
|
|
1281
|
+
const originalSet = Object.getOwnPropertyDescriptor(descriptor, 'set').value;
|
|
1282
|
+
class PortHooks {
|
|
1283
|
+
postMessage(...args) {
|
|
1284
|
+
const channel = observe(this);
|
|
1285
|
+
const data = serialize(args[0]);
|
|
1286
|
+
const result = Reflect.apply(postDescriptor.value, this, args);
|
|
1287
|
+
record('rpc-sent', {
|
|
1288
|
+
channel,
|
|
1289
|
+
...data
|
|
1290
|
+
});
|
|
1291
|
+
return result;
|
|
1292
|
+
}
|
|
1293
|
+
set onmessage(listener) {
|
|
1294
|
+
observe(this);
|
|
1295
|
+
Reflect.apply(originalSet, this, [listener]);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
const hookDescriptor = Object.getOwnPropertyDescriptor(PortHooks.prototype, 'onmessage');
|
|
1299
|
+
Object.defineProperties(prototype, {
|
|
1300
|
+
onmessage: {
|
|
1301
|
+
...descriptor,
|
|
1302
|
+
set: Object.getOwnPropertyDescriptor(hookDescriptor, 'set').value
|
|
1303
|
+
},
|
|
1304
|
+
postMessage: {
|
|
1305
|
+
...postDescriptor,
|
|
1306
|
+
value: Object.getOwnPropertyDescriptor(PortHooks.prototype, 'postMessage').value
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
for (const type of ['click', 'input', 'keydown', 'keyup', 'pointerdown', 'pointerup', 'pointerover', 'pointerout', 'focusin', 'focusout']) {
|
|
1311
|
+
document.addEventListener(type, event => {
|
|
1312
|
+
record('input', {
|
|
1313
|
+
event: type,
|
|
1314
|
+
key: event.key,
|
|
1315
|
+
target: describe(event.target),
|
|
1316
|
+
trusted: event.isTrusted
|
|
1317
|
+
});
|
|
1318
|
+
}, {
|
|
1319
|
+
capture: true,
|
|
1320
|
+
passive: true
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
const observer = new MutationObserver(mutations => {
|
|
1324
|
+
record('dom-mutation', {
|
|
1325
|
+
changes: mutations.slice(0, 10).map(mutation => ({
|
|
1326
|
+
added: [...mutation.addedNodes].slice(0, 2).map(describe),
|
|
1327
|
+
addedCount: mutation.addedNodes.length,
|
|
1328
|
+
attribute: mutation.attributeName,
|
|
1329
|
+
removed: [...mutation.removedNodes].slice(0, 2).map(describe),
|
|
1330
|
+
removedCount: mutation.removedNodes.length,
|
|
1331
|
+
target: describe(mutation.target),
|
|
1332
|
+
type: mutation.type,
|
|
1333
|
+
value: mutation.attributeName && mutation.target instanceof Element ? mutation.target.getAttribute(mutation.attributeName)?.slice(0, 200) : undefined
|
|
1334
|
+
})),
|
|
1335
|
+
count: mutations.length
|
|
1336
|
+
});
|
|
1337
|
+
});
|
|
1338
|
+
observer.observe(document, {
|
|
1339
|
+
attributes: true,
|
|
1340
|
+
characterData: true,
|
|
1341
|
+
childList: true,
|
|
1342
|
+
subtree: true
|
|
1343
|
+
});
|
|
1344
|
+
Object.defineProperty(globalThis, '__lvceTraceTimeline', {
|
|
1345
|
+
value: () => {
|
|
1346
|
+
const offset = sequence > limit ? sequence % limit : 0;
|
|
1347
|
+
return {
|
|
1348
|
+
dropped: Math.max(0, sequence - limit),
|
|
1349
|
+
entries: [...entries.slice(offset), ...entries.slice(0, offset)],
|
|
1350
|
+
limit,
|
|
1351
|
+
version: 1
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
});
|
|
1355
|
+
};
|
|
1356
|
+
|
|
1201
1357
|
const HandleResult = 'HandleResult';
|
|
1202
1358
|
const HandleFinalResult = 'HandleFinalResult';
|
|
1203
1359
|
|
|
@@ -1268,19 +1424,26 @@ const exportTrace = async ({
|
|
|
1268
1424
|
page,
|
|
1269
1425
|
test
|
|
1270
1426
|
}) => {
|
|
1271
|
-
let
|
|
1427
|
+
let capture;
|
|
1272
1428
|
try {
|
|
1273
|
-
|
|
1274
|
-
return
|
|
1429
|
+
capture = await page.evaluate(traceSelector => {
|
|
1430
|
+
return {
|
|
1431
|
+
text: globalThis.document.querySelector(traceSelector)?.textContent || undefined,
|
|
1432
|
+
timeline: globalThis.__lvceTraceTimeline?.()
|
|
1433
|
+
};
|
|
1275
1434
|
}, selector);
|
|
1276
1435
|
} catch {
|
|
1277
1436
|
return false;
|
|
1278
1437
|
}
|
|
1279
|
-
if (!text) {
|
|
1438
|
+
if (!capture.text && !capture.timeline) {
|
|
1280
1439
|
return false;
|
|
1281
1440
|
}
|
|
1282
|
-
JSON.parse(text)
|
|
1283
|
-
|
|
1441
|
+
const trace = capture.text ? JSON.parse(capture.text) : {
|
|
1442
|
+
entries: [],
|
|
1443
|
+
version: 1
|
|
1444
|
+
};
|
|
1445
|
+
if (capture.timeline) trace.timeline = capture.timeline;
|
|
1446
|
+
await writeFile(join(directory, getFileName(test)), `${JSON.stringify(trace)}\n`);
|
|
1284
1447
|
return true;
|
|
1285
1448
|
};
|
|
1286
1449
|
|
|
@@ -1869,7 +2032,7 @@ const runTestsWithReusedPage = async ({
|
|
|
1869
2032
|
const url = getAllTestsUrl(port, filter, traceFocus ?? false, rendererWorkerTraceDirectory !== undefined);
|
|
1870
2033
|
await page.goto(url, {
|
|
1871
2034
|
timeout,
|
|
1872
|
-
waitUntil: '
|
|
2035
|
+
waitUntil: 'domcontentloaded'
|
|
1873
2036
|
});
|
|
1874
2037
|
const text = await readTestResultsText(page, timeout);
|
|
1875
2038
|
results = parseTestResults(text);
|
|
@@ -2472,6 +2635,9 @@ const runAllTests = async (extensionPath, testPath, cwd, browser, headless, time
|
|
|
2472
2635
|
testPath
|
|
2473
2636
|
});
|
|
2474
2637
|
try {
|
|
2638
|
+
if (traceRendererWorker) {
|
|
2639
|
+
await page.addInitScript(install);
|
|
2640
|
+
}
|
|
2475
2641
|
if (reusePage) {
|
|
2476
2642
|
await runWithJavascriptCoverage({
|
|
2477
2643
|
coverage,
|