test(launcher): allow Windows bootstrap integration startup time

Cold and cached launches each have a 15-second command timeout. Give the integration test time for both launches and executable copies instead of the default five-second budget on hosted Windows runners.
This commit is contained in:
sudacode committed 2026-10-01 01:42:10 -07:00
1 parent db45a70ec2
commit 15cb9fe918
1 file changed
+66 -55
@@ -68,61 +68,72 @@ test('preparation failures keep their exit code and never continue to the launch
assert.match(content, /set "ELECTRON_RUN_AS_NODE="/); assert.match(content, /set "ELECTRON_RUN_AS_NODE="/);
}); });
test('Windows bootstrap prepares once and forwards metacharacter arguments', async (t) => { // Cold and cached launches each allow 15 seconds, plus executable copies during setup.
if (process.platform !== 'win32') return; test(
'Windows bootstrap prepares once and forwards metacharacter arguments',
{ timeout: 45_000 },
async (t) => {
if (process.platform !== 'win32') return;
const root = workspace(t); const root = workspace(t);
const appDirectory = path.join(root, 'Installed & App 100% !'); const appDirectory = path.join(root, 'Installed & App 100% !');
const appPath = path.join(appDirectory, 'SubMiner.exe'); const appPath = path.join(appDirectory, 'SubMiner.exe');
const resourcesPath = path.join(appDirectory, 'resources'); const resourcesPath = path.join(appDirectory, 'resources');
const launcherDirectory = path.join(resourcesPath, 'launcher'); const launcherDirectory = path.join(resourcesPath, 'launcher');
const localAppData = path.join(root, 'Local App Data'); const localAppData = path.join(root, 'Local App Data');
const bootstrapPath = path.join(root, 'subminer.cmd'); const bootstrapPath = path.join(root, 'subminer.cmd');
const version = '1.2.3-test'; const version = '1.2.3-test';
const cachedBunPath = path.join(localAppData, 'SubMiner', 'launcher-runtime', version, 'bun.exe'); const cachedBunPath = path.join(
fs.mkdirSync(launcherDirectory, { recursive: true }); localAppData,
fs.copyFileSync(process.execPath, appPath); 'SubMiner',
fs.writeFileSync(path.join(launcherDirectory, 'version'), version); 'launcher-runtime',
fs.writeFileSync( version,
path.join(launcherDirectory, 'subminer.js'), 'bun.exe',
'console.log(JSON.stringify({args:process.argv.slice(2),app:process.env.SUBMINER_BINARY_PATH,resources:process.env.SUBMINER_RESOURCES_PATH,managed:process.env.SUBMINER_MANAGED_LAUNCHER}));', );
); fs.mkdirSync(launcherDirectory, { recursive: true });
fs.writeFileSync( fs.copyFileSync(process.execPath, appPath);
path.join(launcherDirectory, 'prepare.cjs'), fs.writeFileSync(path.join(launcherDirectory, 'version'), version);
`const fs=require('node:fs');const path=require('node:path');exports.prepareLauncherRuntime=()=>{const target=${JSON.stringify(cachedBunPath)};fs.mkdirSync(path.dirname(target),{recursive:true});fs.copyFileSync(process.execPath,target);};`, fs.writeFileSync(
); path.join(launcherDirectory, 'subminer.js'),
fs.writeFileSync(bootstrapPath, windowsLauncherBootstrapContent(appPath)); 'console.log(JSON.stringify({args:process.argv.slice(2),app:process.env.SUBMINER_BINARY_PATH,resources:process.env.SUBMINER_RESOURCES_PATH,managed:process.env.SUBMINER_MANAGED_LAUNCHER}));',
);
fs.writeFileSync(
path.join(launcherDirectory, 'prepare.cjs'),
`const fs=require('node:fs');const path=require('node:path');exports.prepareLauncherRuntime=()=>{const target=${JSON.stringify(cachedBunPath)};fs.mkdirSync(path.dirname(target),{recursive:true});fs.copyFileSync(process.execPath,target);};`,
);
fs.writeFileSync(bootstrapPath, windowsLauncherBootstrapContent(appPath));
const args = [ const args = [
'spaces here', 'spaces here',
'100%', '100%',
'p%TEMP%q', 'p%TEMP%q',
'bang!', 'bang!',
'a&b', 'a&b',
'x|y', 'x|y',
'<left>', '<left>',
'caret^', 'caret^',
'say "hi"', 'say "hi"',
'日本語', '日本語',
]; ];
const env = { ...process.env, PATH: '', Path: '', LOCALAPPDATA: localAppData }; const env = { ...process.env, PATH: '', Path: '', LOCALAPPDATA: localAppData };
const first = await getRunCommand({})(bootstrapPath, args, { env }); const first = await getRunCommand({})(bootstrapPath, args, { env });
assert.equal(first.exitCode, 0, first.stderr); assert.equal(first.exitCode, 0, first.stderr);
assert.ok(fs.existsSync(cachedBunPath)); assert.ok(fs.existsSync(cachedBunPath));
const firstPayload: unknown = JSON.parse(first.stdout); const firstPayload: unknown = JSON.parse(first.stdout);
assert.deepEqual(firstPayload, { assert.deepEqual(firstPayload, {
args, args,
app: appPath, app: appPath,
resources: resourcesPath, resources: resourcesPath,
managed: '1', managed: '1',
}); });
fs.writeFileSync( fs.writeFileSync(
path.join(launcherDirectory, 'prepare.cjs'), path.join(launcherDirectory, 'prepare.cjs'),
"throw new Error('cached launch should not prepare');", "throw new Error('cached launch should not prepare');",
); );
const second = await getRunCommand({})(bootstrapPath, args, { env }); const second = await getRunCommand({})(bootstrapPath, args, { env });
assert.equal(second.exitCode, 0, second.stderr); assert.equal(second.exitCode, 0, second.stderr);
const secondPayload: unknown = JSON.parse(second.stdout); const secondPayload: unknown = JSON.parse(second.stdout);
assert.deepEqual(secondPayload, firstPayload); assert.deepEqual(secondPayload, firstPayload);
}); },
);