factorio-test-cli 3.4.0 → 3.5.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.
@@ -131,6 +131,7 @@ export function registerAllCliOptions(command) {
131
131
  command.option("-c --config <path>", "Path to config file (default: factorio-test.json, or 'factorio-test' key in package.json)");
132
132
  command.option("-g --graphics", "Launch Factorio with graphics (interactive mode) instead of headless");
133
133
  command.option("-w --watch", "Watch for file changes and rerun tests");
134
+ command.option("--no-auto-start", "Configure tests but do not auto-start them (requires --graphics)");
134
135
  addOption(command, f.modPath.cli);
135
136
  addOption(command, f.modName.cli);
136
137
  addOption(command, f.factorioPath.cli);
package/config/loader.js CHANGED
@@ -58,6 +58,7 @@ export function resolveConfig({ cliOptions, patterns }) {
58
58
  return {
59
59
  graphics: cliOptions.graphics,
60
60
  watch: cliOptions.watch,
61
+ noAutoStart: cliOptions.autoStart === false ? true : undefined,
61
62
  modPath: baseConfig.modPath,
62
63
  modName: baseConfig.modName,
63
64
  factorioPath: baseConfig.factorioPath,
@@ -49,7 +49,7 @@ const testConfigFields = {
49
49
  schema: z.boolean().optional(),
50
50
  cli: {
51
51
  flags: "--reorder-failed-first",
52
- description: "Run previously failed tests first (default: enabled).",
52
+ description: "Run previously failed tests first (default: disabled).",
53
53
  negatable: true,
54
54
  },
55
55
  },
package/mod-setup.js CHANGED
@@ -154,17 +154,20 @@ locale=
154
154
  }
155
155
  }
156
156
  }
