Skip to content

Commit

Permalink
tests for app launching and appusermodelid
Browse files Browse the repository at this point in the history
  • Loading branch information
bitdisaster committed Feb 27, 2020
1 parent 0704872 commit 051288a
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 13 deletions.
15 changes: 15 additions & 0 deletions e2e/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"test": "npm run build && npm run e2e",
"build": "tsc --pretty",
"e2e": "mocha lib/**/*.js --timeout 100000 --reporter spec",
"e2e": "mocha lib/**/*.js --timeout 30000 --reporter spec",
"lint": "tslint -c tslint.json 'src/**/*.ts'"
},
"author": "Jan Hannemann",
Expand All @@ -29,11 +29,13 @@
"@types/mocha": "^7.0.1",
"@types/node": "^13.7.4",
"@types/node-powershell": "^3.1.1",
"@types/ps-list": "^6.2.1",
"@types/semver": "^6.2.0",
"expect.js": "^0.3.1",
"hasha": "^5.2.0",
"mocha": "^7.0.1",
"node-powershell": "^4.0.0",
"ps-list": "^7.0.0",
"spawn-rx": "^3.0.0",
"tslint": "^5.20.1"
}
Expand Down
1 change: 0 additions & 1 deletion e2e/src/ambient.d.ts

This file was deleted.

79 changes: 68 additions & 11 deletions e2e/src/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import hasha from 'hasha';
import path from 'path';

import { getWindowsCompliantVersion } from '../../lib/utils/version-util';
import { getProcessPath, kill, launch, runs } from './utils/app-process';
import { checkInstall, getInstallPaths, install, uninstall, uninstallViaPowershell } from './utils/installer';
import { readAppUserModelId } from './utils/lnk-inspector';
import { defaultOptions, HARNESS_APP_DIR, OUT_DIR, packageSampleApp } from './utils/packager';

const msiPath = path.join(OUT_DIR, 'HelloWix.msi');
Expand All @@ -30,6 +32,7 @@ interface TestConfig {
arch: 'x86' | 'x64';
shortcutFolderName?: string;
shortcutName?: string;
appUserModelId?: string;
}

