@lvce-editor/test-with-playwright-worker 22.5.0 → 22.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/workerMain.js +140 -61
- package/package.json +1 -1
package/dist/workerMain.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { join, dirname, basename } from 'node:path';
|
|
2
|
-
import { readFile, writeFile, readdir } from 'node:fs/promises';
|
|
2
|
+
import { readFile, writeFile, readdir, mkdtemp, rm } from 'node:fs/promises';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import net from 'node:net';
|
|
5
|
-
import os from 'node:os';
|
|
5
|
+
import os, { tmpdir } from 'node:os';
|
|
6
6
|
import { fork, spawn } from 'node:child_process';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
8
8
|
import { createRequire } from 'node:module';
|
|
@@ -213,7 +213,6 @@ const walkValue = (value, transferrables, isTransferrable) => {
|
|
|
213
213
|
for (const property of Object.values(value)) {
|
|
214
214
|
walkValue(property, transferrables, isTransferrable);
|
|
215
215
|
}
|
|
216
|
-
return;
|
|
217
216
|
}
|
|
218
217
|
};
|
|
219
218
|
const getTransferrables = value => {
|
|
@@ -367,7 +366,14 @@ class IpcError extends VError {
|
|
|
367
366
|
const cause = new Error(message);
|
|
368
367
|
// @ts-ignore
|
|
369
368
|
cause.code = code;
|
|
370
|
-
|
|
369
|
+
if (stack) {
|
|
370
|
+
Object.defineProperty(cause, 'stack', {
|
|
371
|
+
configurable: true,
|
|
372
|
+
enumerable: false,
|
|
373
|
+
value: stack,
|
|
374
|
+
writable: true
|
|
375
|
+
});
|
|
376
|
+
}
|
|
371
377
|
super(cause, betterMessage);
|
|
372
378
|
} else {
|
|
373
379
|
super(betterMessage);
|
|
@@ -522,8 +528,10 @@ const getCurrentStack = () => {
|
|
|
522
528
|
const currentStack = joinLines(splitLines(new Error().stack || '').slice(stackLinesToSkip));
|
|
523
529
|
return currentStack;
|
|
524
530
|
};
|
|
525
|
-
const getNewLineIndex = (string, startIndex
|
|
526
|
-
|
|
531
|
+
const getNewLineIndex = (string, startIndex) => {
|
|
532
|
+
{
|
|
533
|
+
return string.indexOf(NewLine);
|
|
534
|
+
}
|
|
527
535
|
};
|
|
528
536
|
const getParentStack = error => {
|
|
529
537
|
let parentStack = error.stack || error.data || error.message || '';
|
|
@@ -534,55 +542,77 @@ const getParentStack = error => {
|
|
|
534
542
|
};
|
|
535
543
|
const MethodNotFound = -32601;
|
|
536
544
|
const Custom = -32001;
|
|
545
|
+
const restoreExistingError = (error, currentStack) => {
|
|
546
|
+
if (typeof error.stack === 'string') {
|
|
547
|
+
error.stack = error.stack + NewLine + currentStack;
|
|
548
|
+
}
|
|
549
|
+
return error;
|
|
550
|
+
};
|
|
551
|
+
const restoreMethodNotFoundError = (error, currentStack) => {
|
|
552
|
+
const restoredError = new JsonRpcError(error.message);
|
|
553
|
+
const parentStack = getParentStack(error);
|
|
554
|
+
restoredError.stack = parentStack + NewLine + currentStack;
|
|
555
|
+
return restoredError;
|
|
556
|
+
};
|
|
557
|
+
const restoreStackFromData = (restoredError, error, currentStack) => {
|
|
558
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
559
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
if (error.data.stack) {
|
|
563
|
+
restoredError.stack = error.data.stack;
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
const applyDataProperties = (restoredError, error) => {
|
|
567
|
+
if (!error.data) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
restoreStackFromData(restoredError, error, getCurrentStack());
|
|
571
|
+
if (error.data.codeFrame) {
|
|
572
|
+
// @ts-ignore
|
|
573
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
574
|
+
}
|
|
575
|
+
if (error.data.code) {
|
|
576
|
+
// @ts-ignore
|
|
577
|
+
restoredError.code = error.data.code;
|
|
578
|
+
}
|
|
579
|
+
if (error.data.type) {
|
|
580
|
+
// @ts-ignore
|
|
581
|
+
restoredError.name = error.data.type;
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
const applyDirectProperties = (restoredError, error) => {
|
|
585
|
+
if (error.stack) {
|
|
586
|
+
const lowerStack = restoredError.stack || '';
|
|
587
|
+
const indexNewLine = getNewLineIndex(lowerStack);
|
|
588
|
+
const parentStack = getParentStack(error);
|
|
589
|
+
// @ts-ignore
|
|
590
|
+
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
591
|
+
}
|
|
592
|
+
if (error.codeFrame) {
|
|
593
|
+
// @ts-ignore
|
|
594
|
+
restoredError.codeFrame = error.codeFrame;
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
const restoreMessageError = (error, _currentStack) => {
|
|
598
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
599
|
+
if (error.data) {
|
|
600
|
+
applyDataProperties(restoredError, error);
|
|
601
|
+
} else {
|
|
602
|
+
applyDirectProperties(restoredError, error);
|
|
603
|
+
}
|
|
604
|
+
return restoredError;
|
|
605
|
+
};
|
|
537
606
|
const restoreJsonRpcError = error => {
|
|
538
607
|
const currentStack = getCurrentStack();
|
|
539
608
|
if (error && error instanceof Error) {
|
|
540
|
-
|
|
541
|
-
error.stack = error.stack + NewLine + currentStack;
|
|
542
|
-
}
|
|
543
|
-
return error;
|
|
609
|
+
return restoreExistingError(error, currentStack);
|
|
544
610
|
}
|
|
545
611
|
if (error && error.code && error.code === MethodNotFound) {
|
|
546
|
-
|
|
547
|
-
const parentStack = getParentStack(error);
|
|
548
|
-
restoredError.stack = parentStack + NewLine + currentStack;
|
|
549
|
-
return restoredError;
|
|
612
|
+
return restoreMethodNotFoundError(error, currentStack);
|
|
550
613
|
}
|
|
551
614
|
if (error && error.message) {
|
|
552
|
-
|
|
553
|
-
if (error.data) {
|
|
554
|
-
if (error.data.stack && error.data.type && error.message) {
|
|
555
|
-
restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
|
|
556
|
-
} else if (error.data.stack) {
|
|
557
|
-
restoredError.stack = error.data.stack;
|
|
558
|
-
}
|
|
559
|
-
if (error.data.codeFrame) {
|
|
560
|
-
// @ts-ignore
|
|
561
|
-
restoredError.codeFrame = error.data.codeFrame;
|
|
562
|
-
}
|
|
563
|
-
if (error.data.code) {
|
|
564
|
-
// @ts-ignore
|
|
565
|
-
restoredError.code = error.data.code;
|
|
566
|
-
}
|
|
567
|
-
if (error.data.type) {
|
|
568
|
-
// @ts-ignore
|
|
569
|
-
restoredError.name = error.data.type;
|
|
570
|
-
}
|
|
571
|
-
} else {
|
|
572
|
-
if (error.stack) {
|
|
573
|
-
const lowerStack = restoredError.stack || '';
|
|
574
|
-
// @ts-ignore
|
|
575
|
-
const indexNewLine = getNewLineIndex(lowerStack);
|
|
576
|
-
const parentStack = getParentStack(error);
|
|
577
|
-
// @ts-ignore
|
|
578
|
-
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
579
|
-
}
|
|
580
|
-
if (error.codeFrame) {
|
|
581
|
-
// @ts-ignore
|
|
582
|
-
restoredError.codeFrame = error.codeFrame;
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
return restoredError;
|
|
615
|
+
return restoreMessageError(error);
|
|
586
616
|
}
|
|
587
617
|
if (typeof error === 'string') {
|
|
588
618
|
return new Error(`JsonRpc Error: ${error}`);
|
|
@@ -1725,8 +1755,17 @@ const getElectronLaunchOptions = ({
|
|
|
1725
1755
|
};
|
|
1726
1756
|
};
|
|
1727
1757
|
|
|
1758
|
+
const getElectronProcessArgs = ({
|
|
1759
|
+
args,
|
|
1760
|
+
platform = process.platform,
|
|
1761
|
+
userDataDir
|
|
1762
|
+
}) => {
|
|
1763
|
+
return ['--remote-debugging-port=0', ...(platform === 'linux' ? ['--no-sandbox'] : []), ...args, `--user-data-dir=${userDataDir}`];
|
|
1764
|
+
};
|
|
1765
|
+
|
|
1728
1766
|
const SIGINT = 'SIGINT';
|
|
1729
1767
|
|
|
1768
|
+
const electronConnectionTimeout = 120_000;
|
|
1730
1769
|
const devtoolsRegex = /^DevTools listening on (ws:\/\/.*)$/;
|
|
1731
1770
|
const waitForDevtoolsEndpoint = async child => {
|
|
1732
1771
|
const {
|
|
@@ -1743,10 +1782,13 @@ const waitForDevtoolsEndpoint = async child => {
|
|
|
1743
1782
|
reject,
|
|
1744
1783
|
resolve
|
|
1745
1784
|
} = Promise.withResolvers();
|
|
1785
|
+
const stderrLines = [];
|
|
1746
1786
|
const onExit = () => {
|
|
1747
|
-
|
|
1787
|
+
const details = stderrLines.length > 0 ? `: ${stderrLines.join('\n')}` : '';
|
|
1788
|
+
reject(new Error(`Electron exited before DevTools endpoint was available${details}`));
|
|
1748
1789
|
};
|
|
1749
1790
|
const onLine = line => {
|
|
1791
|
+
stderrLines.push(line);
|
|
1750
1792
|
const match = line.match(devtoolsRegex);
|
|
1751
1793
|
if (match) {
|
|
1752
1794
|
resolve(match[1]);
|
|
@@ -1772,24 +1814,50 @@ const getFirstPage = async browser => {
|
|
|
1772
1814
|
timeout: 15_000
|
|
1773
1815
|
});
|
|
1774
1816
|
};
|
|
1817
|
+
const waitForChildExit = async child => {
|
|
1818
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
1819
|
+
return;
|
|
1820
|
+
}
|
|
1821
|
+
await new Promise(resolve => {
|
|
1822
|
+
const timeout = setTimeout(resolve, 5000);
|
|
1823
|
+
child.once('exit', () => {
|
|
1824
|
+
clearTimeout(timeout);
|
|
1825
|
+
resolve();
|
|
1826
|
+
});
|
|
1827
|
+
});
|
|
1828
|
+
};
|
|
1829
|
+
const stopElectronProcess = async child => {
|
|
1830
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
1831
|
+
child.kill(SIGINT);
|
|
1832
|
+
await waitForChildExit(child);
|
|
1833
|
+
}
|
|
1834
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
1835
|
+
child.kill('SIGKILL');
|
|
1836
|
+
await waitForChildExit(child);
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1775
1839
|
const closeElectron = async ({
|
|
1776
1840
|
browser,
|
|
1777
|
-
child
|
|
1841
|
+
child,
|
|
1842
|
+
userDataDir
|
|
1778
1843
|
}) => {
|
|
1779
1844
|
try {
|
|
1780
1845
|
await browser.close();
|
|
1781
1846
|
} catch {
|
|
1782
1847
|
// ignore close errors during cleanup
|
|
1783
1848
|
}
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1849
|
+
await stopElectronProcess(child);
|
|
1850
|
+
await rm(userDataDir, {
|
|
1851
|
+
force: true,
|
|
1852
|
+
recursive: true
|
|
1853
|
+
});
|
|
1787
1854
|
};
|
|
1788
1855
|
const createElectronLaunch = ({
|
|
1789
1856
|
browser,
|
|
1790
1857
|
child,
|
|
1791
1858
|
page,
|
|
1792
|
-
signal
|
|
1859
|
+
signal,
|
|
1860
|
+
userDataDir
|
|
1793
1861
|
}) => {
|
|
1794
1862
|
let disposed = false;
|
|
1795
1863
|
const dispose = async () => {
|
|
@@ -1802,7 +1870,8 @@ const createElectronLaunch = ({
|
|
|
1802
1870
|
process.off('SIGTERM', handleSigterm);
|
|
1803
1871
|
await closeElectron({
|
|
1804
1872
|
browser,
|
|
1805
|
-
child
|
|
1873
|
+
child,
|
|
1874
|
+
userDataDir
|
|
1806
1875
|
});
|
|
1807
1876
|
};
|
|
1808
1877
|
const handleAbort = () => {
|
|
@@ -1844,7 +1913,12 @@ const startElectron = async ({
|
|
|
1844
1913
|
signal
|
|
1845
1914
|
}) => {
|
|
1846
1915
|
const launchOptions = getElectronLaunchOptions(runtimeOptions);
|
|
1847
|
-
const
|
|
1916
|
+
const userDataDir = await mkdtemp(join(tmpdir(), 'test-with-playwright-electron-'));
|
|
1917
|
+
const args = getElectronProcessArgs({
|
|
1918
|
+
args: launchOptions.args,
|
|
1919
|
+
userDataDir
|
|
1920
|
+
});
|
|
1921
|
+
const child = spawn(launchOptions.executablePath, args, {
|
|
1848
1922
|
env: launchOptions.env,
|
|
1849
1923
|
stdio: ['ignore', 'ignore', 'pipe']
|
|
1850
1924
|
});
|
|
@@ -1854,13 +1928,16 @@ const startElectron = async ({
|
|
|
1854
1928
|
const {
|
|
1855
1929
|
chromium
|
|
1856
1930
|
} = await import('@playwright/test');
|
|
1857
|
-
browser = await chromium.connectOverCDP(endpoint
|
|
1931
|
+
browser = await chromium.connectOverCDP(endpoint, {
|
|
1932
|
+
timeout: electronConnectionTimeout
|
|
1933
|
+
});
|
|
1858
1934
|
const page = await getFirstPage(browser);
|
|
1859
1935
|
return createElectronLaunch({
|
|
1860
1936
|
browser,
|
|
1861
1937
|
child,
|
|
1862
1938
|
page,
|
|
1863
|
-
signal
|
|
1939
|
+
signal,
|
|
1940
|
+
userDataDir
|
|
1864
1941
|
});
|
|
1865
1942
|
} catch (error) {
|
|
1866
1943
|
if (browser) {
|
|
@@ -1870,9 +1947,11 @@ const startElectron = async ({
|
|
|
1870
1947
|
// ignore close errors during cleanup
|
|
1871
1948
|
}
|
|
1872
1949
|
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1950
|
+
await stopElectronProcess(child);
|
|
1951
|
+
await rm(userDataDir, {
|
|
1952
|
+
force: true,
|
|
1953
|
+
recursive: true
|
|
1954
|
+
});
|
|
1876
1955
|
throw error;
|
|
1877
1956
|
}
|
|
1878
1957
|
};
|