@testspectra/cli 1.0.68 → 1.0.70
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/bin/testspectra-runner +0 -0
- package/dist/commands/init.js +1 -1
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.js +113 -0
- package/dist/index.js +6 -0
- package/dist/runner/bridge.js +15 -2
- package/package.json +2 -2
- package/templates/default/package.json +2 -2
- package/templates/nx/package.json +2 -2
package/bin/testspectra-runner
CHANGED
|
Binary file
|
package/dist/commands/init.js
CHANGED
|
@@ -550,7 +550,7 @@ This workspace uses TestSpectra's **"Centralized Configuration, Distributed Impl
|
|
|
550
550
|
|
|
551
551
|
### Centralized Root Elements
|
|
552
552
|
- \`./spectra.config.ts\`: Single source of truth for runtime configurations (Base URL, Appium devices, browser targets, timeouts).
|
|
553
|
-
- \`./.testspectra/\`:
|
|
553
|
+
- \`./.testspectra/\`: Local test project cache (execution logs, temp artifacts, and universal ambient types in \`.testspectra/types/\`). Global binaries and drivers are managed at \`~/.testspectra/drivers/\`.
|
|
554
554
|
- \`./tsconfig.spectra.json\`: Solution TypeScript entry point equipped with TestSpectra language service plugin.
|
|
555
555
|
- \`./tsconfig.spectra.web.json\`: Strongly-typed composite configuration for Web platform tests.
|
|
556
556
|
- \`./tsconfig.spectra.android.json\`: Strongly-typed composite configuration for Android platform tests.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { execSync, execFileSync } from "child_process";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
const PACKAGES = ["@testspectra/cli", "@testspectra/matchers"];
|
|
8
|
+
function getLatestVersion(pkg) {
|
|
9
|
+
try {
|
|
10
|
+
const out = execFileSync("npm", ["view", pkg, "version", "--json"], {
|
|
11
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
12
|
+
timeout: 10000,
|
|
13
|
+
})
|
|
14
|
+
.toString()
|
|
15
|
+
.trim()
|
|
16
|
+
.replace(/"/g, "");
|
|
17
|
+
return out || null;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function getCurrentVersion(pkg, cwd) {
|
|
24
|
+
// Walk up to find the installed version
|
|
25
|
+
let cur = path.resolve(cwd);
|
|
26
|
+
while (cur && cur !== path.dirname(cur)) {
|
|
27
|
+
const pkgJson = path.join(cur, "node_modules", pkg, "package.json");
|
|
28
|
+
if (fs.existsSync(pkgJson)) {
|
|
29
|
+
try {
|
|
30
|
+
const p = JSON.parse(fs.readFileSync(pkgJson, "utf-8"));
|
|
31
|
+
return p.version ?? null;
|
|
32
|
+
}
|
|
33
|
+
catch { }
|
|
34
|
+
}
|
|
35
|
+
cur = path.dirname(cur);
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
function detectPackageManager(cwd) {
|
|
40
|
+
if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml")))
|
|
41
|
+
return "pnpm";
|
|
42
|
+
if (fs.existsSync(path.join(cwd, "bun.lockb")) || fs.existsSync(path.join(cwd, "bun.lock")))
|
|
43
|
+
return "bun";
|
|
44
|
+
return "npm";
|
|
45
|
+
}
|
|
46
|
+
function buildInstallCmd(pm, pkgSpecs) {
|
|
47
|
+
const list = pkgSpecs.join(" ");
|
|
48
|
+
switch (pm) {
|
|
49
|
+
case "pnpm":
|
|
50
|
+
return `pnpm add -D ${list}`;
|
|
51
|
+
case "bun":
|
|
52
|
+
return `bun add -d ${list}`;
|
|
53
|
+
case "npm":
|
|
54
|
+
default:
|
|
55
|
+
return `npm install -D ${list}`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export async function updateCommand(options = {}) {
|
|
59
|
+
const cwd = process.cwd();
|
|
60
|
+
const pm = detectPackageManager(cwd);
|
|
61
|
+
console.log("\x1b[36m┌ 🔄 TestSpectra Self-Update\x1b[0m");
|
|
62
|
+
console.log("\x1b[36m│\x1b[0m");
|
|
63
|
+
console.log(`\x1b[36m│\x1b[0m Package Manager: \x1b[33m${pm}\x1b[0m`);
|
|
64
|
+
console.log("\x1b[36m│\x1b[0m");
|
|
65
|
+
console.log("\x1b[36m│\x1b[0m Fetching latest versions from npm registry...");
|
|
66
|
+
const updates = [];
|
|
67
|
+
for (const pkg of PACKAGES) {
|
|
68
|
+
const current = getCurrentVersion(pkg, cwd);
|
|
69
|
+
const latest = getLatestVersion(pkg);
|
|
70
|
+
const needsUpdate = !!latest && latest !== current;
|
|
71
|
+
updates.push({ pkg, current, latest, needsUpdate });
|
|
72
|
+
const currentStr = current ? `\x1b[33mv${current}\x1b[0m` : "\x1b[90m(not installed)\x1b[0m";
|
|
73
|
+
const latestStr = latest ? `\x1b[32mv${latest}\x1b[0m` : "\x1b[31m(unavailable)\x1b[0m";
|
|
74
|
+
const arrow = needsUpdate ? ` → ${latestStr}` : "";
|
|
75
|
+
const status = !latest
|
|
76
|
+
? "\x1b[31m✗\x1b[0m"
|
|
77
|
+
: needsUpdate
|
|
78
|
+
? "\x1b[33m↑\x1b[0m"
|
|
79
|
+
: "\x1b[32m✓\x1b[0m";
|
|
80
|
+
console.log(`\x1b[36m│\x1b[0m ${status} ${pkg.padEnd(28)} ${currentStr}${arrow}`);
|
|
81
|
+
}
|
|
82
|
+
const toUpdate = updates.filter((u) => u.needsUpdate && u.latest);
|
|
83
|
+
console.log("\x1b[36m│\x1b[0m");
|
|
84
|
+
if (toUpdate.length === 0) {
|
|
85
|
+
console.log("\x1b[36m└──────────────────────────────────────────────────────────\x1b[0m");
|
|
86
|
+
console.log("\x1b[32m✓ All TestSpectra packages are already up-to-date!\x1b[0m\n");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (options.check) {
|
|
90
|
+
console.log(`\x1b[36m│\x1b[0m \x1b[33m${toUpdate.length} update(s) available. Run \x1b[36mspectra update\x1b[33m to install.\x1b[0m`);
|
|
91
|
+
console.log("\x1b[36m└──────────────────────────────────────────────────────────\x1b[0m\n");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const pkgSpecs = toUpdate.map((u) => `${u.pkg}@${u.latest}`);
|
|
95
|
+
const installCmd = buildInstallCmd(pm, pkgSpecs);
|
|
96
|
+
console.log(`\x1b[36m│\x1b[0m Running: \x1b[90m${installCmd}\x1b[0m`);
|
|
97
|
+
console.log("\x1b[36m│\x1b[0m");
|
|
98
|
+
try {
|
|
99
|
+
execSync(installCmd, { cwd, stdio: "inherit" });
|
|
100
|
+
console.log("\x1b[36m│\x1b[0m");
|
|
101
|
+
console.log("\x1b[36m└──────────────────────────────────────────────────────────\x1b[0m");
|
|
102
|
+
console.log("\x1b[32m🎉 TestSpectra updated successfully!\x1b[0m");
|
|
103
|
+
for (const u of toUpdate) {
|
|
104
|
+
console.log(` \x1b[32m✓\x1b[0m ${u.pkg}: v${u.current ?? "?"} → v${u.latest}`);
|
|
105
|
+
}
|
|
106
|
+
console.log("");
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
console.log("\x1b[36m└──────────────────────────────────────────────────────────\x1b[0m");
|
|
110
|
+
console.error(`\x1b[31m✗ Update failed: ${err.message}\x1b[0m\n`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { devicesCommand } from "./commands/devices.js";
|
|
|
5
5
|
import { doctorCommand } from "./commands/doctor.js";
|
|
6
6
|
import { initCommand } from "./commands/init.js";
|
|
7
7
|
import { runCommand } from "./commands/run.js";
|
|
8
|
+
import { updateCommand } from "./commands/update.js";
|
|
8
9
|
import { watchCommand } from "./commands/watch.js";
|
|
9
10
|
export * from "./config/schema.js";
|
|
10
11
|
export * from "./config/loader.js";
|
|
@@ -44,6 +45,11 @@ export function createCliProgram() {
|
|
|
44
45
|
.option("--fix", "Attempt automatic fix / download of missing tools")
|
|
45
46
|
.option("--json", "Output diagnostic results as JSON")
|
|
46
47
|
.action(doctorCommand);
|
|
48
|
+
program
|
|
49
|
+
.command("update")
|
|
50
|
+
.description("Update @testspectra/cli and @testspectra/matchers to the latest version from npm")
|
|
51
|
+
.option("--check", "Only check for available updates without installing")
|
|
52
|
+
.action(updateCommand);
|
|
47
53
|
program
|
|
48
54
|
.command("devices")
|
|
49
55
|
.description("List connected Android/iOS devices and local browsers")
|
package/dist/runner/bridge.js
CHANGED
|
@@ -36,18 +36,31 @@ export class RustCoreBridge {
|
|
|
36
36
|
config: options.config,
|
|
37
37
|
targetDevice: options.targetDevice,
|
|
38
38
|
});
|
|
39
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
40
|
+
const globalDriversDir = path.join(home, ".testspectra", "drivers");
|
|
41
|
+
if (!fs.existsSync(globalDriversDir)) {
|
|
42
|
+
try {
|
|
43
|
+
fs.mkdirSync(globalDriversDir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
catch { }
|
|
46
|
+
}
|
|
47
|
+
const runnerEnv = {
|
|
48
|
+
...process.env,
|
|
49
|
+
TEST_SPECTRA_DRIVER_CACHE: globalDriversDir,
|
|
50
|
+
RUST_LOG: "info",
|
|
51
|
+
};
|
|
39
52
|
return new Promise((resolve, reject) => {
|
|
40
53
|
let child;
|
|
41
54
|
if (binPath === "cargo") {
|
|
42
55
|
const workspaceRoot = path.resolve(__dirname, "../../..");
|
|
43
56
|
child = spawn("cargo", ["run", "--manifest-path", "core/test-runner/Cargo.toml", "--bin", "testspectra-runner", "--", payload], {
|
|
44
57
|
cwd: workspaceRoot,
|
|
45
|
-
env:
|
|
58
|
+
env: runnerEnv,
|
|
46
59
|
});
|
|
47
60
|
}
|
|
48
61
|
else {
|
|
49
62
|
child = spawn(binPath, [payload], {
|
|
50
|
-
env:
|
|
63
|
+
env: runnerEnv,
|
|
51
64
|
});
|
|
52
65
|
}
|
|
53
66
|
let runStatus = "failed";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testspectra/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.70",
|
|
4
4
|
"description": "TestSpectra Zero-Config Cross-Platform Test Runner CLI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@clack/prompts": "^1.7.0",
|
|
33
|
-
"@testspectra/matchers": "^1.0.
|
|
33
|
+
"@testspectra/matchers": "^1.0.70",
|
|
34
34
|
"chalk": "^5.3.0",
|
|
35
35
|
"commander": "^12.1.0",
|
|
36
36
|
"dotenv": "^16.4.5",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"type-check": "tsc -b"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
|
-
"@testspectra/cli": "^1.0.
|
|
12
|
-
"@testspectra/matchers": "^1.0.
|
|
11
|
+
"@testspectra/cli": "^1.0.70",
|
|
12
|
+
"@testspectra/matchers": "^1.0.70",
|
|
13
13
|
"@types/node": "^20.14.0",
|
|
14
14
|
"@wdio/cli": "^9.2.8",
|
|
15
15
|
"@wdio/local-runner": "^9.2.8",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"build": "nx run-many -t build"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
|
-
"@testspectra/cli": "^1.0.
|
|
14
|
-
"@testspectra/matchers": "^1.0.
|
|
13
|
+
"@testspectra/cli": "^1.0.70",
|
|
14
|
+
"@testspectra/matchers": "^1.0.70",
|
|
15
15
|
"@types/node": "^20.14.0",
|
|
16
16
|
"@wdio/cli": "^9.2.8",
|
|
17
17
|
"@wdio/local-runner": "^9.2.8",
|