describe('Electron WIX MSI', () => {
Expand All @@ -41,7 +44,7 @@ describe('Electron WIX MSI', () => {

const tests: TestConfig[] = [
{arch: 'x86'},
{arch: 'x86', shortcutFolderName: 'SuperWix', shortcutName: 'SuperHello'},
{arch: 'x86', shortcutFolderName: 'SuperWix', shortcutName: 'SuperHello', appUserModelId: 'com.wix.super.hello'},
{arch: 'x64'},
];

Expand All @@ -59,7 +62,9 @@ describe('Electron WIX MSI', () => {
configString += test.shortcutFolderName ? '\\' : '';
configString += test.shortcutName || '';
}
return configString;
configString += test.appUserModelId ? `|aumid:${test.appUserModelId}` : '';

return `(${configString})`;
};

describe(`Packaging ${getTestConfigString()}`, () => {
Expand All @@ -70,31 +75,65 @@ describe('Electron WIX MSI', () => {
});

describe(`Installing ${getTestConfigString()}`, () => {
before(async () => {
await kill(options.exe);
});
after(async () => {
await kill(options.exe);
});

const paths = getInstallPaths(options);

it('installs', async () => {
await install(msiPath);
const version = getWindowsCompliantVersion(options.version);
expect(await checkInstall(options.name, version)).ok();
});

it('has all files in program files', () => {
const paths = getInstallPaths(options);
console.log(paths);
expect(fs.pathExistsSync(paths.stubExe)).ok();
expectSameFolderContent(HARNESS_APP_DIR, paths.appFolder);
});

it('has shortcuts', () => {
const paths = getInstallPaths(options);
expect(fs.pathExistsSync(paths.startMenuShortcut)).ok();
expect(fs.pathExistsSync(paths.desktopShortcut)).ok();
});

it('has AppUserModelId', async () => {
const aumid = await readAppUserModelId(paths.startMenuShortcut);
expect(aumid).to.be(paths.appUserModelId);
});

const entryPoints = [
{ name: 'stubExe', path: paths.stubExe },
{ name: 'start menu shortcut', path: paths.startMenuShortcut },
{ name: 'desktop shortcut', path: paths.desktopShortcut },
];

entryPoints.forEach((entryPoint) => {
it(`runs the correct binary via ${entryPoint.name}`, async () => {
await launch(paths.startMenuShortcut);
expect(await runs(options.exe)).ok();
expect(await getProcessPath(options.exe)).to.be(paths.appExe);
await kill(options.exe);
});
});
});

const options124 = {
...options,
version: '1.2.4'
};
describe(`Updating ${getTestConfigString()}`, () => {
const options124 = {
...options,
version: '1.2.4'
};
before(async () => {
await kill(options.exe);
});
after(async () => {
await kill(options.exe);
});

const paths = getInstallPaths(options124);

it('updates', async () => {
await packageSampleApp(options124);
Expand All @@ -104,22 +143,40 @@ describe('Electron WIX MSI', () => {
});

it('has all files in program files', () => {
const paths = getInstallPaths(options124);
expect(fs.pathExistsSync(paths.stubExe)).ok();
expectSameFolderContent(HARNESS_APP_DIR, paths.appFolder);
});

it('has shortcuts', () => {
const paths = getInstallPaths(options124);
expect(fs.pathExistsSync(paths.startMenuShortcut)).ok();
expect(fs.pathExistsSync(paths.desktopShortcut)).ok();
});

const entryPoints = [
{ name: 'stubExe', path: paths.stubExe },
{ name: 'start menu shortcut', path: paths.startMenuShortcut },
{ name: 'desktop shortcut', path: paths.desktopShortcut },
];

entryPoints.forEach((entryPoint) => {
it(`runs the correct binary via ${entryPoint.name}`, async () => {
await launch(paths.startMenuShortcut);
expect(await runs(options.exe)).ok();
expect(await getProcessPath(options.exe)).to.be(paths.appExe);
await kill(options.exe);
});
});
});

describe(`Uninstalling ${getTestConfigString()}`, () => {
it('uninstalls', async () => {
const paths = getInstallPaths(options124);

await uninstall(msiPath);
expect(await checkInstall(options.name)).not.ok();
expect(fs.pathExistsSync(paths.appRootFolder)).not.ok();
expect(fs.pathExistsSync(paths.startMenuShortcut)).not.ok();
expect(fs.pathExistsSync(paths.desktopShortcut)).not.ok();
});
});
});
Expand Down
64 changes: 64 additions & 0 deletions e2e/src/utils/app-process.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import Shell from 'node-powershell';

export const launch = async (path: string) => {
const ps = new Shell({
executionPolicy: 'Bypass',
noProfile: true
});

try {
ps.addCommand(`try { Start-Process "${path}" -ErrorAction Stop } catch {}`);
await ps.invoke();
} finally {
ps.dispose();
}
};

export const runs = async (name: string) => {
const ps = new Shell({
executionPolicy: 'Bypass',
noProfile: true
});

let process: string;
try {
ps.addCommand(`Get-Process ${name.replace('.exe', '')} -ErrorAction SilentlyContinue`);
process = await ps.invoke();
process = process.replace(/(\r\n|\n|\r)/gm, '');
} finally {
ps.dispose();
}
return process !== '';
};

export const getProcessPath = async (name: string) => {
const ps = new Shell({
executionPolicy: 'Bypass',
noProfile: true
});

let processPath: string;
try {
ps.addCommand(`$p = Get-Process ${name.replace('.exe', '')} -ErrorAction SilentlyContinue | Select -First 1`);
ps.addCommand(`$p.Path`);
processPath = await ps.invoke();
processPath = processPath.replace(/(\r\n|\n|\r)/gm, '');
} finally {
ps.dispose();
}
return processPath;
};

export const kill = async (name: string) => {
const ps = new Shell({
executionPolicy: 'Bypass',
noProfile: true
});

try {
ps.addCommand(`Get-Process ${name.replace('.exe', '')} -ErrorAction SilentlyContinue | kill -ErrorAction SilentlyContinue`);
await ps.invoke();
} finally {
ps.dispose();
}
};
Binary file added e2e/src/utils/bin/Lnkspector.exe
Binary file not shown.
7 changes: 7 additions & 0 deletions e2e/src/utils/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import { MSICreatorOptions } from '../../../lib/index';
export interface InstallPaths {
appRootFolder: string;
appFolder: string;
appExe: string;
stubExe: string;
startMenuShortcut: string;
desktopShortcut: string;
appUserModelId: string;
}

export const install = async (msi: string) => {
Expand Down Expand Up @@ -61,12 +63,17 @@ export const checkInstall = async (name: string, version?: string) => {
export const getInstallPaths = (options: MSICreatorOptions): InstallPaths => {
const programFiles = options.arch === 'x64' || options.arch === 'ia64' ? process.env.ProgramFiles! : process.env['ProgramFiles(x86)']!;
const appRootFolder = path.join(programFiles, options.name);

const shortName = options.shortName || options.name;
const appUserModelId = options.appUserModelId || `com.squirrel.${shortName}.${options.exe.replace(/\.exe$/, '')}`;
return {
appRootFolder,
stubExe: path.join(appRootFolder, options.exe),
appFolder: path.join(appRootFolder, `app-${options.version}`),
appExe: path.join(appRootFolder, `app-${options.version}`, options.exe),
startMenuShortcut: path.join(process.env.ProgramData!, `Microsoft/Windows/Start Menu/Programs/${options.shortcutFolderName || options.manufacturer}/${options.shortcutName || options.name}.lnk`),
desktopShortcut: path.join(process.env.Public!, `Desktop/${options.shortcutName || options.name}.lnk`),
appUserModelId,
};
};

8 changes: 8 additions & 0 deletions e2e/src/utils/lnk-inspector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import path from 'path';
import { spawnPromise } from 'spawn-rx';

export const readAppUserModelId = async (lnkPath: string) => {
const lnkspector = path.join(__dirname, '../../src/utils/bin/Lnkspector.exe');
const aumid = await spawnPromise(lnkspector, ['-aumid', lnkPath]);
return aumid.replace(/(\r\n|\n|\r)/gm, '');
};

0 comments on commit 051288a

Please sign in to comment.