@jsenv/core 27.8.1 → 28.0.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/main.js +415 -355
- package/package.json +2 -2
- package/src/build/start_build_server.js +2 -2
- package/src/dev/start_dev_server.js +2 -2
- package/src/execute/execute.js +14 -52
- package/src/execute/runtimes/browsers/from_playwright.js +19 -8
- package/src/main.js +3 -0
- package/src/omega/omega_server.js +2 -2
- package/src/ping_server.js +30 -0
- package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +1 -9
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +13 -0
- package/src/test/execute_plan.js +15 -68
- package/src/test/execute_test_plan.js +4 -26
package/dist/main.js
CHANGED
|
@@ -12,10 +12,10 @@ import { createMagicSource, composeTwoSourcemaps, getOriginalPosition, sourcemap
|
|
|
12
12
|
import { parseHtmlString, stringifyHtmlAst, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, getHtmlNodeText, setHtmlNodeText, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, removeHtmlNodeText, transpileWithParcel, injectJsImport, minifyWithParcel, analyzeLinkNode } from "@jsenv/ast";
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import babelParser from "@babel/parser";
|
|
15
|
+
import net, { createServer, isIP } from "node:net";
|
|
15
16
|
import http from "node:http";
|
|
16
17
|
import cluster from "node:cluster";
|
|
17
18
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
18
|
-
import net, { createServer } from "node:net";
|
|
19
19
|
import { Readable, Stream, Writable } from "node:stream";
|
|
20
20
|
import { Http2ServerResponse } from "node:http2";
|
|
21
21
|
import { lookup } from "node:dns";
|
|
@@ -13742,7 +13742,6 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
13742
13742
|
});
|
|
13743
13743
|
const {
|
|
13744
13744
|
dev = [],
|
|
13745
|
-
test = [],
|
|
13746
13745
|
build = []
|
|
13747
13746
|
} = metadata.importMetaScenarios;
|
|
13748
13747
|
const replacements = [];
|
|
@@ -13759,9 +13758,6 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
13759
13758
|
dev.forEach(path => {
|
|
13760
13759
|
replace(path, "undefined");
|
|
13761
13760
|
});
|
|
13762
|
-
test.forEach(path => {
|
|
13763
|
-
replace(path, context.scenarios.test ? "true" : "undefined");
|
|
13764
|
-
});
|
|
13765
13761
|
build.forEach(path => {
|
|
13766
13762
|
replace(path, "true");
|
|
13767
13763
|
});
|
|
@@ -13773,12 +13769,6 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
13773
13769
|
dev.forEach(path => {
|
|
13774
13770
|
replace(path, "true");
|
|
13775
13771
|
});
|
|
13776
|
-
|
|
13777
|
-
if (context.scenarios.test) {
|
|
13778
|
-
test.forEach(path => {
|
|
13779
|
-
replace(path, "true");
|
|
13780
|
-
});
|
|
13781
|
-
}
|
|
13782
13772
|
}
|
|
13783
13773
|
|
|
13784
13774
|
const magicSource = createMagicSource(urlInfo.content);
|
|
@@ -14062,6 +14052,87 @@ export default inlineContent.text`,
|
|
|
14062
14052
|
return [asJsonModule, asCssModule, asTextModule];
|
|
14063
14053
|
};
|
|
14064
14054
|
|
|
14055
|
+
const babelPluginInstrument = (api, {
|
|
14056
|
+
rootDirectoryUrl,
|
|
14057
|
+
useInlineSourceMaps = false,
|
|
14058
|
+
coverageConfig = {
|
|
14059
|
+
"./**/*": true
|
|
14060
|
+
}
|
|
14061
|
+
}) => {
|
|
14062
|
+
const {
|
|
14063
|
+
programVisitor
|
|
14064
|
+
} = requireFromJsenv("istanbul-lib-instrument");
|
|
14065
|
+
const {
|
|
14066
|
+
types
|
|
14067
|
+
} = api;
|
|
14068
|
+
const associations = URL_META.resolveAssociations({
|
|
14069
|
+
cover: coverageConfig
|
|
14070
|
+
}, rootDirectoryUrl);
|
|
14071
|
+
|
|
14072
|
+
const shouldInstrument = url => {
|
|
14073
|
+
return URL_META.applyAssociations({
|
|
14074
|
+
url,
|
|
14075
|
+
associations
|
|
14076
|
+
}).cover;
|
|
14077
|
+
};
|
|
14078
|
+
|
|
14079
|
+
return {
|
|
14080
|
+
name: "transform-instrument",
|
|
14081
|
+
visitor: {
|
|
14082
|
+
Program: {
|
|
14083
|
+
enter(path) {
|
|
14084
|
+
const {
|
|
14085
|
+
file
|
|
14086
|
+
} = this;
|
|
14087
|
+
const {
|
|
14088
|
+
opts
|
|
14089
|
+
} = file;
|
|
14090
|
+
|
|
14091
|
+
if (!opts.sourceFileName) {
|
|
14092
|
+
console.warn(`cannot instrument file when "sourceFileName" option is not set`);
|
|
14093
|
+
return;
|
|
14094
|
+
}
|
|
14095
|
+
|
|
14096
|
+
const fileUrl = fileSystemPathToUrl$1(opts.sourceFileName);
|
|
14097
|
+
|
|
14098
|
+
if (!shouldInstrument(fileUrl)) {
|
|
14099
|
+
return;
|
|
14100
|
+
}
|
|
14101
|
+
|
|
14102
|
+
this.__dv__ = null;
|
|
14103
|
+
let inputSourceMap;
|
|
14104
|
+
|
|
14105
|
+
if (useInlineSourceMaps) {
|
|
14106
|
+
// https://github.com/istanbuljs/babel-plugin-istanbul/commit/a9e15643d249a2985e4387e4308022053b2cd0ad#diff-1fdf421c05c1140f6d71444ea2b27638R65
|
|
14107
|
+
inputSourceMap = opts.inputSourceMap || file.inputMap ? file.inputMap.sourcemap : null;
|
|
14108
|
+
} else {
|
|
14109
|
+
inputSourceMap = opts.inputSourceMap;
|
|
14110
|
+
}
|
|
14111
|
+
|
|
14112
|
+
this.__dv__ = programVisitor(types, opts.filenameRelative || opts.filename, {
|
|
14113
|
+
coverageVariable: "__coverage__",
|
|
14114
|
+
inputSourceMap
|
|
14115
|
+
});
|
|
14116
|
+
|
|
14117
|
+
this.__dv__.enter(path);
|
|
14118
|
+
},
|
|
14119
|
+
|
|
14120
|
+
exit(path) {
|
|
14121
|
+
if (!this.__dv__) {
|
|
14122
|
+
return;
|
|
14123
|
+
}
|
|
14124
|
+
|
|
14125
|
+
const object = this.__dv__.exit(path); // object got two properties: fileCoverage and sourceMappingURL
|
|
14126
|
+
|
|
14127
|
+
|
|
14128
|
+
this.file.metadata.coverage = object.fileCoverage;
|
|
14129
|
+
}
|
|
14130
|
+
|
|
14131
|
+
}
|
|
14132
|
+
}
|
|
14133
|
+
};
|
|
14134
|
+
};
|
|
14135
|
+
|
|
14065
14136
|
const versionFromValue = value => {
|
|
14066
14137
|
if (typeof value === "number") {
|
|
14067
14138
|
return numberToVersion(value);
|
|
@@ -15243,6 +15314,17 @@ const jsenvPluginBabel = ({
|
|
|
15243
15314
|
getImportSpecifier
|
|
15244
15315
|
});
|
|
15245
15316
|
|
|
15317
|
+
if (context.scenarios.dev) {
|
|
15318
|
+
const requestHeaders = context.request.headers;
|
|
15319
|
+
|
|
15320
|
+
if (requestHeaders["x-coverage-instanbul"]) {
|
|
15321
|
+
babelPluginStructure["transform-instrument"] = [babelPluginInstrument, {
|
|
15322
|
+
rootDirectoryUrl: context.rootDirectoryUrl,
|
|
15323
|
+
coverageConfig: JSON.parse(requestHeaders["x-coverage-instanbul"])
|
|
15324
|
+
}];
|
|
15325
|
+
}
|
|
15326
|
+
}
|
|
15327
|
+
|
|
15246
15328
|
if (getCustomBabelPlugins) {
|
|
15247
15329
|
Object.assign(babelPluginStructure, getCustomBabelPlugins(context));
|
|
15248
15330
|
}
|
|
@@ -18367,101 +18449,12 @@ const statusIsClientError = status => status >= 400 && status < 500;
|
|
|
18367
18449
|
|
|
18368
18450
|
const statusIsServerError = status => status >= 500 && status < 600;
|
|
18369
18451
|
|
|
18370
|
-
const applyDnsResolution = async (hostname, {
|
|
18371
|
-
verbatim = false
|
|
18372
|
-
} = {}) => {
|
|
18373
|
-
const dnsResolution = await new Promise((resolve, reject) => {
|
|
18374
|
-
lookup(hostname, {
|
|
18375
|
-
verbatim
|
|
18376
|
-
}, (error, address, family) => {
|
|
18377
|
-
if (error) {
|
|
18378
|
-
reject(error);
|
|
18379
|
-
} else {
|
|
18380
|
-
resolve({
|
|
18381
|
-
address,
|
|
18382
|
-
family
|
|
18383
|
-
});
|
|
18384
|
-
}
|
|
18385
|
-
});
|
|
18386
|
-
});
|
|
18387
|
-
return dnsResolution;
|
|
18388
|
-
};
|
|
18389
|
-
|
|
18390
|
-
const getServerOrigins = async ({
|
|
18391
|
-
protocol,
|
|
18392
|
-
host,
|
|
18393
|
-
port
|
|
18394
|
-
}) => {
|
|
18395
|
-
const isLocal = LOOPBACK_HOSTNAMES.includes(host);
|
|
18396
|
-
const localhostDnsResolution = await applyDnsResolution("localhost");
|
|
18397
|
-
const localOrigin = createServerOrigin({
|
|
18398
|
-
protocol,
|
|
18399
|
-
hostname: localhostDnsResolution.address === "127.0.0.1" ? "localhost" : "127.0.0.1",
|
|
18400
|
-
port
|
|
18401
|
-
});
|
|
18402
|
-
|
|
18403
|
-
if (isLocal) {
|
|
18404
|
-
return {
|
|
18405
|
-
local: localOrigin
|
|
18406
|
-
};
|
|
18407
|
-
}
|
|
18408
|
-
|
|
18409
|
-
const isAnyIp = WILDCARD_HOSTNAMES.includes(host);
|
|
18410
|
-
const networkOrigin = createServerOrigin({
|
|
18411
|
-
protocol,
|
|
18412
|
-
hostname: isAnyIp ? getExternalIp() : host,
|
|
18413
|
-
port
|
|
18414
|
-
});
|
|
18415
|
-
return {
|
|
18416
|
-
local: localOrigin,
|
|
18417
|
-
network: networkOrigin
|
|
18418
|
-
};
|
|
18419
|
-
};
|
|
18420
|
-
const LOOPBACK_HOSTNAMES = ["localhost", "127.0.0.1", "::1", "0000:0000:0000:0000:0000:0000:0000:0001"];
|
|
18421
|
-
const WILDCARD_HOSTNAMES = [undefined, "0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"];
|
|
18422
|
-
|
|
18423
|
-
const createServerOrigin = ({
|
|
18424
|
-
protocol,
|
|
18425
|
-
hostname,
|
|
18426
|
-
port
|
|
18427
|
-
}) => {
|
|
18428
|
-
const url = new URL("https://127.0.0.1:80");
|
|
18429
|
-
url.protocol = protocol;
|
|
18430
|
-
url.hostname = hostname;
|
|
18431
|
-
url.port = port;
|
|
18432
|
-
return url.origin;
|
|
18433
|
-
};
|
|
18434
|
-
|
|
18435
|
-
const getExternalIp = () => {
|
|
18436
|
-
const networkInterfaceMap = networkInterfaces();
|
|
18437
|
-
let internalIPV4NetworkAddress;
|
|
18438
|
-
Object.keys(networkInterfaceMap).find(key => {
|
|
18439
|
-
const networkAddressArray = networkInterfaceMap[key];
|
|
18440
|
-
return networkAddressArray.find(networkAddress => {
|
|
18441
|
-
if (networkAddress.internal) return false;
|
|
18442
|
-
if (!isIpV4(networkAddress)) return false;
|
|
18443
|
-
internalIPV4NetworkAddress = networkAddress;
|
|
18444
|
-
return true;
|
|
18445
|
-
});
|
|
18446
|
-
});
|
|
18447
|
-
return internalIPV4NetworkAddress ? internalIPV4NetworkAddress.address : null;
|
|
18448
|
-
};
|
|
18449
|
-
|
|
18450
|
-
const isIpV4 = networkAddress => {
|
|
18451
|
-
// node 18+
|
|
18452
|
-
if (typeof networkAddress.family === "number") {
|
|
18453
|
-
return networkAddress.family === 4;
|
|
18454
|
-
}
|
|
18455
|
-
|
|
18456
|
-
return networkAddress.family === "IPv4";
|
|
18457
|
-
};
|
|
18458
|
-
|
|
18459
18452
|
const listen = async ({
|
|
18460
18453
|
signal = new AbortController().signal,
|
|
18461
18454
|
server,
|
|
18462
18455
|
port,
|
|
18463
18456
|
portHint,
|
|
18464
|
-
|
|
18457
|
+
hostname
|
|
18465
18458
|
}) => {
|
|
18466
18459
|
const listeningOperation = Abort.startOperation();
|
|
18467
18460
|
|
|
@@ -18472,7 +18465,7 @@ const listen = async ({
|
|
|
18472
18465
|
listeningOperation.throwIfAborted();
|
|
18473
18466
|
port = await findFreePort(portHint, {
|
|
18474
18467
|
signal: listeningOperation.signal,
|
|
18475
|
-
|
|
18468
|
+
hostname
|
|
18476
18469
|
});
|
|
18477
18470
|
}
|
|
18478
18471
|
|
|
@@ -18480,7 +18473,7 @@ const listen = async ({
|
|
|
18480
18473
|
port = await startListening({
|
|
18481
18474
|
server,
|
|
18482
18475
|
port,
|
|
18483
|
-
|
|
18476
|
+
hostname
|
|
18484
18477
|
});
|
|
18485
18478
|
listeningOperation.addAbortCallback(() => stopListening(server));
|
|
18486
18479
|
listeningOperation.throwIfAborted();
|
|
@@ -18492,7 +18485,7 @@ const listen = async ({
|
|
|
18492
18485
|
|
|
18493
18486
|
const findFreePort = async (initialPort = 1, {
|
|
18494
18487
|
signal = new AbortController().signal,
|
|
18495
|
-
|
|
18488
|
+
hostname = "127.0.0.1",
|
|
18496
18489
|
min = 1,
|
|
18497
18490
|
max = 65534,
|
|
18498
18491
|
next = port => port + 1
|
|
@@ -18514,27 +18507,27 @@ const findFreePort = async (initialPort = 1, {
|
|
|
18514
18507
|
const nextPort = next(port);
|
|
18515
18508
|
|
|
18516
18509
|
if (nextPort > max) {
|
|
18517
|
-
throw new Error(`${
|
|
18510
|
+
throw new Error(`${hostname} has no available port between ${min} and ${max}`);
|
|
18518
18511
|
}
|
|
18519
18512
|
|
|
18520
|
-
return testUntil(nextPort,
|
|
18513
|
+
return testUntil(nextPort, hostname);
|
|
18521
18514
|
};
|
|
18522
18515
|
|
|
18523
|
-
const freePort = await testUntil(initialPort,
|
|
18516
|
+
const freePort = await testUntil(initialPort, hostname);
|
|
18524
18517
|
return freePort;
|
|
18525
18518
|
} finally {
|
|
18526
18519
|
await findFreePortOperation.end();
|
|
18527
18520
|
}
|
|
18528
18521
|
};
|
|
18529
18522
|
|
|
18530
|
-
const portIsFree = async (port,
|
|
18523
|
+
const portIsFree = async (port, hostname) => {
|
|
18531
18524
|
const server = createServer();
|
|
18532
18525
|
|
|
18533
18526
|
try {
|
|
18534
18527
|
await startListening({
|
|
18535
18528
|
server,
|
|
18536
18529
|
port,
|
|
18537
|
-
|
|
18530
|
+
hostname
|
|
18538
18531
|
});
|
|
18539
18532
|
} catch (error) {
|
|
18540
18533
|
if (error && error.code === "EADDRINUSE") {
|
|
@@ -18555,7 +18548,7 @@ const portIsFree = async (port, host) => {
|
|
|
18555
18548
|
const startListening = ({
|
|
18556
18549
|
server,
|
|
18557
18550
|
port,
|
|
18558
|
-
|
|
18551
|
+
hostname
|
|
18559
18552
|
}) => {
|
|
18560
18553
|
return new Promise((resolve, reject) => {
|
|
18561
18554
|
server.on("error", reject);
|
|
@@ -18564,7 +18557,7 @@ const startListening = ({
|
|
|
18564
18557
|
// https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback
|
|
18565
18558
|
resolve(server.address().port);
|
|
18566
18559
|
});
|
|
18567
|
-
server.listen(port,
|
|
18560
|
+
server.listen(port, hostname);
|
|
18568
18561
|
});
|
|
18569
18562
|
};
|
|
18570
18563
|
|
|
@@ -18803,6 +18796,134 @@ const STOP_REASON_PROCESS_BEFORE_EXIT = createReason("process before exit");
|
|
|
18803
18796
|
const STOP_REASON_PROCESS_EXIT = createReason("process exit");
|
|
18804
18797
|
const STOP_REASON_NOT_SPECIFIED = createReason("not specified");
|
|
18805
18798
|
|
|
18799
|
+
const createIpGetters = () => {
|
|
18800
|
+
const networkAddresses = [];
|
|
18801
|
+
const networkInterfaceMap = networkInterfaces();
|
|
18802
|
+
|
|
18803
|
+
for (const key of Object.keys(networkInterfaceMap)) {
|
|
18804
|
+
for (const networkAddress of networkInterfaceMap[key]) {
|
|
18805
|
+
networkAddresses.push(networkAddress);
|
|
18806
|
+
}
|
|
18807
|
+
}
|
|
18808
|
+
|
|
18809
|
+
return {
|
|
18810
|
+
getFirstInternalIp: ({
|
|
18811
|
+
preferIpv6
|
|
18812
|
+
}) => {
|
|
18813
|
+
const isPref = preferIpv6 ? isIpV6 : isIpV4;
|
|
18814
|
+
let firstInternalIp;
|
|
18815
|
+
|
|
18816
|
+
for (const networkAddress of networkAddresses) {
|
|
18817
|
+
if (networkAddress.internal) {
|
|
18818
|
+
firstInternalIp = networkAddress.address;
|
|
18819
|
+
|
|
18820
|
+
if (isPref(networkAddress)) {
|
|
18821
|
+
break;
|
|
18822
|
+
}
|
|
18823
|
+
}
|
|
18824
|
+
}
|
|
18825
|
+
|
|
18826
|
+
return firstInternalIp;
|
|
18827
|
+
},
|
|
18828
|
+
getFirstExternalIp: ({
|
|
18829
|
+
preferIpv6
|
|
18830
|
+
}) => {
|
|
18831
|
+
const isPref = preferIpv6 ? isIpV6 : isIpV4;
|
|
18832
|
+
let firstExternalIp;
|
|
18833
|
+
|
|
18834
|
+
for (const networkAddress of networkAddresses) {
|
|
18835
|
+
if (!networkAddress.internal) {
|
|
18836
|
+
firstExternalIp = networkAddress.address;
|
|
18837
|
+
|
|
18838
|
+
if (isPref(networkAddress)) {
|
|
18839
|
+
break;
|
|
18840
|
+
}
|
|
18841
|
+
}
|
|
18842
|
+
}
|
|
18843
|
+
|
|
18844
|
+
return firstExternalIp;
|
|
18845
|
+
}
|
|
18846
|
+
};
|
|
18847
|
+
};
|
|
18848
|
+
|
|
18849
|
+
const isIpV4 = networkAddress => {
|
|
18850
|
+
// node 18.5
|
|
18851
|
+
if (typeof networkAddress.family === "number") {
|
|
18852
|
+
return networkAddress.family === 4;
|
|
18853
|
+
}
|
|
18854
|
+
|
|
18855
|
+
return networkAddress.family === "IPv4";
|
|
18856
|
+
};
|
|
18857
|
+
|
|
18858
|
+
const isIpV6 = networkAddress => !isIpV4(networkAddress);
|
|
18859
|
+
|
|
18860
|
+
const parseHostname = hostname => {
|
|
18861
|
+
if (hostname === "0.0.0.0") {
|
|
18862
|
+
return {
|
|
18863
|
+
type: "ip",
|
|
18864
|
+
label: "unspecified",
|
|
18865
|
+
version: 4
|
|
18866
|
+
};
|
|
18867
|
+
}
|
|
18868
|
+
|
|
18869
|
+
if (hostname === "::" || hostname === "0000:0000:0000:0000:0000:0000:0000:0000") {
|
|
18870
|
+
return {
|
|
18871
|
+
type: "ip",
|
|
18872
|
+
label: "unspecified",
|
|
18873
|
+
version: 6
|
|
18874
|
+
};
|
|
18875
|
+
}
|
|
18876
|
+
|
|
18877
|
+
if (hostname === "127.0.0.1") {
|
|
18878
|
+
return {
|
|
18879
|
+
type: "ip",
|
|
18880
|
+
label: "loopback",
|
|
18881
|
+
version: 4
|
|
18882
|
+
};
|
|
18883
|
+
}
|
|
18884
|
+
|
|
18885
|
+
if (hostname === "::1" || hostname === "0000:0000:0000:0000:0000:0000:0000:0001") {
|
|
18886
|
+
return {
|
|
18887
|
+
type: "ip",
|
|
18888
|
+
label: "loopback",
|
|
18889
|
+
version: 6
|
|
18890
|
+
};
|
|
18891
|
+
}
|
|
18892
|
+
|
|
18893
|
+
const ipVersion = isIP(hostname);
|
|
18894
|
+
|
|
18895
|
+
if (ipVersion === 0) {
|
|
18896
|
+
return {
|
|
18897
|
+
type: "hostname"
|
|
18898
|
+
};
|
|
18899
|
+
}
|
|
18900
|
+
|
|
18901
|
+
return {
|
|
18902
|
+
type: "ip",
|
|
18903
|
+
version: ipVersion
|
|
18904
|
+
};
|
|
18905
|
+
};
|
|
18906
|
+
|
|
18907
|
+
const applyDnsResolution = async (hostname, {
|
|
18908
|
+
verbatim = false
|
|
18909
|
+
} = {}) => {
|
|
18910
|
+
const dnsResolution = await new Promise((resolve, reject) => {
|
|
18911
|
+
lookup(hostname, {
|
|
18912
|
+
verbatim
|
|
18913
|
+
}, (error, address, family) => {
|
|
18914
|
+
if (error) {
|
|
18915
|
+
reject(error);
|
|
18916
|
+
} else {
|
|
18917
|
+
resolve({
|
|
18918
|
+
address,
|
|
18919
|
+
family
|
|
18920
|
+
});
|
|
18921
|
+
}
|
|
18922
|
+
});
|
|
18923
|
+
});
|
|
18924
|
+
return dnsResolution;
|
|
18925
|
+
};
|
|
18926
|
+
|
|
18806
18927
|
const startServer = async ({
|
|
18807
18928
|
signal = new AbortController().signal,
|
|
18808
18929
|
logLevel,
|
|
@@ -18814,7 +18935,8 @@ const startServer = async ({
|
|
|
18814
18935
|
redirectHttpToHttps,
|
|
18815
18936
|
allowHttpRequestOnHttps = false,
|
|
18816
18937
|
acceptAnyIp = false,
|
|
18817
|
-
|
|
18938
|
+
preferIpv6,
|
|
18939
|
+
hostname = "localhost",
|
|
18818
18940
|
port = 0,
|
|
18819
18941
|
// assign a random available port
|
|
18820
18942
|
portHint,
|
|
@@ -18844,6 +18966,10 @@ const startServer = async ({
|
|
|
18844
18966
|
}));
|
|
18845
18967
|
}
|
|
18846
18968
|
} = {}) => {
|
|
18969
|
+
const logger = createLogger({
|
|
18970
|
+
logLevel
|
|
18971
|
+
});
|
|
18972
|
+
|
|
18847
18973
|
if (protocol !== "http" && protocol !== "https") {
|
|
18848
18974
|
throw new Error(`protocol must be http or https, got ${protocol}`);
|
|
18849
18975
|
}
|
|
@@ -18862,10 +18988,6 @@ const startServer = async ({
|
|
|
18862
18988
|
throw new Error(`http2 needs "https" but protocol is "${protocol}"`);
|
|
18863
18989
|
}
|
|
18864
18990
|
|
|
18865
|
-
const logger = createLogger({
|
|
18866
|
-
logLevel
|
|
18867
|
-
});
|
|
18868
|
-
|
|
18869
18991
|
if (redirectHttpToHttps === undefined && protocol === "https" && !allowHttpRequestOnHttps) {
|
|
18870
18992
|
redirectHttpToHttps = true;
|
|
18871
18993
|
}
|
|
@@ -18898,6 +19020,10 @@ const startServer = async ({
|
|
|
18898
19020
|
let nodeServer;
|
|
18899
19021
|
const startServerOperation = Abort.startOperation();
|
|
18900
19022
|
const stopCallbackList = createCallbackListNotifiedOnce();
|
|
19023
|
+
const serverOrigins = {
|
|
19024
|
+
local: "" // favors hostname when possible
|
|
19025
|
+
|
|
19026
|
+
};
|
|
18901
19027
|
|
|
18902
19028
|
try {
|
|
18903
19029
|
startServerOperation.addAbortSignal(signal);
|
|
@@ -18925,12 +19051,85 @@ const startServer = async ({
|
|
|
18925
19051
|
nodeServer.unref();
|
|
18926
19052
|
}
|
|
18927
19053
|
|
|
19054
|
+
const createOrigin = hostname => {
|
|
19055
|
+
if (isIP(hostname) === 6) {
|
|
19056
|
+
return `${protocol}://[${hostname}]`;
|
|
19057
|
+
}
|
|
19058
|
+
|
|
19059
|
+
return `${protocol}://${hostname}`;
|
|
19060
|
+
};
|
|
19061
|
+
|
|
19062
|
+
const ipGetters = createIpGetters();
|
|
19063
|
+
let hostnameToListen;
|
|
19064
|
+
|
|
19065
|
+
if (acceptAnyIp) {
|
|
19066
|
+
const firstInternalIp = ipGetters.getFirstInternalIp({
|
|
19067
|
+
preferIpv6
|
|
19068
|
+
});
|
|
19069
|
+
serverOrigins.local = createOrigin(firstInternalIp);
|
|
19070
|
+
serverOrigins.localip = createOrigin(firstInternalIp);
|
|
19071
|
+
const firstExternalIp = ipGetters.getFirstExternalIp({
|
|
19072
|
+
preferIpv6
|
|
19073
|
+
});
|
|
19074
|
+
serverOrigins.externalip = createOrigin(firstExternalIp);
|
|
19075
|
+
hostnameToListen = preferIpv6 ? "::" : "0.0.0.0";
|
|
19076
|
+
} else {
|
|
19077
|
+
hostnameToListen = hostname;
|
|
19078
|
+
}
|
|
19079
|
+
|
|
19080
|
+
const hostnameInfo = parseHostname(hostname);
|
|
19081
|
+
|
|
19082
|
+
if (hostnameInfo.type === "ip") {
|
|
19083
|
+
if (acceptAnyIp) {
|
|
19084
|
+
throw new Error(`hostname cannot be an ip when acceptAnyIp is enabled, got ${hostname}`);
|
|
19085
|
+
}
|
|
19086
|
+
|
|
19087
|
+
preferIpv6 = hostnameInfo.version === 6;
|
|
19088
|
+
const firstInternalIp = ipGetters.getFirstInternalIp({
|
|
19089
|
+
preferIpv6
|
|
19090
|
+
});
|
|
19091
|
+
serverOrigins.local = createOrigin(firstInternalIp);
|
|
19092
|
+
serverOrigins.localip = createOrigin(firstInternalIp);
|
|
19093
|
+
|
|
19094
|
+
if (hostnameInfo.label === "unspecified") {
|
|
19095
|
+
const firstExternalIp = ipGetters.getFirstExternalIp({
|
|
19096
|
+
preferIpv6
|
|
19097
|
+
});
|
|
19098
|
+
serverOrigins.externalip = createOrigin(firstExternalIp);
|
|
19099
|
+
} else if (hostnameInfo.label === "loopback") {} else {
|
|
19100
|
+
serverOrigins.local = createOrigin(hostname);
|
|
19101
|
+
}
|
|
19102
|
+
} else {
|
|
19103
|
+
const hostnameDnsResolution = await applyDnsResolution(hostname, {
|
|
19104
|
+
verbatim: true
|
|
19105
|
+
});
|
|
19106
|
+
|
|
19107
|
+
if (hostnameDnsResolution) {
|
|
19108
|
+
const hostnameIp = hostnameDnsResolution.address;
|
|
19109
|
+
serverOrigins.localip = createOrigin(hostnameIp);
|
|
19110
|
+
serverOrigins.local = createOrigin(hostname);
|
|
19111
|
+
} else {
|
|
19112
|
+
const firstInternalIp = ipGetters.getFirstInternalIp({
|
|
19113
|
+
preferIpv6
|
|
19114
|
+
}); // fallback to internal ip because there is no ip
|
|
19115
|
+
// associated to this hostname on operating system (in hosts file)
|
|
19116
|
+
|
|
19117
|
+
hostname = firstInternalIp;
|
|
19118
|
+
hostnameToListen = firstInternalIp;
|
|
19119
|
+
serverOrigins.local = createOrigin(firstInternalIp);
|
|
19120
|
+
}
|
|
19121
|
+
}
|
|
19122
|
+
|
|
18928
19123
|
port = await listen({
|
|
18929
19124
|
signal: startServerOperation.signal,
|
|
18930
19125
|
server: nodeServer,
|
|
18931
19126
|
port,
|
|
18932
19127
|
portHint,
|
|
18933
|
-
|
|
19128
|
+
hostname: hostnameToListen
|
|
19129
|
+
}); // normalize origins (remove :80 when port is 80 for instance)
|
|
19130
|
+
|
|
19131
|
+
Object.keys(serverOrigins).forEach(key => {
|
|
19132
|
+
serverOrigins[key] = new URL(`${serverOrigins[key]}:${port}`).origin;
|
|
18934
19133
|
});
|
|
18935
19134
|
serviceController.callHooks("serverListening", {
|
|
18936
19135
|
port
|
|
@@ -18941,12 +19140,23 @@ const startServer = async ({
|
|
|
18941
19140
|
startServerOperation.throwIfAborted();
|
|
18942
19141
|
} finally {
|
|
18943
19142
|
await startServerOperation.end();
|
|
18944
|
-
} //
|
|
19143
|
+
} // the main server origin
|
|
19144
|
+
// - when protocol is http
|
|
19145
|
+
// node-fetch do not apply local dns resolution to map localhost back to 127.0.0.1
|
|
19146
|
+
// despites localhost being mapped so we prefer to use the internal ip
|
|
19147
|
+
// (127.0.0.1)
|
|
19148
|
+
// - when protocol is https
|
|
19149
|
+
// using the hostname becomes important because the certificate is generated
|
|
19150
|
+
// for hostnames, not for ips
|
|
19151
|
+
// so we prefer https://locahost or https://local_hostname
|
|
19152
|
+
// over the ip
|
|
19153
|
+
|
|
19154
|
+
|
|
19155
|
+
const serverOrigin = serverOrigins.local; // now the server is started (listening) it cannot be aborted anymore
|
|
18945
19156
|
// (otherwise an AbortError is thrown to the code calling "startServer")
|
|
18946
19157
|
// we can proceed to create a stop function to stop it gacefully
|
|
18947
19158
|
// and add a request handler
|
|
18948
19159
|
|
|
18949
|
-
|
|
18950
19160
|
stopCallbackList.add(({
|
|
18951
19161
|
reason
|
|
18952
19162
|
}) => {
|
|
@@ -18984,12 +19194,6 @@ const startServer = async ({
|
|
|
18984
19194
|
};
|
|
18985
19195
|
|
|
18986
19196
|
status = "opened";
|
|
18987
|
-
const serverOrigins = await getServerOrigins({
|
|
18988
|
-
protocol,
|
|
18989
|
-
host,
|
|
18990
|
-
port
|
|
18991
|
-
});
|
|
18992
|
-
const serverOrigin = serverOrigins.local;
|
|
18993
19197
|
const removeConnectionErrorListener = listenServerConnectionError(nodeServer, onError);
|
|
18994
19198
|
stopCallbackList.add(removeConnectionErrorListener);
|
|
18995
19199
|
const connectionsTracker = trackServerPendingConnections(nodeServer, {
|
|
@@ -19609,7 +19813,7 @@ const startServer = async ({
|
|
|
19609
19813
|
let websocketServer = new WebSocketServer({
|
|
19610
19814
|
noServer: true
|
|
19611
19815
|
});
|
|
19612
|
-
const websocketOrigin = protocol === "https" ? `wss://${
|
|
19816
|
+
const websocketOrigin = protocol === "https" ? `wss://${hostname}:${port}` : `ws://${hostname}:${port}`;
|
|
19613
19817
|
server.websocketOrigin = websocketOrigin;
|
|
19614
19818
|
|
|
19615
19819
|
const upgradeCallback = (nodeRequest, socket, head) => {
|
|
@@ -19650,6 +19854,7 @@ const startServer = async ({
|
|
|
19650
19854
|
Object.assign(server, {
|
|
19651
19855
|
getStatus: () => status,
|
|
19652
19856
|
port,
|
|
19857
|
+
hostname,
|
|
19653
19858
|
origin: serverOrigin,
|
|
19654
19859
|
origins: serverOrigins,
|
|
19655
19860
|
nodeServer,
|
|
@@ -25261,7 +25466,7 @@ const startOmegaServer = async ({
|
|
|
25261
25466
|
privateKey,
|
|
25262
25467
|
certificate,
|
|
25263
25468
|
acceptAnyIp,
|
|
25264
|
-
|
|
25469
|
+
hostname,
|
|
25265
25470
|
port = 0,
|
|
25266
25471
|
keepProcessAlive = false,
|
|
25267
25472
|
onStop = () => {},
|
|
@@ -25302,7 +25507,7 @@ const startOmegaServer = async ({
|
|
|
25302
25507
|
certificate,
|
|
25303
25508
|
privateKey,
|
|
25304
25509
|
acceptAnyIp,
|
|
25305
|
-
|
|
25510
|
+
hostname,
|
|
25306
25511
|
port,
|
|
25307
25512
|
requestWaitingMs: 60_1000,
|
|
25308
25513
|
services: [jsenvServiceCORS({
|
|
@@ -25408,7 +25613,7 @@ const startDevServer = async ({
|
|
|
25408
25613
|
http2 = false,
|
|
25409
25614
|
certificate,
|
|
25410
25615
|
privateKey,
|
|
25411
|
-
|
|
25616
|
+
hostname,
|
|
25412
25617
|
port = 3456,
|
|
25413
25618
|
acceptAnyIp,
|
|
25414
25619
|
keepProcessAlive = true,
|
|
@@ -25548,7 +25753,7 @@ const startDevServer = async ({
|
|
|
25548
25753
|
http2,
|
|
25549
25754
|
certificate,
|
|
25550
25755
|
privateKey,
|
|
25551
|
-
|
|
25756
|
+
hostname,
|
|
25552
25757
|
port,
|
|
25553
25758
|
services,
|
|
25554
25759
|
rootDirectoryUrl,
|
|
@@ -25651,87 +25856,6 @@ const generateCoverageTextLog = (coverage, {
|
|
|
25651
25856
|
report.execute(context);
|
|
25652
25857
|
};
|
|
25653
25858
|
|
|
25654
|
-
const babelPluginInstrument = (api, {
|
|
25655
|
-
rootDirectoryUrl,
|
|
25656
|
-
useInlineSourceMaps = false,
|
|
25657
|
-
coverageConfig = {
|
|
25658
|
-
"./**/*": true
|
|
25659
|
-
}
|
|
25660
|
-
}) => {
|
|
25661
|
-
const {
|
|
25662
|
-
programVisitor
|
|
25663
|
-
} = requireFromJsenv("istanbul-lib-instrument");
|
|
25664
|
-
const {
|
|
25665
|
-
types
|
|
25666
|
-
} = api;
|
|
25667
|
-
const associations = URL_META.resolveAssociations({
|
|
25668
|
-
cover: coverageConfig
|
|
25669
|
-
}, rootDirectoryUrl);
|
|
25670
|
-
|
|
25671
|
-
const shouldInstrument = url => {
|
|
25672
|
-
return URL_META.applyAssociations({
|
|
25673
|
-
url,
|
|
25674
|
-
associations
|
|
25675
|
-
}).cover;
|
|
25676
|
-
};
|
|
25677
|
-
|
|
25678
|
-
return {
|
|
25679
|
-
name: "transform-instrument",
|
|
25680
|
-
visitor: {
|
|
25681
|
-
Program: {
|
|
25682
|
-
enter(path) {
|
|
25683
|
-
const {
|
|
25684
|
-
file
|
|
25685
|
-
} = this;
|
|
25686
|
-
const {
|
|
25687
|
-
opts
|
|
25688
|
-
} = file;
|
|
25689
|
-
|
|
25690
|
-
if (!opts.sourceFileName) {
|
|
25691
|
-
console.warn(`cannot instrument file when "sourceFileName" option is not set`);
|
|
25692
|
-
return;
|
|
25693
|
-
}
|
|
25694
|
-
|
|
25695
|
-
const fileUrl = fileSystemPathToUrl$1(opts.sourceFileName);
|
|
25696
|
-
|
|
25697
|
-
if (!shouldInstrument(fileUrl)) {
|
|
25698
|
-
return;
|
|
25699
|
-
}
|
|
25700
|
-
|
|
25701
|
-
this.__dv__ = null;
|
|
25702
|
-
let inputSourceMap;
|
|
25703
|
-
|
|
25704
|
-
if (useInlineSourceMaps) {
|
|
25705
|
-
// https://github.com/istanbuljs/babel-plugin-istanbul/commit/a9e15643d249a2985e4387e4308022053b2cd0ad#diff-1fdf421c05c1140f6d71444ea2b27638R65
|
|
25706
|
-
inputSourceMap = opts.inputSourceMap || file.inputMap ? file.inputMap.sourcemap : null;
|
|
25707
|
-
} else {
|
|
25708
|
-
inputSourceMap = opts.inputSourceMap;
|
|
25709
|
-
}
|
|
25710
|
-
|
|
25711
|
-
this.__dv__ = programVisitor(types, opts.filenameRelative || opts.filename, {
|
|
25712
|
-
coverageVariable: "__coverage__",
|
|
25713
|
-
inputSourceMap
|
|
25714
|
-
});
|
|
25715
|
-
|
|
25716
|
-
this.__dv__.enter(path);
|
|
25717
|
-
},
|
|
25718
|
-
|
|
25719
|
-
exit(path) {
|
|
25720
|
-
if (!this.__dv__) {
|
|
25721
|
-
return;
|
|
25722
|
-
}
|
|
25723
|
-
|
|
25724
|
-
const object = this.__dv__.exit(path); // object got two properties: fileCoverage and sourceMappingURL
|
|
25725
|
-
|
|
25726
|
-
|
|
25727
|
-
this.file.metadata.coverage = object.fileCoverage;
|
|
25728
|
-
}
|
|
25729
|
-
|
|
25730
|
-
}
|
|
25731
|
-
}
|
|
25732
|
-
};
|
|
25733
|
-
};
|
|
25734
|
-
|
|
25735
25859
|
const readNodeV8CoverageDirectory = async ({
|
|
25736
25860
|
logger,
|
|
25737
25861
|
signal,
|
|
@@ -26424,6 +26548,41 @@ const run = async ({
|
|
|
26424
26548
|
}
|
|
26425
26549
|
};
|
|
26426
26550
|
|
|
26551
|
+
const pingServer = async url => {
|
|
26552
|
+
const server = createServer();
|
|
26553
|
+
const {
|
|
26554
|
+
hostname,
|
|
26555
|
+
port
|
|
26556
|
+
} = new URL(url);
|
|
26557
|
+
|
|
26558
|
+
try {
|
|
26559
|
+
await new Promise((resolve, reject) => {
|
|
26560
|
+
server.on("error", reject);
|
|
26561
|
+
server.on("listening", () => {
|
|
26562
|
+
resolve();
|
|
26563
|
+
});
|
|
26564
|
+
server.listen(port, hostname);
|
|
26565
|
+
});
|
|
26566
|
+
} catch (error) {
|
|
26567
|
+
if (error && error.code === "EADDRINUSE") {
|
|
26568
|
+
return true;
|
|
26569
|
+
}
|
|
26570
|
+
|
|
26571
|
+
if (error && error.code === "EACCES") {
|
|
26572
|
+
return true;
|
|
26573
|
+
}
|
|
26574
|
+
|
|
26575
|
+
throw error;
|
|
26576
|
+
}
|
|
26577
|
+
|
|
26578
|
+
await new Promise((resolve, reject) => {
|
|
26579
|
+
server.on("error", reject);
|
|
26580
|
+
server.on("close", resolve);
|
|
26581
|
+
server.close();
|
|
26582
|
+
});
|
|
26583
|
+
return false;
|
|
26584
|
+
};
|
|
26585
|
+
|
|
26427
26586
|
const ensureGlobalGc = () => {
|
|
26428
26587
|
if (!global.gc) {
|
|
26429
26588
|
v8.setFlagsFromString("--expose_gc");
|
|
@@ -26859,8 +27018,8 @@ const executePlan = async (plan, {
|
|
|
26859
27018
|
completedExecutionLogMerging,
|
|
26860
27019
|
completedExecutionLogAbbreviation,
|
|
26861
27020
|
rootDirectoryUrl,
|
|
27021
|
+
devServerOrigin,
|
|
26862
27022
|
keepRunning,
|
|
26863
|
-
services,
|
|
26864
27023
|
defaultMsAllocatedPerExecution,
|
|
26865
27024
|
maxExecutionsInParallel,
|
|
26866
27025
|
failFast,
|
|
@@ -26873,18 +27032,6 @@ const executePlan = async (plan, {
|
|
|
26873
27032
|
coverageMethodForNodeJs,
|
|
26874
27033
|
coverageV8ConflictWarning,
|
|
26875
27034
|
coverageTempDirectoryRelativeUrl,
|
|
26876
|
-
scenarios,
|
|
26877
|
-
sourcemaps,
|
|
26878
|
-
plugins,
|
|
26879
|
-
nodeEsmResolution,
|
|
26880
|
-
fileSystemMagicResolution,
|
|
26881
|
-
transpilation,
|
|
26882
|
-
writeGeneratedFiles,
|
|
26883
|
-
protocol,
|
|
26884
|
-
privateKey,
|
|
26885
|
-
certificate,
|
|
26886
|
-
host,
|
|
26887
|
-
port,
|
|
26888
27035
|
beforeExecutionCallback = () => {},
|
|
26889
27036
|
afterExecutionCallback = () => {}
|
|
26890
27037
|
} = {}) => {
|
|
@@ -26908,7 +27055,7 @@ const executePlan = async (plan, {
|
|
|
26908
27055
|
if (runtime) {
|
|
26909
27056
|
runtimes[runtime.name] = runtime.version;
|
|
26910
27057
|
|
|
26911
|
-
if (runtime.
|
|
27058
|
+
if (runtime.type === "browser") {
|
|
26912
27059
|
someNeedsServer = true;
|
|
26913
27060
|
}
|
|
26914
27061
|
|
|
@@ -26999,6 +27146,7 @@ const executePlan = async (plan, {
|
|
|
26999
27146
|
|
|
27000
27147
|
let runtimeParams = {
|
|
27001
27148
|
rootDirectoryUrl,
|
|
27149
|
+
devServerOrigin,
|
|
27002
27150
|
coverageEnabled,
|
|
27003
27151
|
coverageConfig,
|
|
27004
27152
|
coverageMethodForBrowsers,
|
|
@@ -27007,48 +27155,15 @@ const executePlan = async (plan, {
|
|
|
27007
27155
|
};
|
|
27008
27156
|
|
|
27009
27157
|
if (someNeedsServer) {
|
|
27010
|
-
|
|
27011
|
-
|
|
27012
|
-
|
|
27013
|
-
keepProcessAlive: false,
|
|
27014
|
-
port,
|
|
27015
|
-
host,
|
|
27016
|
-
protocol,
|
|
27017
|
-
certificate,
|
|
27018
|
-
privateKey,
|
|
27019
|
-
services,
|
|
27020
|
-
rootDirectoryUrl,
|
|
27021
|
-
scenarios,
|
|
27022
|
-
runtimeCompat: runtimes,
|
|
27023
|
-
plugins,
|
|
27024
|
-
htmlSupervisor: true,
|
|
27025
|
-
nodeEsmResolution,
|
|
27026
|
-
fileSystemMagicResolution,
|
|
27027
|
-
transpilation: { ...transpilation,
|
|
27028
|
-
getCustomBabelPlugins: ({
|
|
27029
|
-
clientRuntimeCompat
|
|
27030
|
-
}) => {
|
|
27031
|
-
if (coverageEnabled && (coverageMethodForBrowsers !== "playwright_api" || Object.keys(clientRuntimeCompat)[0] !== "chrome")) {
|
|
27032
|
-
return {
|
|
27033
|
-
"transform-instrument": [babelPluginInstrument, {
|
|
27034
|
-
rootDirectoryUrl,
|
|
27035
|
-
coverageConfig
|
|
27036
|
-
}]
|
|
27037
|
-
};
|
|
27038
|
-
}
|
|
27158
|
+
if (!devServerOrigin) {
|
|
27159
|
+
throw new TypeError(`devServerOrigin is required when running tests on browser(s)`);
|
|
27160
|
+
}
|
|
27039
27161
|
|
|
27040
|
-
|
|
27041
|
-
|
|
27042
|
-
|
|
27043
|
-
|
|
27044
|
-
|
|
27045
|
-
});
|
|
27046
|
-
multipleExecutionsOperation.addEndCallback(async () => {
|
|
27047
|
-
await server.stop();
|
|
27048
|
-
});
|
|
27049
|
-
runtimeParams = { ...runtimeParams,
|
|
27050
|
-
server
|
|
27051
|
-
};
|
|
27162
|
+
const devServerStarted = await pingServer(devServerOrigin);
|
|
27163
|
+
|
|
27164
|
+
if (!devServerStarted) {
|
|
27165
|
+
throw new Error(`dev server not started at ${devServerOrigin}. It is required to run tests`);
|
|
27166
|
+
}
|
|
27052
27167
|
}
|
|
27053
27168
|
|
|
27054
27169
|
logger.debug(`Generate executions`);
|
|
@@ -27391,9 +27506,10 @@ const executeInParallel = async ({
|
|
|
27391
27506
|
};
|
|
27392
27507
|
|
|
27393
27508
|
/**
|
|
27394
|
-
* Execute a list of files and log how it goes
|
|
27509
|
+
* Execute a list of files and log how it goes.
|
|
27395
27510
|
* @param {Object} testPlanParameters
|
|
27396
27511
|
* @param {string|url} testPlanParameters.rootDirectoryUrl Root directory of the project
|
|
27512
|
+
* @param {string|url} [testPlanParameters.serverOrigin=undefined] Jsenv dev server origin; required when executing test on browsers
|
|
27397
27513
|
* @param {Object} testPlanParameters.testPlan Object associating patterns leading to files to runtimes where they should be executed
|
|
27398
27514
|
* @param {boolean} [testPlanParameters.completedExecutionLogAbbreviation=false] Abbreviate completed execution information to shorten terminal output
|
|
27399
27515
|
* @param {boolean} [testPlanParameters.completedExecutionLogMerging=false] Merge completed execution logs to shorten terminal output
|
|
@@ -27420,6 +27536,7 @@ const executeTestPlan = async ({
|
|
|
27420
27536
|
completedExecutionLogAbbreviation = false,
|
|
27421
27537
|
completedExecutionLogMerging = false,
|
|
27422
27538
|
rootDirectoryUrl,
|
|
27539
|
+
devServerOrigin,
|
|
27423
27540
|
testPlan,
|
|
27424
27541
|
updateProcessExitCode = true,
|
|
27425
27542
|
maxExecutionsInParallel = 1,
|
|
@@ -27450,17 +27567,7 @@ const executeTestPlan = async ({
|
|
|
27450
27567
|
coverageReportSkipFull = false,
|
|
27451
27568
|
coverageReportTextLog = true,
|
|
27452
27569
|
coverageReportJsonFile = process.env.CI ? null : "./.coverage/coverage.json",
|
|
27453
|
-
coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null
|
|
27454
|
-
sourcemaps = "inline",
|
|
27455
|
-
plugins = [],
|
|
27456
|
-
nodeEsmResolution,
|
|
27457
|
-
fileSystemMagicResolution,
|
|
27458
|
-
writeGeneratedFiles = false,
|
|
27459
|
-
protocol,
|
|
27460
|
-
privateKey,
|
|
27461
|
-
certificate,
|
|
27462
|
-
host,
|
|
27463
|
-
port
|
|
27570
|
+
coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null
|
|
27464
27571
|
}) => {
|
|
27465
27572
|
const logger = createLogger({
|
|
27466
27573
|
logLevel
|
|
@@ -27520,6 +27627,7 @@ const executeTestPlan = async ({
|
|
|
27520
27627
|
completedExecutionLogMerging,
|
|
27521
27628
|
completedExecutionLogAbbreviation,
|
|
27522
27629
|
rootDirectoryUrl,
|
|
27630
|
+
devServerOrigin,
|
|
27523
27631
|
maxExecutionsInParallel,
|
|
27524
27632
|
defaultMsAllocatedPerExecution,
|
|
27525
27633
|
failFast,
|
|
@@ -27532,21 +27640,7 @@ const executeTestPlan = async ({
|
|
|
27532
27640
|
coverageMethodForBrowsers,
|
|
27533
27641
|
coverageMethodForNodeJs,
|
|
27534
27642
|
coverageV8ConflictWarning,
|
|
27535
|
-
coverageTempDirectoryRelativeUrl
|
|
27536
|
-
scenarios: {
|
|
27537
|
-
dev: true,
|
|
27538
|
-
test: true
|
|
27539
|
-
},
|
|
27540
|
-
sourcemaps,
|
|
27541
|
-
plugins,
|
|
27542
|
-
nodeEsmResolution,
|
|
27543
|
-
fileSystemMagicResolution,
|
|
27544
|
-
writeGeneratedFiles,
|
|
27545
|
-
protocol,
|
|
27546
|
-
privateKey,
|
|
27547
|
-
certificate,
|
|
27548
|
-
host,
|
|
27549
|
-
port
|
|
27643
|
+
coverageTempDirectoryRelativeUrl
|
|
27550
27644
|
});
|
|
27551
27645
|
|
|
27552
27646
|
if (updateProcessExitCode && result.planSummary.counters.total !== result.planSummary.counters.completed) {
|
|
@@ -27664,8 +27758,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27664
27758
|
const runtime = {
|
|
27665
27759
|
type: "browser",
|
|
27666
27760
|
name: browserName,
|
|
27667
|
-
version: browserVersion
|
|
27668
|
-
needsServer: true
|
|
27761
|
+
version: browserVersion
|
|
27669
27762
|
};
|
|
27670
27763
|
let browserAndContextPromise;
|
|
27671
27764
|
|
|
@@ -27674,7 +27767,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27674
27767
|
logger,
|
|
27675
27768
|
rootDirectoryUrl,
|
|
27676
27769
|
fileRelativeUrl,
|
|
27677
|
-
|
|
27770
|
+
devServerOrigin,
|
|
27678
27771
|
// measurePerformance,
|
|
27679
27772
|
collectPerformance,
|
|
27680
27773
|
coverageEnabled = false,
|
|
@@ -27749,7 +27842,13 @@ const createRuntimeFromPlaywright = ({
|
|
|
27749
27842
|
await disconnected;
|
|
27750
27843
|
};
|
|
27751
27844
|
|
|
27752
|
-
const
|
|
27845
|
+
const coverageInHeaders = coverageEnabled && (!coveragePlaywrightAPIAvailable || coverageMethodForBrowsers !== "playwright_api");
|
|
27846
|
+
const page = await browserContext.newPage({
|
|
27847
|
+
extraHTTPHeaders: { ...(coverageInHeaders ? {
|
|
27848
|
+
"x-coverage-istanbul": JSON.stringify(coverageConfig)
|
|
27849
|
+
} : {})
|
|
27850
|
+
}
|
|
27851
|
+
});
|
|
27753
27852
|
|
|
27754
27853
|
const closePage = async () => {
|
|
27755
27854
|
try {
|
|
@@ -27777,7 +27876,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27777
27876
|
const v8CoveragesWithFsUrls = v8CoveragesWithWebUrls.map(v8CoveragesWithWebUrl => {
|
|
27778
27877
|
const fsUrl = moveUrl({
|
|
27779
27878
|
url: v8CoveragesWithWebUrl.url,
|
|
27780
|
-
from: `${
|
|
27879
|
+
from: `${devServerOrigin}/`,
|
|
27781
27880
|
to: rootDirectoryUrl,
|
|
27782
27881
|
preferAbsolute: true
|
|
27783
27882
|
});
|
|
@@ -27848,7 +27947,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27848
27947
|
});
|
|
27849
27948
|
}
|
|
27850
27949
|
|
|
27851
|
-
const fileClientUrl = new URL(fileRelativeUrl, `${
|
|
27950
|
+
const fileClientUrl = new URL(fileRelativeUrl, `${devServerOrigin}/`).href; // https://github.com/GoogleChrome/puppeteer/blob/v1.4.0/docs/api.md#event-console
|
|
27852
27951
|
|
|
27853
27952
|
const removeConsoleListener = registerEvent({
|
|
27854
27953
|
object: page,
|
|
@@ -27962,7 +28061,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27962
28061
|
} = returnValue;
|
|
27963
28062
|
const error = evalException(exceptionSource, {
|
|
27964
28063
|
rootDirectoryUrl,
|
|
27965
|
-
|
|
28064
|
+
devServerOrigin,
|
|
27966
28065
|
transformErrorHook
|
|
27967
28066
|
});
|
|
27968
28067
|
cb({
|
|
@@ -28198,7 +28297,7 @@ const registerEvent = ({
|
|
|
28198
28297
|
|
|
28199
28298
|
const evalException = (exceptionSource, {
|
|
28200
28299
|
rootDirectoryUrl,
|
|
28201
|
-
|
|
28300
|
+
devServerOrigin,
|
|
28202
28301
|
transformErrorHook
|
|
28203
28302
|
}) => {
|
|
28204
28303
|
const script = new Script(exceptionSource, {
|
|
@@ -28207,7 +28306,7 @@ const evalException = (exceptionSource, {
|
|
|
28207
28306
|
const error = script.runInThisContext();
|
|
28208
28307
|
|
|
28209
28308
|
if (error && error instanceof Error) {
|
|
28210
|
-
const remoteRootRegexp = new RegExp(escapeRegexpSpecialChars(`${
|
|
28309
|
+
const remoteRootRegexp = new RegExp(escapeRegexpSpecialChars(`${devServerOrigin}/`), "g");
|
|
28211
28310
|
error.stack = error.stack.replace(remoteRootRegexp, rootDirectoryUrl);
|
|
28212
28311
|
error.message = error.message.replace(remoteRootRegexp, rootDirectoryUrl);
|
|
28213
28312
|
}
|
|
@@ -29205,7 +29304,7 @@ const startBuildServer = async ({
|
|
|
29205
29304
|
certificate,
|
|
29206
29305
|
privateKey,
|
|
29207
29306
|
acceptAnyIp,
|
|
29208
|
-
|
|
29307
|
+
hostname,
|
|
29209
29308
|
port = 9779,
|
|
29210
29309
|
services = [],
|
|
29211
29310
|
keepProcessAlive = true,
|
|
@@ -29342,7 +29441,7 @@ const startBuildServer = async ({
|
|
|
29342
29441
|
certificate,
|
|
29343
29442
|
privateKey,
|
|
29344
29443
|
acceptAnyIp,
|
|
29345
|
-
|
|
29444
|
+
hostname,
|
|
29346
29445
|
port,
|
|
29347
29446
|
serverTiming: true,
|
|
29348
29447
|
requestWaitingMs: 60_000,
|
|
@@ -29413,32 +29512,17 @@ const execute = async ({
|
|
|
29413
29512
|
handleSIGINT = true,
|
|
29414
29513
|
logLevel,
|
|
29415
29514
|
rootDirectoryUrl,
|
|
29515
|
+
devServerOrigin,
|
|
29416
29516
|
fileRelativeUrl,
|
|
29417
29517
|
allocatedMs,
|
|
29418
29518
|
mirrorConsole = true,
|
|
29419
29519
|
keepRunning = false,
|
|
29420
|
-
services,
|
|
29421
29520
|
collectConsole,
|
|
29422
29521
|
collectCoverage,
|
|
29423
29522
|
coverageTempDirectoryUrl,
|
|
29424
29523
|
collectPerformance = false,
|
|
29425
29524
|
runtime,
|
|
29426
29525
|
runtimeParams,
|
|
29427
|
-
scenarios = {
|
|
29428
|
-
dev: true
|
|
29429
|
-
},
|
|
29430
|
-
plugins = [],
|
|
29431
|
-
nodeEsmResolution,
|
|
29432
|
-
fileSystemMagicResolution,
|
|
29433
|
-
transpilation,
|
|
29434
|
-
htmlSupervisor = true,
|
|
29435
|
-
sourcemaps = "inline",
|
|
29436
|
-
writeGeneratedFiles = false,
|
|
29437
|
-
port,
|
|
29438
|
-
protocol,
|
|
29439
|
-
http2,
|
|
29440
|
-
certificate,
|
|
29441
|
-
privateKey,
|
|
29442
29526
|
ignoreError = false
|
|
29443
29527
|
}) => {
|
|
29444
29528
|
const logger = createLogger({
|
|
@@ -29460,45 +29544,21 @@ const execute = async ({
|
|
|
29460
29544
|
|
|
29461
29545
|
runtimeParams = {
|
|
29462
29546
|
rootDirectoryUrl,
|
|
29547
|
+
devServerOrigin,
|
|
29463
29548
|
fileRelativeUrl,
|
|
29464
29549
|
...runtimeParams
|
|
29465
29550
|
};
|
|
29466
29551
|
|
|
29467
|
-
if (runtime.
|
|
29468
|
-
|
|
29469
|
-
|
|
29470
|
-
|
|
29471
|
-
keepProcessAlive: false,
|
|
29472
|
-
services,
|
|
29473
|
-
port,
|
|
29474
|
-
protocol,
|
|
29475
|
-
http2,
|
|
29476
|
-
certificate,
|
|
29477
|
-
privateKey,
|
|
29478
|
-
rootDirectoryUrl,
|
|
29479
|
-
scenarios,
|
|
29480
|
-
runtimeCompat: {
|
|
29481
|
-
[runtime.name]: runtime.version
|
|
29482
|
-
},
|
|
29483
|
-
plugins,
|
|
29484
|
-
htmlSupervisor,
|
|
29485
|
-
nodeEsmResolution,
|
|
29486
|
-
fileSystemMagicResolution,
|
|
29487
|
-
transpilation,
|
|
29488
|
-
sourcemaps,
|
|
29489
|
-
writeGeneratedFiles
|
|
29490
|
-
});
|
|
29491
|
-
executeOperation.addEndCallback(async () => {
|
|
29492
|
-
await server.stop("execution done");
|
|
29493
|
-
});
|
|
29494
|
-
runtimeParams = { ...runtimeParams,
|
|
29495
|
-
server
|
|
29496
|
-
};
|
|
29552
|
+
if (runtime.type === "browser") {
|
|
29553
|
+
if (!devServerOrigin) {
|
|
29554
|
+
throw new TypeError(`devServerOrigin is required when running tests on browser(s)`);
|
|
29555
|
+
}
|
|
29497
29556
|
|
|
29498
|
-
|
|
29499
|
-
|
|
29500
|
-
|
|
29501
|
-
|
|
29557
|
+
const devServerStarted = await pingServer(devServerOrigin);
|
|
29558
|
+
|
|
29559
|
+
if (!devServerStarted) {
|
|
29560
|
+
throw new Error(`dev server not started at ${devServerOrigin}. It is required to run tests`);
|
|
29561
|
+
}
|
|
29502
29562
|
}
|
|
29503
29563
|
|
|
29504
29564
|
let result = await run({
|
|
@@ -29620,4 +29680,4 @@ const jsenvPluginInjectGlobals = urlAssociations => {
|
|
|
29620
29680
|
};
|
|
29621
29681
|
};
|
|
29622
29682
|
|
|
29623
|
-
export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeChildProcess, nodeWorkerThread, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
|
|
29683
|
+
export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeChildProcess, nodeWorkerThread, pingServer, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
|