157
- export async function setSettingsForAutorun(factorioPath, dataDir, modsDir, modToTest, mode, options) {
157
+ export async function ensureModSettingsDat(factorioPath, dataDir, modsDir, verbose) {
158
158
  const settingsDat = path.join(modsDir, "mod-settings.dat");
159
- if (!fs.existsSync(settingsDat)) {
160
- if (options?.verbose)
161
- console.log("Creating mod-settings.dat file by running factorio");
162
- const dummySaveFile = path.join(dataDir, "____dummy_save_file.zip");
163
- await runProcess(false, factorioPath, "--create", dummySaveFile, "--mod-directory", modsDir, "-c", path.join(dataDir, "config.ini"));
164
- if (fs.existsSync(dummySaveFile)) {
165
- await fsp.rm(dummySaveFile);
166
- }
159
+ if (fs.existsSync(settingsDat))
160
+ return;
161
+ if (verbose)
162
+ console.log("Creating mod-settings.dat file by running factorio");
163
+ const dummySaveFile = path.join(dataDir, "____dummy_save_file.zip");
164
+ await runProcess(false, factorioPath, "--create", dummySaveFile, "--mod-directory", modsDir, "-c", path.join(dataDir, "config.ini"));
165
+ if (fs.existsSync(dummySaveFile)) {
166
+ await fsp.rm(dummySaveFile);
167
167
  }
168
+ }
169
+ export async function setSettingsForAutorun(factorioPath, dataDir, modsDir, modToTest, mode, options) {
170
+ await ensureModSettingsDat(factorioPath, dataDir, modsDir, options?.verbose);
168
171
  if (options?.verbose)
169
172
  console.log("Setting autorun settings");
170
173
  const autoStartConfig = JSON.stringify({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "factorio-test-cli",
3
- "version": "3.4.0",
3
+ "version": "3.5.1",
4
4
  "description": "A CLI to run FactorioTest.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/run.js CHANGED
@@ -5,10 +5,9 @@ import * as fsp from "fs/promises";
5
5
  import * as path from "path";
6
6
  import { CliError } from "./cli-error.js";
7
7
  import { registerAllCliOptions, resolveConfig } from "./config/index.js";
8
- import { autoDetectFactorioPath } from "./factorio-process.js";
9
- import { getHeadlessSavePath, runFactorioTestsGraphics, runFactorioTestsHeadless, } from "./factorio-process.js";
8
+ import { autoDetectFactorioPath, getHeadlessSavePath, runFactorioTestsGraphics, runFactorioTestsHeadless, } from "./factorio-process.js";
10
9
  import { watchDirectory, watchFile } from "./file-watcher.js";
11
- import { configureModToTest, ensureConfigIni, installFactorioTest, installModDependencies, installMods, parseModRequirement, resetAutorunSettings, resolveModWatchTarget, setSettingsForAutorun, } from "./mod-setup.js";
10
+ import { configureModToTest, ensureConfigIni, ensureModSettingsDat, installFactorioTest, installModDependencies, installMods, parseModRequirement, resetAutorunSettings, resolveModWatchTarget, setSettingsForAutorun, } from "./mod-setup.js";
12
11
  import { runScript, setVerbose } from "./process-utils.js";
13
12
  import { OutputFormatter } from "./test-output.js";
14
13
  import { readPreviousFailedTests, writeResultsFile } from "./test-results.js";
@@ -16,17 +15,27 @@ const thisCommand = program
16
15
  .command("run")
17
16
  .summary("Runs tests with Factorio test.")
18
17
  .description(`Runs tests for the specified mod with Factorio test. Exits with code 0 only if all tests pass.
19
-
20
18
  One of --mod-path or --mod-name is required.
21
- Test execution options (--test-pattern, --tag-*, --bail, etc.) override in-mod config.
22
19
 
23
- When using variadic options (--mods, --factorio-args, etc.) with filter patterns,
24
- use -- to separate them:
25
- factorio-test run -p ./my-mod --mods quality space-age -- "inventory"
20
+ JSON configuration:
21
+ Instead of using command-line arguments, you can configure the test runner using a JSON file.
22
+ By default, the CLI will look for a factorio-test.json file or a "factorio-test" key in
23
+ package.json. You can specify a custom file using the --config option.
24
+ CLI arguments override file config.
25
+ Test execution options (options that can also be specified in the mod itself) go under the
26
+ "test" key using snake_case, overriding in-mod config.
27
+ {
28
+ "modPath": "./my-mod",
29
+ "test": { "bail": 1, "game_speed": 100, "tag_blacklist": ["slow"] }
30
+ }
26
31
 
27
- Patterns use Lua pattern syntax (not regex). Special characters like - must be
28
- escaped with %:
29
- factorio-test run -p ./my-mod "my%-test" Match "my-test" (escape the dash)
32
+ Test filter patterns:
33
+ Filter patterns use Lua pattern syntax (not regex). Special characters like -
34
+ must be escaped with %:
35
+ factorio-test run -p ./my-mod "foo > my%-test"
36
+ When using variadic options (--mods, --factorio-args, etc.) with filter
37
+ patterns, use -- to separate them:
38
+ factorio-test run -p ./my-mod --mods quality space-age -- "inventory"
30
39
 
31
40
  Examples:
32
41
  factorio-test run -p ./my-mod Run all tests
@@ -47,6 +56,9 @@ async function setupTestRun(patterns, cliOptions) {
47
56
  if (config.modPath === undefined && config.modName === undefined) {
48
57
  throw new CliError("One of --mod-path or --mod-name must be specified.");
49
58
  }
59
+ if (config.noAutoStart && !config.graphics) {
60
+ throw new CliError("--no-auto-start requires --graphics.");
61
+ }
50
62
  const factorioPath = config.factorioPath ?? autoDetectFactorioPath();
51
63
  const dataDir = config.dataDirectory;
52
64
  const modsDir = path.join(dataDir, "mods");
@@ -82,7 +94,7 @@ async function setupTestRun(patterns, cliOptions) {
82
94
  async function executeTestRun(ctx, execOptions) {
83
95
  const { config, factorioPath, dataDir, modsDir, modToTest, mode, savePath, factorioArgs } = ctx;
84
96
  const { signal, skipResetAutorun, resolveOnResult } = execOptions ?? {};
85
- const reorderEnabled = config.testConfig.reorder_failed_first ?? true;
97
+ const reorderEnabled = config.testConfig.reorder_failed_first ?? false;
86
98
  const lastFailedTests = reorderEnabled && config.outputFile ? await readPreviousFailedTests(config.outputFile) : [];
87
99
  await setSettingsForAutorun(factorioPath, dataDir, modsDir, modToTest, mode, {
88
100
  verbose: config.verbose,
@@ -191,9 +203,24 @@ async function runHeadlessWatchMode(ctx) {
191
203
  });
192
204
  return new Promise(() => { });
193
205
  }
206
+ async function launchWithoutAutoStart(ctx) {
207
+ const { config, factorioPath, dataDir, modsDir, modToTest, savePath, factorioArgs } = ctx;
208
+ await ensureModSettingsDat(factorioPath, dataDir, modsDir, config.verbose);
209
+ await runScript("fmtk", "settings", "set", "runtime-global", "factorio-test-mod-to-test", modToTest, "--modsPath", modsDir);
210
+ if (Object.keys(config.testConfig).length > 0) {
211
+ await runScript("fmtk", "settings", "set", "runtime-global", "factorio-test-config", JSON.stringify(config.testConfig), "--modsPath", modsDir);
212
+ }
213
+ await runFactorioTestsGraphics(factorioPath, dataDir, savePath, factorioArgs, {
214
+ verbose: config.verbose,
215
+ quiet: config.quiet,
216
+ });
217
+ }
194
218
  async function runTests(patterns, cliOptions) {
195
219
  const ctx = await setupTestRun(patterns, cliOptions);
196
- if (ctx.config.watch && ctx.config.graphics) {
220
+ if (ctx.config.noAutoStart) {
221
+ await launchWithoutAutoStart(ctx);
222
+ }
223
+ else if (ctx.config.watch && ctx.config.graphics) {
197
224
  await runGraphicsWatchMode(ctx);
198
225
  }
199
226
  else if (ctx.config.watch) {