@wp-tester/cli 0.0.4 → 0.1.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/cli/cli.js +16 -2
- package/dist/cli/cli.js.map +1 -1
- package/dist/commands/config/index.d.ts +1 -1
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +11 -3
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/validate.d.ts +45 -1
- package/dist/commands/config/validate.d.ts.map +1 -1
- package/dist/commands/config/validate.js +187 -18
- package/dist/commands/config/validate.js.map +1 -1
- package/dist/commands/config/validate.spec.d.ts +2 -0
- package/dist/commands/config/validate.spec.d.ts.map +1 -0
- package/dist/commands/config/validate.spec.js +89 -0
- package/dist/commands/config/validate.spec.js.map +1 -0
- package/dist/commands/test/index.d.ts +4 -1
- package/dist/commands/test/index.d.ts.map +1 -1
- package/dist/commands/test/index.js +34 -4
- package/dist/commands/test/index.js.map +1 -1
- package/dist/commands/test/runner.d.ts +23 -1
- package/dist/commands/test/runner.d.ts.map +1 -1
- package/dist/commands/test/runner.js +103 -49
- package/dist/commands/test/runner.js.map +1 -1
- package/dist/commands/test/watcher.d.ts +6 -0
- package/dist/commands/test/watcher.d.ts.map +1 -0
- package/dist/commands/test/watcher.js +173 -0
- package/dist/commands/test/watcher.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -5
|
@@ -4,34 +4,50 @@ import * as clack from '../../cli/theme.js';
|
|
|
4
4
|
import { runSmokeTests } from "@wp-tester/smoke-tests";
|
|
5
5
|
import { runPhpunitTests } from "@wp-tester/phpunit";
|
|
6
6
|
import { mergeReports, printSummary } from "@wp-tester/results";
|
|
7
|
-
import {
|
|
7
|
+
import { resolveConfig } from "@wp-tester/config";
|
|
8
|
+
import { validateConfig } from "../config/validate.js";
|
|
9
|
+
import { getConfigPath } from "@wp-tester/config";
|
|
10
|
+
/**
|
|
11
|
+
* Apply --failed-only CLI override to config reporters.
|
|
12
|
+
* Sets all filter options to false except failed: true.
|
|
13
|
+
*/
|
|
14
|
+
function applyFailedOnlyOverride(config) {
|
|
15
|
+
const failedOnlyFilter = {
|
|
16
|
+
passed: false,
|
|
17
|
+
failed: true,
|
|
18
|
+
skipped: false,
|
|
19
|
+
pending: false,
|
|
20
|
+
other: false,
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
...config,
|
|
24
|
+
reporters: {
|
|
25
|
+
...config.reporters,
|
|
26
|
+
default: config.reporters?.default !== undefined
|
|
27
|
+
? typeof config.reporters.default === "object"
|
|
28
|
+
? { ...config.reporters.default, ...failedOnlyFilter }
|
|
29
|
+
: failedOnlyFilter
|
|
30
|
+
: failedOnlyFilter,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
8
34
|
async function resolveConfigPath(configPath) {
|
|
9
|
-
const resolvedPath =
|
|
35
|
+
const resolvedPath = getConfigPath(configPath);
|
|
10
36
|
try {
|
|
11
37
|
const stats = await stat(resolvedPath);
|
|
12
38
|
if (stats.isDirectory()) {
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
await access(configFile, constants.F_OK);
|
|
16
|
-
return configFile;
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
clack.log.error(`Config file not found in directory: ${resolvedPath}`);
|
|
20
|
-
clack.log.error("Please provide a path to a valid WP Tester config file.");
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
39
|
+
return path.join(resolvedPath, "wp-tester.json");
|
|
23
40
|
}
|
|
24
41
|
}
|
|
25
42
|
catch {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
process.exit(1);
|
|
43
|
+
// File doesn't exist yet, but that's ok - return the resolved path
|
|
44
|
+
// The caller will handle the missing file case
|
|
29
45
|
}
|
|
30
46
|
return resolvedPath;
|
|
31
47
|
}
|
|
32
48
|
async function checkConfigExists(configPath) {
|
|
33
49
|
try {
|
|
34
|
-
const resolvedPath =
|
|
50
|
+
const resolvedPath = getConfigPath(configPath);
|
|
35
51
|
await access(resolvedPath, constants.F_OK);
|
|
36
52
|
return true;
|
|
37
53
|
}
|
|
@@ -50,31 +66,22 @@ function getSmokeTestFilter(testType) {
|
|
|
50
66
|
}
|
|
51
67
|
return smokeTestTypes.includes(testType) ? testType : false;
|
|
52
68
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return "Config path is required";
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
if (clack.isCancel(newPath)) {
|
|
68
|
-
clack.cancel("Test cancelled.");
|
|
69
|
-
process.exit(0);
|
|
70
|
-
}
|
|
71
|
-
finalConfigPath = newPath;
|
|
69
|
+
/**
|
|
70
|
+
* Execute tests and return results without exiting the process.
|
|
71
|
+
* Used internally and by watch mode.
|
|
72
|
+
*/
|
|
73
|
+
export const executeTests = async (configPath, options) => {
|
|
74
|
+
const { testType, extraArgs, failedOnly } = options || {};
|
|
75
|
+
const finalConfigPath = await resolveConfigPath(configPath);
|
|
76
|
+
// Validate configuration before running tests
|
|
77
|
+
const isValid = await validateConfig(finalConfigPath);
|
|
78
|
+
if (!isValid) {
|
|
79
|
+
process.exit(1);
|
|
72
80
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
configForTests = await mergePhpunitArgs(absoluteConfigPath, phpunitArgs);
|
|
81
|
+
// Resolve config and apply CLI overrides
|
|
82
|
+
let resolvedConfig = await resolveConfig(finalConfigPath);
|
|
83
|
+
if (failedOnly) {
|
|
84
|
+
resolvedConfig = applyFailedOnlyOverride(resolvedConfig);
|
|
78
85
|
}
|
|
79
86
|
// Run all test suites and collect results
|
|
80
87
|
const reports = [];
|
|
@@ -82,29 +89,76 @@ export const runTests = async (configPath, testType, phpunitArgs) => {
|
|
|
82
89
|
const shouldRunPhpUnit = !testType || testType === "phpunit";
|
|
83
90
|
// Run smoke tests (wp, plugin, theme) - smoke tests package handles whether to run
|
|
84
91
|
const smokeTestFilter = getSmokeTestFilter(testType);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
92
|
+
if (smokeTestFilter !== false) {
|
|
93
|
+
const smokeTestReport = await runSmokeTests(resolvedConfig, smokeTestFilter, extraArgs);
|
|
94
|
+
if (smokeTestReport.results.summary.tests > 0) {
|
|
95
|
+
reports.push(smokeTestReport);
|
|
96
|
+
}
|
|
88
97
|
}
|
|
89
98
|
// Run PHPUnit tests
|
|
90
99
|
if (shouldRunPhpUnit) {
|
|
91
|
-
const phpunitReport = await runPhpunitTests(
|
|
100
|
+
const phpunitReport = await runPhpunitTests(resolvedConfig, extraArgs);
|
|
101
|
+
// Always include report if PHPUnit was configured to run
|
|
102
|
+
// This ensures bootstrap failures are visible
|
|
92
103
|
if (phpunitReport.results.summary.tests > 0) {
|
|
93
104
|
reports.push(phpunitReport);
|
|
94
105
|
}
|
|
95
106
|
}
|
|
96
|
-
//
|
|
107
|
+
// No tests were run
|
|
97
108
|
if (reports.length === 0) {
|
|
98
109
|
clack.log.error("No tests were run. Check your configuration.");
|
|
99
|
-
|
|
110
|
+
return { success: false, hasTests: false };
|
|
100
111
|
}
|
|
101
112
|
// Merge results from all test suites
|
|
102
113
|
const mergedReport = mergeReports(reports);
|
|
103
114
|
// Display unified summary
|
|
104
115
|
const { summary } = mergedReport.results;
|
|
105
116
|
const success = summary.failed === 0;
|
|
106
|
-
// Print final combined summary
|
|
107
|
-
|
|
108
|
-
|
|
117
|
+
// Print final combined summary with default reporter options
|
|
118
|
+
const defaultReporterOptions = resolvedConfig.reporters?.default;
|
|
119
|
+
// Convert reporter options to summary options (handle boolean shorthand)
|
|
120
|
+
// When false or true (boolean shorthand), pass undefined to use printSummary defaults
|
|
121
|
+
// When an object, pass it directly since SummaryOptions now matches BaseReporterOptions
|
|
122
|
+
const summaryOptions = typeof defaultReporterOptions === "object"
|
|
123
|
+
? defaultReporterOptions
|
|
124
|
+
: undefined;
|
|
125
|
+
printSummary(summary, summaryOptions);
|
|
126
|
+
return { success, hasTests: true };
|
|
127
|
+
};
|
|
128
|
+
export const runTests = async (configPath, options) => {
|
|
129
|
+
const { passWithNoTests } = options || {};
|
|
130
|
+
let finalConfigPath = await resolveConfigPath(configPath);
|
|
131
|
+
// Check if config file exists
|
|
132
|
+
while (!(await checkConfigExists(finalConfigPath))) {
|
|
133
|
+
const resolvedPath = getConfigPath(finalConfigPath);
|
|
134
|
+
clack.log.error(`Config file not found: ${resolvedPath}`);
|
|
135
|
+
const newPath = await clack.text({
|
|
136
|
+
message: "Enter the correct path to your config file:",
|
|
137
|
+
placeholder: "./wp-tester.json",
|
|
138
|
+
validate: (value) => {
|
|
139
|
+
if (!value)
|
|
140
|
+
return "Config path is required";
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
if (clack.isCancel(newPath)) {
|
|
144
|
+
clack.cancel("Test cancelled.");
|
|
145
|
+
process.exit(0);
|
|
146
|
+
}
|
|
147
|
+
finalConfigPath = newPath;
|
|
148
|
+
}
|
|
149
|
+
const result = await executeTests(finalConfigPath, options);
|
|
150
|
+
if (!result.hasTests) {
|
|
151
|
+
// If passWithNoTests is enabled, treat no tests as success
|
|
152
|
+
if (passWithNoTests) {
|
|
153
|
+
clack.log.info("No tests were run. Check your configuration.");
|
|
154
|
+
process.exit(0);
|
|
155
|
+
}
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
// Determine exit code based on test results
|
|
159
|
+
if (!result.success) {
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
process.exit(0);
|
|
109
163
|
};
|
|
110
164
|
//# sourceMappingURL=runner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/commands/test/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,KAAK,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/commands/test/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../../src/commands/test/watcher.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAiDD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAsJvE"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { watch } from 'fs';
|
|
2
|
+
import picomatch from 'picomatch';
|
|
3
|
+
import * as clack from '../../cli/theme.js';
|
|
4
|
+
import { getProjectDir, readConfigFile, normalizeConfigPath } from '@wp-tester/config';
|
|
5
|
+
// Default patterns to exclude when watching for changes
|
|
6
|
+
const DEFAULT_EXCLUDE_PATTERNS = [
|
|
7
|
+
'**/node_modules/**',
|
|
8
|
+
'**/vendor/**',
|
|
9
|
+
'**/.git/**',
|
|
10
|
+
'**/.svn/**',
|
|
11
|
+
'**/.hg/**',
|
|
12
|
+
'**/.DS_Store',
|
|
13
|
+
'**/Thumbs.db',
|
|
14
|
+
];
|
|
15
|
+
function createWatchMatcher(watchConfig) {
|
|
16
|
+
// Merge default excludes with user-provided excludes
|
|
17
|
+
const excludePatterns = watchConfig?.exclude ?? DEFAULT_EXCLUDE_PATTERNS;
|
|
18
|
+
const includePatterns = watchConfig?.include;
|
|
19
|
+
// Create picomatch matchers
|
|
20
|
+
const excludeMatcher = picomatch(excludePatterns, { dot: true });
|
|
21
|
+
const includeMatcher = includePatterns
|
|
22
|
+
? picomatch(includePatterns, { dot: true })
|
|
23
|
+
: null;
|
|
24
|
+
return {
|
|
25
|
+
shouldWatch: (filePath) => {
|
|
26
|
+
// Normalize path separators for cross-platform compatibility
|
|
27
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
28
|
+
// Check if file should be excluded
|
|
29
|
+
if (excludeMatcher(normalizedPath)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
// Check include patterns if specified
|
|
33
|
+
if (includeMatcher) {
|
|
34
|
+
return includeMatcher(normalizedPath);
|
|
35
|
+
}
|
|
36
|
+
// No include patterns means watch everything (that's not excluded)
|
|
37
|
+
return true;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export async function runWatchMode(options) {
|
|
42
|
+
const { configPath, onRunTests } = options;
|
|
43
|
+
// Resolve config to get the project directory and watch settings
|
|
44
|
+
const config = await readConfigFile(configPath);
|
|
45
|
+
// Normalize config path to handle directory paths (appends wp-tester.json if needed)
|
|
46
|
+
const normalizedConfigPath = normalizeConfigPath(configPath);
|
|
47
|
+
const projectDir = getProjectDir(config, normalizedConfigPath);
|
|
48
|
+
const watchConfig = config.tests.watch;
|
|
49
|
+
// Create the file matcher
|
|
50
|
+
const matcher = createWatchMatcher(watchConfig);
|
|
51
|
+
// Always watch the project directory, use matcher to filter files
|
|
52
|
+
clack.log.info(`Watching for changes in: ${projectDir}`);
|
|
53
|
+
if (watchConfig?.include) {
|
|
54
|
+
clack.log.step(`Include patterns: ${watchConfig.include.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
if (watchConfig?.exclude) {
|
|
57
|
+
clack.log.step(`Exclude patterns: ${watchConfig.exclude.join(", ")}`);
|
|
58
|
+
}
|
|
59
|
+
clack.log.info("Press Enter to re-run tests, or q to quit.\n");
|
|
60
|
+
let isRunning = false;
|
|
61
|
+
let pendingRun = false;
|
|
62
|
+
let debounceTimer = null;
|
|
63
|
+
let watcher = null;
|
|
64
|
+
const runTests = async () => {
|
|
65
|
+
if (isRunning) {
|
|
66
|
+
pendingRun = true;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
isRunning = true;
|
|
70
|
+
// Clear screen and move cursor to top-left using ANSI escape codes
|
|
71
|
+
// \x1b[2J clears the entire screen, \x1b[3J clears scrollback, \x1b[H moves cursor to home
|
|
72
|
+
// This is more reliable than console.clear() in watch mode
|
|
73
|
+
process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
|
|
74
|
+
clack.log.info(" Test run\n");
|
|
75
|
+
try {
|
|
76
|
+
await onRunTests();
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Tests may exit with non-zero code, which is expected
|
|
80
|
+
if (error instanceof Error && !error.message.includes("process.exit")) {
|
|
81
|
+
clack.log.error(`Error running tests: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
isRunning = false;
|
|
86
|
+
clack.log.info("Watching for changes... (Enter to re-run, q to quit)");
|
|
87
|
+
if (pendingRun) {
|
|
88
|
+
pendingRun = false;
|
|
89
|
+
await runTests();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const scheduleRun = () => {
|
|
94
|
+
if (debounceTimer) {
|
|
95
|
+
clearTimeout(debounceTimer);
|
|
96
|
+
}
|
|
97
|
+
// Debounce file changes - wait 300ms before running tests
|
|
98
|
+
debounceTimer = setTimeout(() => {
|
|
99
|
+
void runTests();
|
|
100
|
+
}, 300);
|
|
101
|
+
};
|
|
102
|
+
// Set up file watcher
|
|
103
|
+
try {
|
|
104
|
+
watcher = watch(projectDir, { recursive: true }, (eventType, filename) => {
|
|
105
|
+
if (filename && matcher.shouldWatch(filename)) {
|
|
106
|
+
scheduleRun();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
watcher.on("error", (error) => {
|
|
110
|
+
clack.log.error(`Watcher error: ${error.message}`);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
if (error instanceof Error) {
|
|
115
|
+
clack.log.error(`Failed to start watcher: ${error.message}`);
|
|
116
|
+
}
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
// Set up keyboard input handling
|
|
120
|
+
if (process.stdin.isTTY) {
|
|
121
|
+
process.stdin.setRawMode(true);
|
|
122
|
+
process.stdin.resume();
|
|
123
|
+
process.stdin.setEncoding("utf8");
|
|
124
|
+
process.stdin.on("data", (key) => {
|
|
125
|
+
// Handle Ctrl+C
|
|
126
|
+
if (key === "\u0003") {
|
|
127
|
+
cleanup();
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
130
|
+
// Handle 'q' or 'Q' to quit
|
|
131
|
+
if (key === "q" || key === "Q") {
|
|
132
|
+
cleanup();
|
|
133
|
+
process.exit(0);
|
|
134
|
+
}
|
|
135
|
+
// Handle Enter to re-run tests
|
|
136
|
+
if (key === "\r" || key === "\n") {
|
|
137
|
+
scheduleRun();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const onSigint = () => {
|
|
142
|
+
cleanup();
|
|
143
|
+
process.exit(0);
|
|
144
|
+
};
|
|
145
|
+
const onSigterm = () => {
|
|
146
|
+
cleanup();
|
|
147
|
+
process.exit(0);
|
|
148
|
+
};
|
|
149
|
+
const cleanup = () => {
|
|
150
|
+
if (debounceTimer) {
|
|
151
|
+
clearTimeout(debounceTimer);
|
|
152
|
+
}
|
|
153
|
+
if (watcher) {
|
|
154
|
+
watcher.close();
|
|
155
|
+
}
|
|
156
|
+
if (process.stdin.isTTY) {
|
|
157
|
+
process.stdin.setRawMode(false);
|
|
158
|
+
}
|
|
159
|
+
process.off("SIGINT", onSigint);
|
|
160
|
+
process.off("SIGTERM", onSigterm);
|
|
161
|
+
clack.log.info('\nWatch mode stopped.');
|
|
162
|
+
};
|
|
163
|
+
// Handle process termination
|
|
164
|
+
process.on("SIGINT", onSigint);
|
|
165
|
+
process.on("SIGTERM", onSigterm);
|
|
166
|
+
// Run tests initially
|
|
167
|
+
await runTests();
|
|
168
|
+
// Keep the process alive
|
|
169
|
+
await new Promise(() => {
|
|
170
|
+
// This promise never resolves, keeping watch mode running
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/commands/test/watcher.ts"],"names":[],"mappings":"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"}
|