diff --git a/.github/manual-test b/.github/manual-test index db2dca4..160c636 100755 --- a/.github/manual-test +++ b/.github/manual-test @@ -104,3 +104,38 @@ printf '\n***** SMOKE TEST 3: Test checklist ***** launch_app "$tmp_dir" "$name" request_feedback "$tmp_dir" + +# ------------------------------------------------------------------------------ + +printf '\n***** SMOKE TEST 4: Setting up test and building app... *****\n' +tmp_dir=$(mktemp -d -t nativefier-manual-test-tray-XXXXX) +name='nativefier-smoke-test-4' +node ./lib/cli.js 'https://google.com/' \ + --name "$name" \ + --tray \ + "$tmp_dir" + +printf '\n***** SMOKE TEST 4: Test checklist ***** +- Should have an app with a tray icon +- Console: no Electron runtime deprecation warnings/error logged' + +launch_app "$tmp_dir" "$name" +request_feedback "$tmp_dir" + +# ------------------------------------------------------------------------------ + +printf '\n***** SMOKE TEST 5: Setting up test and building app... *****\n' +tmp_dir=$(mktemp -d -t nativefier-manual-test-start-in-tray-XXXXX) +name='nativefier-smoke-test-5' +node ./lib/cli.js 'https://google.com/' \ + --name "$name" \ + --tray start-in-tray \ + "$tmp_dir" + +printf '\n***** SMOKE TEST 5: Test checklist ***** +- Should have an app that does not show a window initially, + but will have a tray icon that will show the window. +- Console: no Electron runtime deprecation warnings/error logged' + +launch_app "$tmp_dir" "$name" +request_feedback "$tmp_dir" diff --git a/app/src/components/mainWindow.ts b/app/src/components/mainWindow.ts index 5ef08c0..c002432 100644 --- a/app/src/components/mainWindow.ts +++ b/app/src/components/mainWindow.ts @@ -146,7 +146,7 @@ function createContextMenu(options, window: BrowserWindow): void { export function saveAppArgs(newAppArgs: any): void { try { - fs.writeFileSync(APP_ARGS_FILE_PATH, JSON.stringify(newAppArgs)); + fs.writeFileSync(APP_ARGS_FILE_PATH, JSON.stringify(newAppArgs, null, 2)); } catch (err: unknown) { log.warn( `WARNING: Ignored nativefier.json rewrital (${(err as Error).message})`, diff --git a/src/build/prepareElectronApp.ts b/src/build/prepareElectronApp.ts index c40baf0..51df923 100644 --- a/src/build/prepareElectronApp.ts +++ b/src/build/prepareElectronApp.ts @@ -165,7 +165,7 @@ function changeAppPackageJsonName( packageJson.name = normalizedAppName; log.debug(`Updating ${packageJsonPath} 'name' field to ${normalizedAppName}`); - fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson)); + fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); } /** @@ -190,7 +190,7 @@ export async function prepareElectronApp( log.debug(`Writing app config to ${appJsonPath}`); await writeFileAsync( appJsonPath, - JSON.stringify(pickElectronAppArgs(options)), + JSON.stringify(pickElectronAppArgs(options), null, 2), ); if (options.nativefier.bookmarksMenu) { diff --git a/src/cli.test.ts b/src/cli.test.ts index c4b9693..0e7c0f3 100644 --- a/src/cli.test.ts +++ b/src/cli.test.ts @@ -130,6 +130,7 @@ describe('initArgs + parseArgs', () => { isJsonString: true, }, { arg: 'proxy-rules', shortArg: '', value: 'RULE: PROXY' }, + { arg: 'tray', shortArg: '', value: 'true' }, { arg: 'user-agent', shortArg: 'u', value: 'FIREFOX' }, { arg: 'win32metadata', @@ -220,7 +221,6 @@ describe('initArgs + parseArgs', () => { { arg: 'portable', shortArg: '' }, { arg: 'show-menu-bar', shortArg: 'm' }, { arg: 'single-instance', shortArg: '' }, - { arg: 'tray', shortArg: '' }, { arg: 'verbose', shortArg: '' }, { arg: 'widevine', shortArg: '' }, ])('test boolean arg %s', ({ arg, shortArg }) => { @@ -303,4 +303,29 @@ describe('initArgs + parseArgs', () => { expect(badShortArgs[arg]).toBeNaN(); } }); + + test.each([ + { arg: 'tray', value: 'true' }, + { arg: 'tray', value: 'false' }, + { arg: 'tray', value: 'start-in-tray' }, + { arg: 'tray', value: '' }, + { arg: 'tray', value: undefined }, + ])('test tray valyue %s', ({ arg, value }) => { + if (value !== undefined) { + const args = parseArgs( + initArgs(['https://google.com', `--${arg}`, `${value}`]), + ) as Record; + if (value !== '') { + expect(args[arg]).toBe(value); + } else { + expect(args[arg]).toBe('true'); + } + } else { + const args = parseArgs(initArgs(['https://google.com'])) as Record< + string, + number + >; + expect(args[arg]).toBe('false'); + } + }); }); diff --git a/src/cli.ts b/src/cli.ts index a6ec98d..4f88bf0 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,9 +1,11 @@ #!/usr/bin/env node import 'source-map-support/register'; +import electronPackager = require('electron-packager'); import * as log from 'loglevel'; import * as yargs from 'yargs'; +import { DEFAULT_ELECTRON_VERSION } from './constants'; import { checkInternet, getProcessEnvs, @@ -13,11 +15,10 @@ import { supportedArchs, supportedPlatforms } from './infer/inferOs'; import { buildNativefierApp } from './main'; import { RawOptions } from './options/model'; import { parseJson } from './utils/parseUtils'; -import { DEFAULT_ELECTRON_VERSION } from './constants'; -import electronPackager = require('electron-packager'); export function initArgs(argv: string[]): yargs.Argv { - const args = yargs(argv) + const sanitizedArgs = sanitizeArgs(argv); + const args = yargs(sanitizedArgs) .scriptName('nativefier') .usage( '$0 [outputDirectory] [other options]\nor\n$0 --upgrade [other options]', @@ -229,10 +230,10 @@ export function initArgs(argv: string[]): yargs.Argv { type: 'boolean', }) .option('tray', { - default: false, + default: 'false', description: "allow app to stay in system tray. If 'start-in-tray' is set as argument, don't show main window on first start", - type: 'boolean', + type: 'string', }) .option('width', { defaultDescription: '1280', @@ -569,18 +570,20 @@ export function parseArgs(args: yargs.Argv): RawOptions { return parsed; } -if (require.main === module) { - // Not sure if we still need this with yargs. Keeping for now. +function sanitizeArgs(argv: string[]): string[] { const sanitizedArgs: string[] = []; - process.argv.forEach((arg) => { + argv.forEach((arg) => { if (isArgFormatInvalid(arg)) { throw new Error( `Invalid argument passed: ${arg} .\nNativefier supports short options (like "-n") and long options (like "--name"), all lowercase. Run "nativefier --help" for help.\nAborting`, ); } + const isLastArg = sanitizedArgs.length + 1 === argv.length; if (sanitizedArgs.length > 0) { const previousArg = sanitizedArgs[sanitizedArgs.length - 1]; + log.debug({ arg, previousArg, isLastArg }); + // Work around commander.js not supporting default argument for options if ( previousArg === '--tray' && @@ -590,12 +593,21 @@ if (require.main === module) { } } sanitizedArgs.push(arg); + + if (arg === '--tray' && isLastArg) { + // Add a true if --tray is last so it gets enabled + sanitizedArgs.push('true'); + } }); + return sanitizedArgs; +} + +if (require.main === module) { let args: yargs.Argv | undefined = undefined; let parsedArgs: RawOptions; try { - args = initArgs(sanitizedArgs.slice(2)); + args = initArgs(process.argv.slice(2)); parsedArgs = parseArgs(args); } catch (err: unknown) { if (args) {