doc-detective 4.6.1 → 4.7.0-runtime-dependency-detection.1
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/cli.js +57 -6
- package/dist/cli.js.map +1 -1
- package/dist/common/src/schemas/schemas.json +6 -18
- package/dist/common/src/types/generated/config_v3.d.ts +2 -1
- package/dist/common/src/types/generated/config_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/resolvedTests_v3.d.ts +2 -1
- package/dist/common/src/types/generated/resolvedTests_v3.d.ts.map +1 -1
- package/dist/core/config.d.ts +17 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +218 -63
- package/dist/core/config.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +7 -10
- package/dist/core/index.js.map +1 -1
- package/dist/core/tests.d.ts +41 -1
- package/dist/core/tests.d.ts.map +1 -1
- package/dist/core/tests.js +166 -7
- package/dist/core/tests.js.map +1 -1
- package/dist/debug/command.d.ts +10 -0
- package/dist/debug/command.d.ts.map +1 -0
- package/dist/debug/command.js +72 -0
- package/dist/debug/command.js.map +1 -0
- package/dist/debug/envvars.d.ts +9 -0
- package/dist/debug/envvars.d.ts.map +1 -0
- package/dist/debug/envvars.js +231 -0
- package/dist/debug/envvars.js.map +1 -0
- package/dist/debug/index.d.ts +85 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +465 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/debug/redact.d.ts +7 -0
- package/dist/debug/redact.d.ts.map +1 -0
- package/dist/debug/redact.js +190 -0
- package/dist/debug/redact.js.map +1 -0
- package/dist/debug/render.d.ts +8 -0
- package/dist/debug/render.d.ts.map +1 -0
- package/dist/debug/render.js +42 -0
- package/dist/debug/render.js.map +1 -0
- package/dist/debug/system.d.ts +24 -0
- package/dist/debug/system.d.ts.map +1 -0
- package/dist/debug/system.js +59 -0
- package/dist/debug/system.js.map +1 -0
- package/dist/debug/tools.d.ts +11 -0
- package/dist/debug/tools.d.ts.map +1 -0
- package/dist/debug/tools.js +170 -0
- package/dist/debug/tools.js.map +1 -0
- package/dist/hints/hints.d.ts.map +1 -1
- package/dist/hints/hints.js +17 -0
- package/dist/hints/hints.js.map +1 -1
- package/dist/index.cjs +374 -147
- package/dist/runtime/browsers.d.ts +14 -0
- package/dist/runtime/browsers.d.ts.map +1 -1
- package/dist/runtime/browsers.js +23 -0
- package/dist/runtime/browsers.js.map +1 -1
- package/dist/runtime/installer.d.ts.map +1 -1
- package/dist/runtime/installer.js +44 -9
- package/dist/runtime/installer.js.map +1 -1
- package/dist/runtime/loader.d.ts +20 -0
- package/dist/runtime/loader.d.ts.map +1 -1
- package/dist/runtime/loader.js +50 -0
- package/dist/runtime/loader.js.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +38 -11
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -9923,7 +9923,8 @@ var init_schemas = __esm({
|
|
|
9923
9923
|
title: "Environment details"
|
|
9924
9924
|
},
|
|
9925
9925
|
debug: {
|
|
9926
|
-
description: "
|
|
9926
|
+
description: "Deprecated and ignored. Previously reserved for an interactive step-through debugger that was never implemented. Retained so existing configs continue to validate. For diagnostics, run `doc-detective debug` or set the `DOC_DETECTIVE_DEBUG` environment variable.",
|
|
9927
|
+
deprecated: true,
|
|
9927
9928
|
anyOf: [
|
|
9928
9929
|
{
|
|
9929
9930
|
type: "boolean"
|
|
@@ -9934,8 +9935,7 @@ var init_schemas = __esm({
|
|
|
9934
9935
|
"stepThrough"
|
|
9935
9936
|
]
|
|
9936
9937
|
}
|
|
9937
|
-
]
|
|
9938
|
-
default: false
|
|
9938
|
+
]
|
|
9939
9939
|
},
|
|
9940
9940
|
dryRun: {
|
|
9941
9941
|
description: "If `true`, fully resolve tests (file/env config merge, schema validation, file detection, inline-test extraction) and emit the resolved test plan as JSON, but do not execute any steps. Equivalent to `--dry-run` on the CLI.",
|
|
@@ -18245,12 +18245,6 @@ var init_schemas = __esm({
|
|
|
18245
18245
|
{
|
|
18246
18246
|
debug: false
|
|
18247
18247
|
},
|
|
18248
|
-
{
|
|
18249
|
-
debug: true
|
|
18250
|
-
},
|
|
18251
|
-
{
|
|
18252
|
-
debug: "stepThrough"
|
|
18253
|
-
},
|
|
18254
18248
|
{
|
|
18255
18249
|
integrations: {
|
|
18256
18250
|
docDetectiveApi: {
|
|
@@ -31882,7 +31876,8 @@ var init_schemas = __esm({
|
|
|
31882
31876
|
title: "Environment details"
|
|
31883
31877
|
},
|
|
31884
31878
|
debug: {
|
|
31885
|
-
description: "
|
|
31879
|
+
description: "Deprecated and ignored. Previously reserved for an interactive step-through debugger that was never implemented. Retained so existing configs continue to validate. For diagnostics, run `doc-detective debug` or set the `DOC_DETECTIVE_DEBUG` environment variable.",
|
|
31880
|
+
deprecated: true,
|
|
31886
31881
|
anyOf: [
|
|
31887
31882
|
{
|
|
31888
31883
|
type: "boolean"
|
|
@@ -31893,8 +31888,7 @@ var init_schemas = __esm({
|
|
|
31893
31888
|
"stepThrough"
|
|
31894
31889
|
]
|
|
31895
31890
|
}
|
|
31896
|
-
]
|
|
31897
|
-
default: false
|
|
31891
|
+
]
|
|
31898
31892
|
},
|
|
31899
31893
|
dryRun: {
|
|
31900
31894
|
description: "If `true`, fully resolve tests (file/env config merge, schema validation, file detection, inline-test extraction) and emit the resolved test plan as JSON, but do not execute any steps. Equivalent to `--dry-run` on the CLI.",
|
|
@@ -40204,12 +40198,6 @@ var init_schemas = __esm({
|
|
|
40204
40198
|
{
|
|
40205
40199
|
debug: false
|
|
40206
40200
|
},
|
|
40207
|
-
{
|
|
40208
|
-
debug: true
|
|
40209
|
-
},
|
|
40210
|
-
{
|
|
40211
|
-
debug: "stepThrough"
|
|
40212
|
-
},
|
|
40213
40201
|
{
|
|
40214
40202
|
integrations: {
|
|
40215
40203
|
docDetectiveApi: {
|
|
@@ -130740,7 +130728,9 @@ var loader_exports = {};
|
|
|
130740
130728
|
__export(loader_exports, {
|
|
130741
130729
|
ensureRuntimeInstalled: () => ensureRuntimeInstalled,
|
|
130742
130730
|
loadHeavyDep: () => loadHeavyDep,
|
|
130743
|
-
resolveHeavyDepPath: () => resolveHeavyDepPath
|
|
130731
|
+
resolveHeavyDepPath: () => resolveHeavyDepPath,
|
|
130732
|
+
resolveHeavyDepSource: () => resolveHeavyDepSource,
|
|
130733
|
+
resolveHeavyDepVersion: () => resolveHeavyDepVersion
|
|
130744
130734
|
});
|
|
130745
130735
|
function tryResolveFromShim(name) {
|
|
130746
130736
|
try {
|
|
@@ -130764,6 +130754,36 @@ function tryResolveFromCache(name, ctx = {}) {
|
|
|
130764
130754
|
function resolveHeavyDepPath(name, ctx = {}) {
|
|
130765
130755
|
return tryResolveFromShim(name) ?? tryResolveFromCache(name, ctx);
|
|
130766
130756
|
}
|
|
130757
|
+
function resolveHeavyDepSource(name, ctx = {}) {
|
|
130758
|
+
if (tryResolveFromShim(name))
|
|
130759
|
+
return "shim";
|
|
130760
|
+
if (tryResolveFromCache(name, ctx))
|
|
130761
|
+
return "cache";
|
|
130762
|
+
return null;
|
|
130763
|
+
}
|
|
130764
|
+
function resolveHeavyDepVersion(name, ctx = {}) {
|
|
130765
|
+
const entry = resolveHeavyDepPath(name, ctx);
|
|
130766
|
+
if (!entry)
|
|
130767
|
+
return null;
|
|
130768
|
+
let dir = import_node_path4.default.dirname(entry);
|
|
130769
|
+
for (let i = 0; i < 12; i++) {
|
|
130770
|
+
const pkgJsonPath = import_node_path4.default.join(dir, "package.json");
|
|
130771
|
+
try {
|
|
130772
|
+
if (import_node_fs4.default.existsSync(pkgJsonPath)) {
|
|
130773
|
+
const parsed = JSON.parse(import_node_fs4.default.readFileSync(pkgJsonPath, "utf8"));
|
|
130774
|
+
if (parsed?.name === name && typeof parsed.version === "string") {
|
|
130775
|
+
return parsed.version;
|
|
130776
|
+
}
|
|
130777
|
+
}
|
|
130778
|
+
} catch {
|
|
130779
|
+
}
|
|
130780
|
+
const parent = import_node_path4.default.dirname(dir);
|
|
130781
|
+
if (parent === dir)
|
|
130782
|
+
break;
|
|
130783
|
+
dir = parent;
|
|
130784
|
+
}
|
|
130785
|
+
return null;
|
|
130786
|
+
}
|
|
130767
130787
|
async function loadHeavyDep(name, options = {}) {
|
|
130768
130788
|
const { autoInstall = true, ctx = {}, deps = {} } = options;
|
|
130769
130789
|
let resolved = tryResolveFromShim(name);
|
|
@@ -131426,6 +131446,7 @@ var config_exports = {};
|
|
|
131426
131446
|
__export(config_exports, {
|
|
131427
131447
|
clearAppCache: () => clearAppCache,
|
|
131428
131448
|
getAvailableApps: () => getAvailableApps,
|
|
131449
|
+
getBrowserDiagnostics: () => getBrowserDiagnostics,
|
|
131429
131450
|
getEnvironment: () => getEnvironment,
|
|
131430
131451
|
resolveConcurrentRunners: () => resolveConcurrentRunners,
|
|
131431
131452
|
setConfig: () => setConfig
|
|
@@ -131619,19 +131640,14 @@ function clearAppCache(config) {
|
|
|
131619
131640
|
}
|
|
131620
131641
|
cachedAppsByDir.delete(cacheKeyFor(config));
|
|
131621
131642
|
}
|
|
131622
|
-
async function
|
|
131623
|
-
const browsersDir = getBrowsersDir({ cacheDir: config?.cacheDir });
|
|
131624
|
-
const key = browsersDir;
|
|
131625
|
-
const hit = cachedAppsByDir.get(key);
|
|
131626
|
-
if (hit)
|
|
131627
|
-
return hit;
|
|
131643
|
+
async function probeBrowserEnvironment({ config, browsersDir }) {
|
|
131628
131644
|
setAppiumHome({ cacheDir: config?.cacheDir });
|
|
131629
131645
|
const cwd = process.cwd();
|
|
131630
131646
|
process.chdir(import_node_path7.default.join(__dirname4, "../.."));
|
|
131631
|
-
|
|
131647
|
+
let installedBrowsers = [];
|
|
131632
131648
|
let browserDetectionFailed = false;
|
|
131649
|
+
let appiumDriverOutput = "";
|
|
131633
131650
|
try {
|
|
131634
|
-
let installedBrowsers = [];
|
|
131635
131651
|
const browsersInstalled = resolveHeavyDepPath("@puppeteer/browsers", {
|
|
131636
131652
|
cacheDir: config?.cacheDir
|
|
131637
131653
|
});
|
|
@@ -131686,47 +131702,165 @@ async function getAvailableApps({ config }) {
|
|
|
131686
131702
|
});
|
|
131687
131703
|
});
|
|
131688
131704
|
});
|
|
131689
|
-
|
|
131690
|
-
const chrome = installedBrowsers.find((browser) => browser.browser === "chrome");
|
|
131691
|
-
const chromeVersion = chrome?.buildId;
|
|
131692
|
-
const chromedriver = installedBrowsers.find((browser) => browser.browser === "chromedriver");
|
|
131693
|
-
const appiumChromium = appiumDriverOutput.match(/\n.*chromium.*installed \(npm\).*\n/);
|
|
131694
|
-
if (chrome && chromedriver && appiumChromium) {
|
|
131695
|
-
apps.push({
|
|
131696
|
-
name: "chrome",
|
|
131697
|
-
version: chromeVersion,
|
|
131698
|
-
path: chrome.executablePath,
|
|
131699
|
-
driver: chromedriver.executablePath
|
|
131700
|
-
});
|
|
131701
|
-
}
|
|
131702
|
-
const firefox = installedBrowsers.find((browser) => browser.browser === "firefox");
|
|
131703
|
-
const appiumFirefox = appiumDriverOutput.match(/\n.*gecko.*installed \(npm\).*\n/);
|
|
131704
|
-
if (firefox && appiumFirefox) {
|
|
131705
|
-
apps.push({
|
|
131706
|
-
name: "firefox",
|
|
131707
|
-
version: firefox.buildId,
|
|
131708
|
-
path: firefox.executablePath
|
|
131709
|
-
});
|
|
131710
|
-
}
|
|
131711
|
-
if (config.environment.platform === "mac") {
|
|
131712
|
-
const safariVersion = await spawnCommand("defaults read /Applications/Safari.app/Contents/Info.plist CFBundleShortVersionString");
|
|
131713
|
-
const appiumSafari = appiumDriverOutput.match(/\n.*safari.*installed \(npm\).*\n/);
|
|
131714
|
-
if (safariVersion.exitCode === 0 && appiumSafari) {
|
|
131715
|
-
apps.push({ name: "safari", version: safariVersion.stdout.trim(), path: "" });
|
|
131716
|
-
}
|
|
131717
|
-
}
|
|
131705
|
+
appiumDriverOutput = installedAppiumDrivers.stdout + "\n" + installedAppiumDrivers.stderr;
|
|
131718
131706
|
} finally {
|
|
131719
131707
|
process.chdir(cwd);
|
|
131720
131708
|
}
|
|
131709
|
+
return { installedBrowsers, appiumDriverOutput, browserDetectionFailed };
|
|
131710
|
+
}
|
|
131711
|
+
async function getAvailableApps({ config }) {
|
|
131712
|
+
const browsersDir = getBrowsersDir({ cacheDir: config?.cacheDir });
|
|
131713
|
+
const key = browsersDir;
|
|
131714
|
+
const hit = cachedAppsByDir.get(key);
|
|
131715
|
+
if (hit)
|
|
131716
|
+
return hit;
|
|
131717
|
+
const { installedBrowsers, appiumDriverOutput, browserDetectionFailed } = await probeBrowserEnvironment({ config, browsersDir });
|
|
131718
|
+
const apps = [];
|
|
131719
|
+
const chrome = installedBrowsers.find((browser) => browser.browser === "chrome");
|
|
131720
|
+
const chromeVersion = chrome?.buildId;
|
|
131721
|
+
const chromedriver = installedBrowsers.find((browser) => browser.browser === "chromedriver");
|
|
131722
|
+
const appiumChromium = appiumDriverOutput.match(/\n.*chromium.*installed \(npm\).*\n/);
|
|
131723
|
+
if (chrome && chromedriver && appiumChromium) {
|
|
131724
|
+
apps.push({
|
|
131725
|
+
name: "chrome",
|
|
131726
|
+
version: chromeVersion,
|
|
131727
|
+
path: chrome.executablePath,
|
|
131728
|
+
driver: chromedriver.executablePath
|
|
131729
|
+
});
|
|
131730
|
+
}
|
|
131731
|
+
const firefox = installedBrowsers.find((browser) => browser.browser === "firefox");
|
|
131732
|
+
const appiumFirefox = appiumDriverOutput.match(/\n.*gecko.*installed \(npm\).*\n/);
|
|
131733
|
+
if (firefox && appiumFirefox) {
|
|
131734
|
+
apps.push({
|
|
131735
|
+
name: "firefox",
|
|
131736
|
+
version: firefox.buildId,
|
|
131737
|
+
path: firefox.executablePath
|
|
131738
|
+
});
|
|
131739
|
+
}
|
|
131740
|
+
if (config.environment.platform === "mac") {
|
|
131741
|
+
const safariVersion = await spawnCommand("defaults read /Applications/Safari.app/Contents/Info.plist CFBundleShortVersionString");
|
|
131742
|
+
const appiumSafari = appiumDriverOutput.match(/\n.*safari.*installed \(npm\).*\n/);
|
|
131743
|
+
if (safariVersion.exitCode === 0 && appiumSafari) {
|
|
131744
|
+
apps.push({ name: "safari", version: safariVersion.stdout.trim(), path: "" });
|
|
131745
|
+
}
|
|
131746
|
+
}
|
|
131721
131747
|
if (!browserDetectionFailed)
|
|
131722
131748
|
cachedAppsByDir.set(key, apps);
|
|
131723
131749
|
return apps;
|
|
131724
131750
|
}
|
|
131725
|
-
|
|
131751
|
+
function probeSafariVersion(timeoutMs) {
|
|
131752
|
+
return new Promise((resolve) => {
|
|
131753
|
+
let child;
|
|
131754
|
+
try {
|
|
131755
|
+
child = (0, import_node_child_process3.spawn)("defaults", [
|
|
131756
|
+
"read",
|
|
131757
|
+
"/Applications/Safari.app/Contents/Info.plist",
|
|
131758
|
+
"CFBundleShortVersionString"
|
|
131759
|
+
], { stdio: ["ignore", "pipe", "ignore"] });
|
|
131760
|
+
} catch {
|
|
131761
|
+
resolve(null);
|
|
131762
|
+
return;
|
|
131763
|
+
}
|
|
131764
|
+
let stdout = "";
|
|
131765
|
+
let settled = false;
|
|
131766
|
+
const finish = (value) => {
|
|
131767
|
+
if (settled)
|
|
131768
|
+
return;
|
|
131769
|
+
settled = true;
|
|
131770
|
+
clearTimeout(timer);
|
|
131771
|
+
try {
|
|
131772
|
+
child.kill();
|
|
131773
|
+
} catch {
|
|
131774
|
+
}
|
|
131775
|
+
resolve(value);
|
|
131776
|
+
};
|
|
131777
|
+
const timer = setTimeout(() => finish(null), timeoutMs);
|
|
131778
|
+
timer.unref?.();
|
|
131779
|
+
child.stdout?.on("data", (c) => {
|
|
131780
|
+
stdout += typeof c === "string" ? c : c.toString("utf8");
|
|
131781
|
+
});
|
|
131782
|
+
child.on("error", () => finish(null));
|
|
131783
|
+
child.on("close", (code) => finish(code === 0 ? stdout.trim() : null));
|
|
131784
|
+
});
|
|
131785
|
+
}
|
|
131786
|
+
async function getBrowserDiagnostics({ config }) {
|
|
131787
|
+
let detectionFailed = false;
|
|
131788
|
+
let record;
|
|
131789
|
+
try {
|
|
131790
|
+
record = readInstalledRecord({ cacheDir: config?.cacheDir });
|
|
131791
|
+
} catch {
|
|
131792
|
+
detectionFailed = true;
|
|
131793
|
+
record = { npmPackages: {}, browsers: {} };
|
|
131794
|
+
}
|
|
131795
|
+
const browsersRec = record.browsers || {};
|
|
131796
|
+
const platform = config?.environment?.platform;
|
|
131797
|
+
const brow = (name) => browsersRec[name];
|
|
131798
|
+
const npmInstalled = (name) => Boolean(resolveHeavyDepPath(name, { cacheDir: config?.cacheDir }));
|
|
131799
|
+
const browsers = [];
|
|
131800
|
+
const chrome = brow("chrome");
|
|
131801
|
+
const chromedriver = brow("chromedriver");
|
|
131802
|
+
const appiumChromium = npmInstalled("appium-chromium-driver");
|
|
131803
|
+
browsers.push({
|
|
131804
|
+
name: "chrome",
|
|
131805
|
+
supported: true,
|
|
131806
|
+
available: Boolean(chrome && chromedriver && appiumChromium),
|
|
131807
|
+
components: [
|
|
131808
|
+
{ label: "chrome browser", installed: Boolean(chrome), detail: chrome?.installedVersion },
|
|
131809
|
+
{ label: "chromedriver", installed: Boolean(chromedriver), detail: chromedriver?.installedVersion },
|
|
131810
|
+
{ label: "appium-chromium-driver", installed: appiumChromium }
|
|
131811
|
+
]
|
|
131812
|
+
});
|
|
131813
|
+
const firefox = brow("firefox");
|
|
131814
|
+
const geckodriver = brow("geckodriver");
|
|
131815
|
+
const appiumGecko = npmInstalled("appium-geckodriver");
|
|
131816
|
+
browsers.push({
|
|
131817
|
+
name: "firefox",
|
|
131818
|
+
supported: true,
|
|
131819
|
+
available: Boolean(firefox && geckodriver && appiumGecko),
|
|
131820
|
+
components: [
|
|
131821
|
+
{ label: "firefox browser", installed: Boolean(firefox), detail: firefox?.installedVersion },
|
|
131822
|
+
{ label: "geckodriver", installed: Boolean(geckodriver), detail: geckodriver?.installedVersion },
|
|
131823
|
+
{ label: "appium-geckodriver", installed: appiumGecko }
|
|
131824
|
+
]
|
|
131825
|
+
});
|
|
131826
|
+
const isMac = platform === "mac";
|
|
131827
|
+
const appiumSafari = npmInstalled("appium-safari-driver");
|
|
131828
|
+
let safariApp = false;
|
|
131829
|
+
let safariVersion;
|
|
131830
|
+
let safaridriver = false;
|
|
131831
|
+
if (isMac) {
|
|
131832
|
+
try {
|
|
131833
|
+
const version = await probeSafariVersion(4e3);
|
|
131834
|
+
safariApp = version !== null;
|
|
131835
|
+
safariVersion = version ?? void 0;
|
|
131836
|
+
safaridriver = import_node_fs7.default.existsSync("/usr/bin/safaridriver");
|
|
131837
|
+
} catch {
|
|
131838
|
+
detectionFailed = true;
|
|
131839
|
+
}
|
|
131840
|
+
}
|
|
131841
|
+
browsers.push({
|
|
131842
|
+
name: "safari",
|
|
131843
|
+
supported: isMac,
|
|
131844
|
+
available: Boolean(isMac && safariApp && safaridriver && appiumSafari),
|
|
131845
|
+
components: [
|
|
131846
|
+
{ label: "Safari app", installed: safariApp, detail: safariVersion },
|
|
131847
|
+
{
|
|
131848
|
+
label: "safaridriver",
|
|
131849
|
+
installed: safaridriver,
|
|
131850
|
+
detail: safaridriver ? "/usr/bin/safaridriver" : void 0
|
|
131851
|
+
},
|
|
131852
|
+
{ label: "appium-safari-driver", installed: appiumSafari }
|
|
131853
|
+
],
|
|
131854
|
+
note: isMac ? void 0 : "Safari is only available on macOS"
|
|
131855
|
+
});
|
|
131856
|
+
return { browsers, detectionFailed };
|
|
131857
|
+
}
|
|
131858
|
+
var import_node_os3, import_node_fs7, import_node_path7, import_node_child_process3, import_node_url5, __dirname4, platformMap, defaultFileTypes, cachedAppsByDir;
|
|
131726
131859
|
var init_config = __esm({
|
|
131727
131860
|
"dist/core/config.js"() {
|
|
131728
131861
|
"use strict";
|
|
131729
131862
|
import_node_os3 = __toESM(require("node:os"), 1);
|
|
131863
|
+
import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
131730
131864
|
init_validate();
|
|
131731
131865
|
init_utils();
|
|
131732
131866
|
import_node_path7 = __toESM(require("node:path"), 1);
|
|
@@ -132020,8 +132154,19 @@ var browsers_exports = {};
|
|
|
132020
132154
|
__export(browsers_exports, {
|
|
132021
132155
|
BROWSER_CHANNELS: () => BROWSER_CHANNELS,
|
|
132022
132156
|
ensureBrowserInstalled: () => ensureBrowserInstalled,
|
|
132023
|
-
getInstalledBrowsers: () => getInstalledBrowsers
|
|
132157
|
+
getInstalledBrowsers: () => getInstalledBrowsers,
|
|
132158
|
+
requiredBrowserAssets: () => requiredBrowserAssets
|
|
132024
132159
|
});
|
|
132160
|
+
function requiredBrowserAssets(name) {
|
|
132161
|
+
switch ((name ?? "").toLowerCase()) {
|
|
132162
|
+
case "chrome":
|
|
132163
|
+
return ["chrome", "chromedriver"];
|
|
132164
|
+
case "firefox":
|
|
132165
|
+
return ["firefox", "geckodriver"];
|
|
132166
|
+
default:
|
|
132167
|
+
return [];
|
|
132168
|
+
}
|
|
132169
|
+
}
|
|
132025
132170
|
async function loadPuppeteerBrowsers(deps, ctx) {
|
|
132026
132171
|
if (deps.browsersModule)
|
|
132027
132172
|
return deps.browsersModule;
|
|
@@ -132399,7 +132544,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
132399
132544
|
init_config();
|
|
132400
132545
|
|
|
132401
132546
|
// dist/core/detectTests.js
|
|
132402
|
-
var
|
|
132547
|
+
var import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
132403
132548
|
var import_node_path9 = __toESM(require("node:path"), 1);
|
|
132404
132549
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
132405
132550
|
var import_node_crypto3 = __toESM(require("node:crypto"), 1);
|
|
@@ -133231,7 +133376,7 @@ init_files();
|
|
|
133231
133376
|
init_utils();
|
|
133232
133377
|
|
|
133233
133378
|
// dist/core/integrations/heretto.js
|
|
133234
|
-
var
|
|
133379
|
+
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
133235
133380
|
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
133236
133381
|
var import_node_https = __toESM(require("node:https"), 1);
|
|
133237
133382
|
var import_node_http = __toESM(require("node:http"), 1);
|
|
@@ -133392,11 +133537,11 @@ var HerettoUploader = class {
|
|
|
133392
133537
|
return result;
|
|
133393
133538
|
}
|
|
133394
133539
|
}
|
|
133395
|
-
if (!
|
|
133540
|
+
if (!import_node_fs8.default.existsSync(localFilePath)) {
|
|
133396
133541
|
result.description = `Local file not found: ${localFilePath}`;
|
|
133397
133542
|
return result;
|
|
133398
133543
|
}
|
|
133399
|
-
const fileContent =
|
|
133544
|
+
const fileContent = import_node_fs8.default.readFileSync(localFilePath);
|
|
133400
133545
|
const contentType = this.getContentType(localFilePath);
|
|
133401
133546
|
try {
|
|
133402
133547
|
await this.uploadFile({
|
|
@@ -134170,7 +134315,7 @@ async function pollJobStatus(client, fileId, jobId, log3, config) {
|
|
|
134170
134315
|
return null;
|
|
134171
134316
|
}
|
|
134172
134317
|
async function downloadAndExtractOutput(client, fileId, jobId, herettoName, log3, config, deps) {
|
|
134173
|
-
const fsModule = deps?.fsModule ||
|
|
134318
|
+
const fsModule = deps?.fsModule || import_node_fs8.default;
|
|
134174
134319
|
const ZipClass = deps?.ZipClass || import_adm_zip.default;
|
|
134175
134320
|
const tempDir = import_node_path8.default.join(import_node_os4.default.tmpdir(), "doc-detective");
|
|
134176
134321
|
const hash = import_node_crypto2.default.createHash("md5").update(`${herettoName}_${jobId}`).digest("hex");
|
|
@@ -134408,7 +134553,7 @@ async function isValidSourceFile({ config, files, source }) {
|
|
|
134408
134553
|
} else {
|
|
134409
134554
|
beforePath = import_node_path9.default.resolve(test.before);
|
|
134410
134555
|
}
|
|
134411
|
-
if (!
|
|
134556
|
+
if (!import_node_fs9.default.existsSync(beforePath)) {
|
|
134412
134557
|
log(config, "debug", `${beforePath} is specified to run before a test but isn't a valid file. Skipping ${source}.`);
|
|
134413
134558
|
return false;
|
|
134414
134559
|
}
|
|
@@ -134420,7 +134565,7 @@ async function isValidSourceFile({ config, files, source }) {
|
|
|
134420
134565
|
} else {
|
|
134421
134566
|
afterPath = import_node_path9.default.resolve(test.after);
|
|
134422
134567
|
}
|
|
134423
|
-
if (!
|
|
134568
|
+
if (!import_node_fs9.default.existsSync(afterPath)) {
|
|
134424
134569
|
log(config, "debug", `${afterPath} is specified to run after a test but isn't a valid file. Skipping ${source}.`);
|
|
134425
134570
|
return false;
|
|
134426
134571
|
}
|
|
@@ -134438,9 +134583,9 @@ async function processDitaMap({ config, source }) {
|
|
|
134438
134583
|
const hash = import_node_crypto3.default.createHash("md5").update(source).digest("hex");
|
|
134439
134584
|
const tmpBase = import_node_path9.default.join(import_node_os5.default.tmpdir(), "doc-detective");
|
|
134440
134585
|
const outputDir = import_node_path9.default.join(tmpBase, `ditamap_${hash}`);
|
|
134441
|
-
if (!
|
|
134586
|
+
if (!import_node_fs9.default.existsSync(tmpBase)) {
|
|
134442
134587
|
log(config, "debug", `Creating temp directory: ${tmpBase}`);
|
|
134443
|
-
|
|
134588
|
+
import_node_fs9.default.mkdirSync(tmpBase, { recursive: true });
|
|
134444
134589
|
}
|
|
134445
134590
|
const ditaVersion = await spawnCommand("dita", ["--version"]);
|
|
134446
134591
|
if (ditaVersion.exitCode !== 0) {
|
|
@@ -134542,8 +134687,8 @@ async function qualifyFiles({ config }) {
|
|
|
134542
134687
|
let isFile = false;
|
|
134543
134688
|
let isDir = false;
|
|
134544
134689
|
try {
|
|
134545
|
-
isFile =
|
|
134546
|
-
isDir =
|
|
134690
|
+
isFile = import_node_fs9.default.statSync(source).isFile();
|
|
134691
|
+
isDir = import_node_fs9.default.statSync(source).isDirectory();
|
|
134547
134692
|
} catch {
|
|
134548
134693
|
log(config, "warning", `Cannot access path: ${source}. Skipping.`);
|
|
134549
134694
|
continue;
|
|
@@ -134563,13 +134708,13 @@ async function qualifyFiles({ config }) {
|
|
|
134563
134708
|
dirs = [];
|
|
134564
134709
|
dirs[0] = source;
|
|
134565
134710
|
for (const dir of dirs) {
|
|
134566
|
-
const objects =
|
|
134711
|
+
const objects = import_node_fs9.default.readdirSync(dir);
|
|
134567
134712
|
for (const object of objects) {
|
|
134568
134713
|
const content = import_node_path9.default.resolve(dir + "/" + object);
|
|
134569
134714
|
if (content.includes("node_modules"))
|
|
134570
134715
|
continue;
|
|
134571
|
-
const isFile2 =
|
|
134572
|
-
const isDir2 =
|
|
134716
|
+
const isFile2 = import_node_fs9.default.statSync(content).isFile();
|
|
134717
|
+
const isDir2 = import_node_fs9.default.statSync(content).isDirectory();
|
|
134573
134718
|
if (isFile2 && await isValidSourceFile({ config, files, source: content })) {
|
|
134574
134719
|
files.push(import_node_path9.default.resolve(content));
|
|
134575
134720
|
} else if (isDir2 && config.recursive) {
|
|
@@ -134590,7 +134735,7 @@ async function parseTests({ config, files }) {
|
|
|
134590
134735
|
let rawContent;
|
|
134591
134736
|
if (extension === "json" || extension === "yaml" || extension === "yml") {
|
|
134592
134737
|
try {
|
|
134593
|
-
rawContent = await
|
|
134738
|
+
rawContent = await import_node_fs9.default.promises.readFile(file, "utf8");
|
|
134594
134739
|
if (extension === "json") {
|
|
134595
134740
|
content = JSON.parse(rawContent);
|
|
134596
134741
|
} else {
|
|
@@ -134976,6 +135121,7 @@ init_utils();
|
|
|
134976
135121
|
// dist/core/tests.js
|
|
134977
135122
|
var import_tree_kill = __toESM(require("tree-kill"), 1);
|
|
134978
135123
|
init_loader();
|
|
135124
|
+
init_browsers();
|
|
134979
135125
|
var import_node_os8 = __toESM(require("node:os"), 1);
|
|
134980
135126
|
init_utils();
|
|
134981
135127
|
var import_axios6 = __toESM(require("axios"), 1);
|
|
@@ -136236,7 +136382,7 @@ async function waitForDOMStable(driver, idleTime, timeout) {
|
|
|
136236
136382
|
// dist/core/tests/runShell.js
|
|
136237
136383
|
init_validate();
|
|
136238
136384
|
init_utils();
|
|
136239
|
-
var
|
|
136385
|
+
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
136240
136386
|
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
136241
136387
|
async function runShell({ config, step }) {
|
|
136242
136388
|
const result = {
|
|
@@ -136311,23 +136457,23 @@ async function runShell({ config, step }) {
|
|
|
136311
136457
|
}
|
|
136312
136458
|
if (step.runShell.path) {
|
|
136313
136459
|
const dir = import_node_path10.default.dirname(step.runShell.path);
|
|
136314
|
-
if (!
|
|
136315
|
-
|
|
136460
|
+
if (!import_node_fs10.default.existsSync(dir)) {
|
|
136461
|
+
import_node_fs10.default.mkdirSync(dir, { recursive: true });
|
|
136316
136462
|
}
|
|
136317
136463
|
let filePath = step.runShell.path;
|
|
136318
136464
|
log(config, "debug", `Saving stdio to file: ${filePath}`);
|
|
136319
|
-
if (!
|
|
136320
|
-
|
|
136465
|
+
if (!import_node_fs10.default.existsSync(filePath)) {
|
|
136466
|
+
import_node_fs10.default.writeFileSync(filePath, result.outputs.stdio.stdout);
|
|
136321
136467
|
} else {
|
|
136322
136468
|
if (step.runShell.overwrite == "false") {
|
|
136323
136469
|
result.description = result.description + ` Didn't save output. File already exists.`;
|
|
136324
136470
|
}
|
|
136325
|
-
const existingFile =
|
|
136471
|
+
const existingFile = import_node_fs10.default.readFileSync(filePath, "utf8");
|
|
136326
136472
|
const fractionalDiff = calculateFractionalDifference(existingFile, result.outputs.stdio.stdout);
|
|
136327
136473
|
log(config, "debug", `Fractional difference: ${fractionalDiff}`);
|
|
136328
136474
|
if (fractionalDiff > step.runShell.maxVariation) {
|
|
136329
136475
|
if (step.runShell.overwrite == "aboveVariation") {
|
|
136330
|
-
|
|
136476
|
+
import_node_fs10.default.writeFileSync(filePath, result.outputs.stdio.stdout);
|
|
136331
136477
|
result.description += ` Saved output to file.`;
|
|
136332
136478
|
}
|
|
136333
136479
|
result.status = "WARNING";
|
|
@@ -136335,7 +136481,7 @@ async function runShell({ config, step }) {
|
|
|
136335
136481
|
return result;
|
|
136336
136482
|
}
|
|
136337
136483
|
if (step.runShell.overwrite == "true") {
|
|
136338
|
-
|
|
136484
|
+
import_node_fs10.default.writeFileSync(filePath, result.outputs.stdio.stdout);
|
|
136339
136485
|
result.description += ` Saved output to file.`;
|
|
136340
136486
|
}
|
|
136341
136487
|
}
|
|
@@ -136520,7 +136666,7 @@ async function checkLink({ config, step }) {
|
|
|
136520
136666
|
init_validate();
|
|
136521
136667
|
init_utils();
|
|
136522
136668
|
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
136523
|
-
var
|
|
136669
|
+
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
136524
136670
|
init_loader();
|
|
136525
136671
|
var _pngjs = null;
|
|
136526
136672
|
var _sharp = null;
|
|
@@ -136647,8 +136793,8 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136647
136793
|
const rawBase = import_node_path11.default.basename(urlPathname.split("?")[0].split("#")[0].replace(/\\/g, "/"));
|
|
136648
136794
|
const safeBase = sanitizeFilesystemName(rawBase, `${step.stepId}.png`);
|
|
136649
136795
|
dir = import_node_path11.default.join(process.cwd(), "doc-detective-runs", getOrInitRunTimestamp(config));
|
|
136650
|
-
if (!
|
|
136651
|
-
|
|
136796
|
+
if (!import_node_fs11.default.existsSync(dir)) {
|
|
136797
|
+
import_node_fs11.default.mkdirSync(dir, { recursive: true });
|
|
136652
136798
|
}
|
|
136653
136799
|
const captureId = `${step.stepId || "screenshot"}_${Date.now()}`;
|
|
136654
136800
|
filePath = import_node_path11.default.join(dir, `${captureId}_${safeBase}`);
|
|
@@ -136664,10 +136810,10 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136664
136810
|
}
|
|
136665
136811
|
} else {
|
|
136666
136812
|
dir = import_node_path11.default.dirname(step.screenshot.path);
|
|
136667
|
-
if (!
|
|
136668
|
-
|
|
136813
|
+
if (!import_node_fs11.default.existsSync(dir)) {
|
|
136814
|
+
import_node_fs11.default.mkdirSync(dir, { recursive: true });
|
|
136669
136815
|
}
|
|
136670
|
-
if (
|
|
136816
|
+
if (import_node_fs11.default.existsSync(filePath)) {
|
|
136671
136817
|
if (step.screenshot.overwrite == "false") {
|
|
136672
136818
|
result.status = "SKIPPED";
|
|
136673
136819
|
result.description = `File already exists: ${filePath}`;
|
|
@@ -136763,8 +136909,8 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136763
136909
|
} catch (error) {
|
|
136764
136910
|
result.status = "FAIL";
|
|
136765
136911
|
result.description = `Couldn't save screenshot. ${error}`;
|
|
136766
|
-
if (existFilePath && filePath !== existFilePath &&
|
|
136767
|
-
|
|
136912
|
+
if (existFilePath && filePath !== existFilePath && import_node_fs11.default.existsSync(filePath)) {
|
|
136913
|
+
import_node_fs11.default.unlinkSync(filePath);
|
|
136768
136914
|
}
|
|
136769
136915
|
return result;
|
|
136770
136916
|
}
|
|
@@ -136816,12 +136962,12 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136816
136962
|
width: rect.width,
|
|
136817
136963
|
height: rect.height
|
|
136818
136964
|
}).toFile(croppedPath);
|
|
136819
|
-
|
|
136965
|
+
import_node_fs11.default.renameSync(croppedPath, filePath);
|
|
136820
136966
|
} catch (error) {
|
|
136821
136967
|
result.status = "FAIL";
|
|
136822
136968
|
result.description = `Couldn't crop image. ${error}`;
|
|
136823
|
-
if (existFilePath && filePath !== existFilePath &&
|
|
136824
|
-
|
|
136969
|
+
if (existFilePath && filePath !== existFilePath && import_node_fs11.default.existsSync(filePath)) {
|
|
136970
|
+
import_node_fs11.default.unlinkSync(filePath);
|
|
136825
136971
|
}
|
|
136826
136972
|
return result;
|
|
136827
136973
|
}
|
|
@@ -136829,7 +136975,7 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136829
136975
|
if (existFilePath) {
|
|
136830
136976
|
if (step.screenshot.overwrite == "true" && !isUrlPath) {
|
|
136831
136977
|
result.description += ` Overwrote existing file.`;
|
|
136832
|
-
|
|
136978
|
+
import_node_fs11.default.renameSync(filePath, existFilePath);
|
|
136833
136979
|
result.outputs.screenshotPath = existFilePath;
|
|
136834
136980
|
result.outputs.changed = true;
|
|
136835
136981
|
if (step.screenshot.sourceIntegration) {
|
|
@@ -136842,21 +136988,21 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136842
136988
|
let img1;
|
|
136843
136989
|
let img2;
|
|
136844
136990
|
try {
|
|
136845
|
-
img1 = PNG.sync.read(
|
|
136846
|
-
img2 = PNG.sync.read(
|
|
136991
|
+
img1 = PNG.sync.read(import_node_fs11.default.readFileSync(existFilePath));
|
|
136992
|
+
img2 = PNG.sync.read(import_node_fs11.default.readFileSync(filePath));
|
|
136847
136993
|
} catch (error) {
|
|
136848
136994
|
result.status = "FAIL";
|
|
136849
136995
|
result.description = isUrlPath ? `Couldn't decode PNG for comparison. The URL reference (${redactedUrl}) may not be a valid PNG. ${error}` : `Couldn't decode PNG for comparison. ${error}`;
|
|
136850
|
-
if (!isUrlPath && filePath !== existFilePath &&
|
|
136851
|
-
|
|
136996
|
+
if (!isUrlPath && filePath !== existFilePath && import_node_fs11.default.existsSync(filePath)) {
|
|
136997
|
+
import_node_fs11.default.unlinkSync(filePath);
|
|
136852
136998
|
}
|
|
136853
136999
|
return result;
|
|
136854
137000
|
}
|
|
136855
137001
|
if (!aspectRatiosMatch(img1, img2)) {
|
|
136856
137002
|
result.status = "FAIL";
|
|
136857
137003
|
result.description = `Couldn't compare images. Images have different aspect ratios.`;
|
|
136858
|
-
if (!isUrlPath && filePath !== existFilePath &&
|
|
136859
|
-
|
|
137004
|
+
if (!isUrlPath && filePath !== existFilePath && import_node_fs11.default.existsSync(filePath)) {
|
|
137005
|
+
import_node_fs11.default.unlinkSync(filePath);
|
|
136860
137006
|
}
|
|
136861
137007
|
return result;
|
|
136862
137008
|
}
|
|
@@ -136883,8 +137029,8 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136883
137029
|
} catch (error) {
|
|
136884
137030
|
result.status = "FAIL";
|
|
136885
137031
|
result.description = `Couldn't load screenshot comparison dependency (pixelmatch). ${error?.message ?? error}`;
|
|
136886
|
-
if (!isUrlPath && filePath !== existFilePath &&
|
|
136887
|
-
|
|
137032
|
+
if (!isUrlPath && filePath !== existFilePath && import_node_fs11.default.existsSync(filePath)) {
|
|
137033
|
+
import_node_fs11.default.unlinkSync(filePath);
|
|
136888
137034
|
}
|
|
136889
137035
|
return result;
|
|
136890
137036
|
}
|
|
@@ -136897,7 +137043,7 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136897
137043
|
});
|
|
136898
137044
|
if (fractionalDiff > step.screenshot.maxVariation) {
|
|
136899
137045
|
if (step.screenshot.overwrite == "aboveVariation" && !isUrlPath) {
|
|
136900
|
-
|
|
137046
|
+
import_node_fs11.default.renameSync(filePath, existFilePath);
|
|
136901
137047
|
}
|
|
136902
137048
|
result.status = "WARNING";
|
|
136903
137049
|
result.description += ` The difference between the existing screenshot and new screenshot (${fractionalDiff.toFixed(2)}) is greater than the max accepted variation (${step.screenshot.maxVariation}).`;
|
|
@@ -136923,7 +137069,7 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136923
137069
|
result.outputs.sourceIntegration = step.screenshot.sourceIntegration;
|
|
136924
137070
|
}
|
|
136925
137071
|
if (step.screenshot.overwrite != "true") {
|
|
136926
|
-
|
|
137072
|
+
import_node_fs11.default.unlinkSync(filePath);
|
|
136927
137073
|
}
|
|
136928
137074
|
}
|
|
136929
137075
|
}
|
|
@@ -136943,7 +137089,7 @@ async function saveScreenshot({ config, step, driver }) {
|
|
|
136943
137089
|
init_validate();
|
|
136944
137090
|
init_utils();
|
|
136945
137091
|
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
136946
|
-
var
|
|
137092
|
+
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
136947
137093
|
var import_node_os6 = __toESM(require("node:os"), 1);
|
|
136948
137094
|
async function startRecording({ config, context, step, driver }) {
|
|
136949
137095
|
let result = {
|
|
@@ -136981,10 +137127,10 @@ async function startRecording({ config, context, step, driver }) {
|
|
|
136981
137127
|
let filePath = step.record.path;
|
|
136982
137128
|
const baseName = import_node_path12.default.basename(filePath, import_node_path12.default.extname(filePath));
|
|
136983
137129
|
const dir = import_node_path12.default.dirname(step.record.path);
|
|
136984
|
-
if (!
|
|
136985
|
-
|
|
137130
|
+
if (!import_node_fs12.default.existsSync(dir)) {
|
|
137131
|
+
import_node_fs12.default.mkdirSync(dir, { recursive: true });
|
|
136986
137132
|
}
|
|
136987
|
-
if (
|
|
137133
|
+
if (import_node_fs12.default.existsSync(filePath) && step.record.overwrite == "false") {
|
|
136988
137134
|
result.status = "SKIPPED";
|
|
136989
137135
|
result.description = `File already exists: ${filePath}`;
|
|
136990
137136
|
return result;
|
|
@@ -137108,7 +137254,7 @@ init_validate();
|
|
|
137108
137254
|
init_utils();
|
|
137109
137255
|
var import_node_child_process4 = require("node:child_process");
|
|
137110
137256
|
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
137111
|
-
var
|
|
137257
|
+
var import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
137112
137258
|
init_loader();
|
|
137113
137259
|
async function getFfmpegPath(ctx = {}) {
|
|
137114
137260
|
const mod = await loadHeavyDep("@ffmpeg-installer/ffmpeg", { ctx });
|
|
@@ -137157,11 +137303,11 @@ async function stopRecording({ config, step, driver }) {
|
|
|
137157
137303
|
window.recorder.stop();
|
|
137158
137304
|
});
|
|
137159
137305
|
let waitCount = 0;
|
|
137160
|
-
while (!
|
|
137306
|
+
while (!import_node_fs13.default.existsSync(config.recording.downloadPath) && waitCount < 60) {
|
|
137161
137307
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
137162
137308
|
waitCount++;
|
|
137163
137309
|
}
|
|
137164
|
-
if (!
|
|
137310
|
+
if (!import_node_fs13.default.existsSync(config.recording.downloadPath)) {
|
|
137165
137311
|
result.status = "FAIL";
|
|
137166
137312
|
result.description = "Recording download timed out.";
|
|
137167
137313
|
return result;
|
|
@@ -137186,7 +137332,7 @@ async function stopRecording({ config, step, driver }) {
|
|
|
137186
137332
|
if (code === 0) {
|
|
137187
137333
|
if (targetPath !== downloadPath) {
|
|
137188
137334
|
try {
|
|
137189
|
-
|
|
137335
|
+
import_node_fs13.default.unlinkSync(downloadPath);
|
|
137190
137336
|
} catch {
|
|
137191
137337
|
}
|
|
137192
137338
|
}
|
|
@@ -137232,7 +137378,7 @@ async function loadVariables({ step }) {
|
|
|
137232
137378
|
init_validate();
|
|
137233
137379
|
init_utils();
|
|
137234
137380
|
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
137235
|
-
var
|
|
137381
|
+
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
137236
137382
|
async function saveCookie({ config, step, driver }) {
|
|
137237
137383
|
let result = {
|
|
137238
137384
|
status: "PASS",
|
|
@@ -137299,14 +137445,14 @@ async function saveCookie({ config, step, driver }) {
|
|
|
137299
137445
|
if (filePath) {
|
|
137300
137446
|
const outputDirectory = directory || config.output || process.cwd();
|
|
137301
137447
|
const fullPath = import_node_path14.default.resolve(outputDirectory, filePath);
|
|
137302
|
-
if (
|
|
137448
|
+
if (import_node_fs14.default.existsSync(fullPath) && !(overwrite === true || overwrite === "true")) {
|
|
137303
137449
|
result.status = "FAIL";
|
|
137304
137450
|
result.description = `File '${fullPath}' already exists and overwrite is not enabled.`;
|
|
137305
137451
|
return result;
|
|
137306
137452
|
}
|
|
137307
137453
|
const dir = import_node_path14.default.dirname(fullPath);
|
|
137308
|
-
if (!
|
|
137309
|
-
|
|
137454
|
+
if (!import_node_fs14.default.existsSync(dir)) {
|
|
137455
|
+
import_node_fs14.default.mkdirSync(dir, { recursive: true });
|
|
137310
137456
|
}
|
|
137311
137457
|
if (targetCookie) {
|
|
137312
137458
|
const netscapeCookie = formatCookieForNetscape(targetCookie);
|
|
@@ -137314,11 +137460,11 @@ async function saveCookie({ config, step, driver }) {
|
|
|
137314
137460
|
# This is a cookie file saved by Doc Detective
|
|
137315
137461
|
${netscapeCookie}
|
|
137316
137462
|
`;
|
|
137317
|
-
|
|
137463
|
+
import_node_fs14.default.writeFileSync(fullPath, content, "utf8");
|
|
137318
137464
|
result.description = `Saved cookie '${cookieName}' to '${fullPath}'.`;
|
|
137319
137465
|
log(config, "debug", `Saved cookie '${cookieName}' to file: ${fullPath}`);
|
|
137320
137466
|
} else {
|
|
137321
|
-
|
|
137467
|
+
import_node_fs14.default.writeFileSync(fullPath, "# No cookie data\n", "utf8");
|
|
137322
137468
|
result.description = `Created empty cookie file at '${fullPath}'.`;
|
|
137323
137469
|
log(config, "debug", `Created empty cookie file: ${fullPath}`);
|
|
137324
137470
|
}
|
|
@@ -137346,7 +137492,7 @@ function formatCookieForNetscape(cookie) {
|
|
|
137346
137492
|
init_validate();
|
|
137347
137493
|
init_utils();
|
|
137348
137494
|
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
137349
|
-
var
|
|
137495
|
+
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
137350
137496
|
async function loadCookie({ config, step, driver }) {
|
|
137351
137497
|
let result = {
|
|
137352
137498
|
status: "PASS",
|
|
@@ -137402,13 +137548,13 @@ async function loadCookie({ config, step, driver }) {
|
|
|
137402
137548
|
} else if (filePath) {
|
|
137403
137549
|
const inputDirectory = directory || config.output || process.cwd();
|
|
137404
137550
|
const fullPath = import_node_path15.default.resolve(inputDirectory, filePath);
|
|
137405
|
-
if (!
|
|
137551
|
+
if (!import_node_fs15.default.existsSync(fullPath)) {
|
|
137406
137552
|
result.status = "FAIL";
|
|
137407
137553
|
result.description = `Cookie file '${fullPath}' not found`;
|
|
137408
137554
|
return result;
|
|
137409
137555
|
}
|
|
137410
137556
|
try {
|
|
137411
|
-
const fileContent =
|
|
137557
|
+
const fileContent = import_node_fs15.default.readFileSync(fullPath, "utf8");
|
|
137412
137558
|
const cookies = parseNetscapeCookieFile(fileContent);
|
|
137413
137559
|
if (cookies.length === 0) {
|
|
137414
137560
|
result.status = "FAIL";
|
|
@@ -137574,7 +137720,7 @@ function isDomainCompatible(currentDomain, cookieDomain) {
|
|
|
137574
137720
|
// dist/core/tests/httpRequest.js
|
|
137575
137721
|
init_validate();
|
|
137576
137722
|
var import_axios5 = __toESM(require("axios"), 1);
|
|
137577
|
-
var
|
|
137723
|
+
var import_node_fs16 = __toESM(require("node:fs"), 1);
|
|
137578
137724
|
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
137579
137725
|
var import_ajv2 = __toESM(require("ajv"), 1);
|
|
137580
137726
|
init_openapi();
|
|
@@ -137881,24 +138027,24 @@ async function httpRequest({ config, step, openApiDefinitions = [] }) {
|
|
|
137881
138027
|
}
|
|
137882
138028
|
if (step.httpRequest.path) {
|
|
137883
138029
|
const dir = import_node_path16.default.dirname(step.httpRequest.path);
|
|
137884
|
-
if (!
|
|
137885
|
-
|
|
138030
|
+
if (!import_node_fs16.default.existsSync(dir)) {
|
|
138031
|
+
import_node_fs16.default.mkdirSync(dir, { recursive: true });
|
|
137886
138032
|
}
|
|
137887
138033
|
let filePath = step.httpRequest.path;
|
|
137888
138034
|
log(config, "debug", `Saving output to file: ${filePath}`);
|
|
137889
|
-
if (!
|
|
137890
|
-
await
|
|
138035
|
+
if (!import_node_fs16.default.existsSync(filePath)) {
|
|
138036
|
+
await import_node_fs16.default.promises.writeFile(filePath, JSON.stringify(response.data, null, 2));
|
|
137891
138037
|
result.description += ` Saved output to file.`;
|
|
137892
138038
|
} else {
|
|
137893
138039
|
if (step.httpRequest.overwrite == "false") {
|
|
137894
138040
|
result.description += ` Didn't save output. File already exists.`;
|
|
137895
138041
|
}
|
|
137896
|
-
const existingFile =
|
|
138042
|
+
const existingFile = import_node_fs16.default.readFileSync(filePath, "utf8");
|
|
137897
138043
|
const fractionalDiff = calculateFractionalDifference(existingFile, JSON.stringify(response.data, null, 2));
|
|
137898
138044
|
log(config, "debug", `Fractional difference: ${fractionalDiff}`);
|
|
137899
138045
|
if (fractionalDiff > step.httpRequest.maxVariation) {
|
|
137900
138046
|
if (step.httpRequest.overwrite == "aboveVariation") {
|
|
137901
|
-
await
|
|
138047
|
+
await import_node_fs16.default.promises.writeFile(filePath, JSON.stringify(response.data, null, 2));
|
|
137902
138048
|
result.description += ` Saved response to file.`;
|
|
137903
138049
|
}
|
|
137904
138050
|
result.status = "WARNING";
|
|
@@ -137906,7 +138052,7 @@ async function httpRequest({ config, step, openApiDefinitions = [] }) {
|
|
|
137906
138052
|
return result;
|
|
137907
138053
|
}
|
|
137908
138054
|
if (step.httpRequest.overwrite == "true") {
|
|
137909
|
-
|
|
138055
|
+
import_node_fs16.default.writeFileSync(filePath, JSON.stringify(response.data, null, 2));
|
|
137910
138056
|
result.description += ` Saved response to file.`;
|
|
137911
138057
|
}
|
|
137912
138058
|
}
|
|
@@ -138083,7 +138229,7 @@ async function clickElement({ config, step, driver }) {
|
|
|
138083
138229
|
// dist/core/tests/runCode.js
|
|
138084
138230
|
init_validate();
|
|
138085
138231
|
init_utils();
|
|
138086
|
-
var
|
|
138232
|
+
var import_node_fs17 = __toESM(require("node:fs"), 1);
|
|
138087
138233
|
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
138088
138234
|
var import_node_os7 = __toESM(require("node:os"), 1);
|
|
138089
138235
|
function createTempScript(code, language) {
|
|
@@ -138107,7 +138253,7 @@ function createTempScript(code, language) {
|
|
|
138107
138253
|
const tmpDir = import_node_os7.default.tmpdir();
|
|
138108
138254
|
const tmpFile = import_node_path17.default.join(tmpDir, `doc-detective-${Date.now()}${extension}`);
|
|
138109
138255
|
try {
|
|
138110
|
-
|
|
138256
|
+
import_node_fs17.default.writeFileSync(tmpFile, code);
|
|
138111
138257
|
} catch (error) {
|
|
138112
138258
|
throw new Error(`Failed to create temporary script: ${error.message}`);
|
|
138113
138259
|
}
|
|
@@ -138191,7 +138337,7 @@ async function runCode({ config, step }) {
|
|
|
138191
138337
|
result.description = error.message;
|
|
138192
138338
|
} finally {
|
|
138193
138339
|
try {
|
|
138194
|
-
|
|
138340
|
+
import_node_fs17.default.unlinkSync(scriptPath);
|
|
138195
138341
|
log(config, "debug", `Removed temporary script: ${scriptPath}`);
|
|
138196
138342
|
} catch (error) {
|
|
138197
138343
|
log(config, "warn", `Failed to remove temporary script: ${scriptPath}`);
|
|
@@ -138739,6 +138885,14 @@ var driverActions2 = [
|
|
|
138739
138885
|
"type"
|
|
138740
138886
|
];
|
|
138741
138887
|
var KNOWN_BROWSERS = ["firefox", "chrome", "safari", "webkit"];
|
|
138888
|
+
function combinationKey(context) {
|
|
138889
|
+
const rawName = context?.browser?.name;
|
|
138890
|
+
const name = rawName === "webkit" ? "safari" : rawName || "<none>";
|
|
138891
|
+
return `${context?.platform}::${name}`;
|
|
138892
|
+
}
|
|
138893
|
+
function warmUpDecision(prev) {
|
|
138894
|
+
return prev === "failed" ? "skip" : "attempt";
|
|
138895
|
+
}
|
|
138742
138896
|
function getDriverCapabilities({ runnerDetails, name, options }) {
|
|
138743
138897
|
let capabilities = {};
|
|
138744
138898
|
let args = [];
|
|
@@ -139017,8 +139171,10 @@ async function runSpecs({ resolvedTests }) {
|
|
|
139017
139171
|
allowUnsafeSteps: await allowUnsafeSteps({ config })
|
|
139018
139172
|
};
|
|
139019
139173
|
const platform = runnerDetails.environment.platform;
|
|
139020
|
-
|
|
139174
|
+
let availableApps = runnerDetails.availableApps;
|
|
139021
139175
|
const metaValues = { specs: {} };
|
|
139176
|
+
const installAttempts = /* @__PURE__ */ new Map();
|
|
139177
|
+
const warmUpResults = /* @__PURE__ */ new Map();
|
|
139022
139178
|
let appium;
|
|
139023
139179
|
const report = {
|
|
139024
139180
|
summary: {
|
|
@@ -139133,14 +139289,46 @@ async function runSpecs({ resolvedTests }) {
|
|
|
139133
139289
|
testReport.contexts.push(contextReport);
|
|
139134
139290
|
continue;
|
|
139135
139291
|
}
|
|
139136
|
-
|
|
139292
|
+
let supportedContext = isSupportedContext({
|
|
139137
139293
|
context,
|
|
139138
139294
|
apps: availableApps,
|
|
139139
139295
|
platform
|
|
139140
139296
|
});
|
|
139297
|
+
let freshInstallRedetected = false;
|
|
139298
|
+
if (!supportedContext && context.platform === platform && // Mirror isSupportedContext's own guard: isDriverRequired iterates
|
|
139299
|
+
// context.steps, so a malformed context without a steps array would
|
|
139300
|
+
// otherwise crash the loop here instead of skipping cleanly.
|
|
139301
|
+
Array.isArray(context?.steps) && isDriverRequired({ test: context }) && requiredBrowserAssets(context.browser?.name).length > 0) {
|
|
139302
|
+
const firstAttempt = !installAttempts.has((context.browser?.name ?? "<none>").toLowerCase());
|
|
139303
|
+
const outcome = await ensureContextBrowserInstalled({
|
|
139304
|
+
browserName: context.browser?.name,
|
|
139305
|
+
config,
|
|
139306
|
+
installAttempts,
|
|
139307
|
+
deps: {
|
|
139308
|
+
ensureBrowser: (asset, options) => ensureBrowserInstalled(asset, options),
|
|
139309
|
+
log
|
|
139310
|
+
}
|
|
139311
|
+
});
|
|
139312
|
+
if (firstAttempt && (outcome === "installed" || outcome === "failed")) {
|
|
139313
|
+
freshInstallRedetected = true;
|
|
139314
|
+
clearAppCache(config);
|
|
139315
|
+
availableApps = await getAvailableApps({ config });
|
|
139316
|
+
runnerDetails.availableApps = availableApps;
|
|
139317
|
+
supportedContext = isSupportedContext({
|
|
139318
|
+
context,
|
|
139319
|
+
apps: availableApps,
|
|
139320
|
+
platform
|
|
139321
|
+
});
|
|
139322
|
+
}
|
|
139323
|
+
}
|
|
139141
139324
|
if (!supportedContext) {
|
|
139142
|
-
|
|
139143
|
-
|
|
139325
|
+
const errorMessage = freshInstallRedetected ? `Skipping context '${context.browser?.name}' on '${context.platform}': the missing browser dependency was installed but still could not be detected.` : `Skipping context. The current system doesn't support this context: {"platform": "${context.platform}", "apps": ${JSON.stringify(context.apps)}}`;
|
|
139326
|
+
log(config, freshInstallRedetected ? "warning" : "info", errorMessage);
|
|
139327
|
+
contextReport = {
|
|
139328
|
+
...contextReport,
|
|
139329
|
+
result: "SKIPPED",
|
|
139330
|
+
resultDescription: errorMessage
|
|
139331
|
+
};
|
|
139144
139332
|
report.summary.contexts.skipped++;
|
|
139145
139333
|
testReport.contexts.push(contextReport);
|
|
139146
139334
|
continue;
|
|
@@ -139153,6 +139341,19 @@ ${JSON.stringify(context, null, 2)}`);
|
|
|
139153
139341
|
}
|
|
139154
139342
|
const driverRequired = isDriverRequired({ test: context });
|
|
139155
139343
|
if (driverRequired) {
|
|
139344
|
+
const combo = combinationKey(context);
|
|
139345
|
+
if (warmUpDecision(warmUpResults.get(combo)) === "skip") {
|
|
139346
|
+
const errorMessage = `Skipping context '${context.browser?.name}' on '${context.platform}': this context combination could not start a driver earlier in this run.`;
|
|
139347
|
+
log(config, "warning", errorMessage);
|
|
139348
|
+
contextReport = {
|
|
139349
|
+
...contextReport,
|
|
139350
|
+
result: "SKIPPED",
|
|
139351
|
+
resultDescription: errorMessage
|
|
139352
|
+
};
|
|
139353
|
+
report.summary.contexts.skipped++;
|
|
139354
|
+
testReport.contexts.push(contextReport);
|
|
139355
|
+
continue;
|
|
139356
|
+
}
|
|
139156
139357
|
let caps = getDriverCapabilities({
|
|
139157
139358
|
runnerDetails,
|
|
139158
139359
|
name: context.browser.name,
|
|
@@ -139185,19 +139386,23 @@ ${JSON.stringify(context, null, 2)}`);
|
|
|
139185
139386
|
driver = await driverStart(caps, appiumPort, 4, { cacheDir: config?.cacheDir });
|
|
139186
139387
|
} catch (error2) {
|
|
139187
139388
|
let errorMessage = `Failed to start context '${context.browser?.name}' on '${platform}'.`;
|
|
139188
|
-
if (context.browser?.name === "safari")
|
|
139389
|
+
if (context.browser?.name === "safari" || context.browser?.name === "webkit")
|
|
139189
139390
|
errorMessage = errorMessage + " Make sure you've run `safaridriver --enable` in a terminal and enabled 'Allow Remote Automation' in Safari's Develop menu.";
|
|
139190
139391
|
log(config, "error", errorMessage);
|
|
139392
|
+
if (!warmUpResults.has(combo))
|
|
139393
|
+
warmUpResults.set(combo, "failed");
|
|
139191
139394
|
contextReport = {
|
|
139395
|
+
...contextReport,
|
|
139192
139396
|
result: "SKIPPED",
|
|
139193
|
-
resultDescription: errorMessage
|
|
139194
|
-
...contextReport
|
|
139397
|
+
resultDescription: errorMessage
|
|
139195
139398
|
};
|
|
139196
139399
|
report.summary.contexts.skipped++;
|
|
139197
139400
|
testReport.contexts.push(contextReport);
|
|
139198
139401
|
continue;
|
|
139199
139402
|
}
|
|
139200
139403
|
}
|
|
139404
|
+
if (!warmUpResults.has(combo))
|
|
139405
|
+
warmUpResults.set(combo, "ok");
|
|
139201
139406
|
if (context.browser?.viewport?.width || context.browser?.viewport?.height) {
|
|
139202
139407
|
await setViewportSize(context, driver);
|
|
139203
139408
|
} else if (context.browser?.window?.width || context.browser?.window?.height) {
|
|
@@ -139533,6 +139738,31 @@ async function ensureChromeAvailable(config, deps) {
|
|
|
139533
139738
|
}
|
|
139534
139739
|
return availableApps;
|
|
139535
139740
|
}
|
|
139741
|
+
async function ensureContextBrowserInstalled({ browserName, config, installAttempts, deps }) {
|
|
139742
|
+
const key = (browserName ?? "<none>").toLowerCase();
|
|
139743
|
+
const cached = installAttempts.get(key);
|
|
139744
|
+
if (cached)
|
|
139745
|
+
return cached;
|
|
139746
|
+
const assets = requiredBrowserAssets(browserName);
|
|
139747
|
+
if (assets.length === 0) {
|
|
139748
|
+
installAttempts.set(key, "notInstallable");
|
|
139749
|
+
return "notInstallable";
|
|
139750
|
+
}
|
|
139751
|
+
const ctx = { cacheDir: config?.cacheDir };
|
|
139752
|
+
const logger = (msg, level = "info") => deps.log?.(config, level === "warn" ? "warning" : level, msg);
|
|
139753
|
+
try {
|
|
139754
|
+
deps.log?.(config, "info", `Browser '${browserName}' is not available; attempting on-demand install of: ${assets.join(", ")}.`);
|
|
139755
|
+
for (const asset of assets) {
|
|
139756
|
+
await deps.ensureBrowser(asset, { ctx, deps: { logger } });
|
|
139757
|
+
}
|
|
139758
|
+
installAttempts.set(key, "installed");
|
|
139759
|
+
return "installed";
|
|
139760
|
+
} catch (err) {
|
|
139761
|
+
deps.log?.(config, "warning", `On-demand install for '${browserName}' failed: ${err?.message ?? err}`);
|
|
139762
|
+
installAttempts.set(key, "failed");
|
|
139763
|
+
return "failed";
|
|
139764
|
+
}
|
|
139765
|
+
}
|
|
139536
139766
|
async function getRunner(options = {}) {
|
|
139537
139767
|
const environment = getEnvironment();
|
|
139538
139768
|
const config = { ...options.config, environment };
|
|
@@ -139746,22 +139976,19 @@ async function runTests(config, options = {}) {
|
|
|
139746
139976
|
if (needs.browsers.size > 0) {
|
|
139747
139977
|
try {
|
|
139748
139978
|
const { getAvailableApps: getAvailableApps2, clearAppCache: clearAppCache2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
139749
|
-
const { ensureBrowserInstalled: ensureBrowserInstalled2 } = await Promise.resolve().then(() => (init_browsers(), browsers_exports));
|
|
139979
|
+
const { ensureBrowserInstalled: ensureBrowserInstalled2, requiredBrowserAssets: requiredBrowserAssets2 } = await Promise.resolve().then(() => (init_browsers(), browsers_exports));
|
|
139750
139980
|
const available = await getAvailableApps2({ config });
|
|
139751
139981
|
const availableNames = new Set(available.map((a) => a.name));
|
|
139752
139982
|
let installedAnything = false;
|
|
139753
139983
|
for (const browser of needs.browsers) {
|
|
139754
139984
|
if (availableNames.has(browser))
|
|
139755
139985
|
continue;
|
|
139756
|
-
|
|
139757
|
-
|
|
139758
|
-
await ensureBrowserInstalled2(
|
|
139759
|
-
installedAnything = true;
|
|
139760
|
-
} else if (browser === "firefox") {
|
|
139761
|
-
await ensureBrowserInstalled2("firefox", { ctx, deps: { logger: preflightLogger } });
|
|
139762
|
-
await ensureBrowserInstalled2("geckodriver", { ctx, deps: { logger: preflightLogger } });
|
|
139763
|
-
installedAnything = true;
|
|
139986
|
+
const assets = requiredBrowserAssets2(browser);
|
|
139987
|
+
for (const asset of assets) {
|
|
139988
|
+
await ensureBrowserInstalled2(asset, { ctx, deps: { logger: preflightLogger } });
|
|
139764
139989
|
}
|
|
139990
|
+
if (assets.length > 0)
|
|
139991
|
+
installedAnything = true;
|
|
139765
139992
|
}
|
|
139766
139993
|
if (installedAnything)
|
|
139767
139994
|
clearAppCache2(config);
|