import { Arch, Platform } from "electron-builder"
import { copyFile, writeFile } from "fs-extra"
import * as path from "path"
import { assertThat } from "../helpers/fileAssert"
import { app, assertPack, copyTestAsset, modifyPackageJson } from "../helpers/packTester"
import { checkHelpers, doTest, expectUpdateMetadata } from "../helpers/winHelper"
const nsisTarget = Platform.WINDOWS.createTarget(["nsis"], Arch.x64)
function pickSnapshotDefines(defines: any) {
return {
APP_32_NAME: defines.APP_32_NAME,
APP_64_NAME: defines.APP_64_NAME,
APP_ARM64_NAME: defines.APP_ARM64_NAME,
APP_FILENAME: defines.APP_FILENAME,
APP_ID: defines.APP_ID,
APP_PACKAGE_NAME: defines.APP_PACKAGE_NAME,
APP_PRODUCT_FILENAME: defines.APP_PRODUCT_FILENAME,
COMPANY_NAME: defines.COMPANY_NAME,
ONE_CLICK: defines.ONE_CLICK,
PRODUCT_FILENAME: defines.PRODUCT_FILENAME,
PRODUCT_NAME: defines.PRODUCT_NAME,
SHORTCUT_NAME: defines.SHORTCUT_NAME,
UNINSTALL_DISPLAY_NAME: defines.UNINSTALL_DISPLAY_NAME,
}
}
test("one-click", ({ expect }) =>
app(
expect,
{
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.x64),
config: {
win: {
signtoolOptions: {
publisherName: "Foo, Inc",
},
},
publish: {
provider: "generic",
url: "https://develar.s3.amazonaws.com/test/${os}/${arch}",
},
nsis: {
deleteAppDataOnUninstall: true,
packElevateHelper: false,
},
electronFuses: {
runAsNode: true,
enableCookieEncryption: true,
enableNodeOptionsEnvironmentVariable: true,
enableNodeCliInspectArguments: true,
enableEmbeddedAsarIntegrityValidation: true,
onlyLoadAppFromAsar: true,
loadBrowserProcessSpecificV8Snapshot: true,
grantFileProtocolExtraPrivileges: undefined,
},
},
},
{
signedWin: true,
packed: async context => {
await checkHelpers(expect, context.getResources(Platform.WINDOWS, Arch.x64), false)
await doTest(expect, context.outDir, true, "TestApp Setup", "TestApp", null, false)
await expectUpdateMetadata(expect, context, Arch.x64, true)
},
}
))
test("custom guid", ({ expect }) =>
app(expect, {
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32),
config: {
appId: "boo",
productName: "boo Hub",
publish: null,
nsis: {
guid: "Foo Technologies\\Bar",
},
},
}))
test("multi language license", ({ expect }) =>
app(
expect,
{
targets: Platform.WINDOWS.createTarget("nsis", Arch.x64),
config: {
publish: null,
nsis: {
uninstallDisplayName: "Hi!!!",
createDesktopShortcut: false,
},
},
},
{
projectDirCreated: projectDir => {
return Promise.all([
writeFile(path.join(projectDir, "build", "license_en.txt"), "Hi"),
writeFile(path.join(projectDir, "build", "license_ru.txt"), "Привет"),
writeFile(path.join(projectDir, "build", "license_ko.txt"), "Привет"),
writeFile(path.join(projectDir, "build", "license_fi.txt"), "Привет"),
])
},
}
))
test("html license", ({ expect }) =>
app(
expect,
{
targets: Platform.WINDOWS.createTarget("nsis", Arch.x64),
config: {
publish: null,
nsis: {
uninstallDisplayName: "Hi!!!",
createDesktopShortcut: false,
},
},
},
{
projectDirCreated: projectDir => {
return Promise.all([
writeFile(path.join(projectDir, "build", "license.html"), '<html><body><p>Hi <a href="https://google.com" target="_blank">google</a></p></body></html>'),
])
},
}
))
test.ifDevOrWinCi("createDesktopShortcut always", ({ expect }) =>
app(expect, {
targets: Platform.WINDOWS.createTarget("nsis"),
config: {
publish: null,
nsis: {
createDesktopShortcut: "always",
},
},
})
)
test.ifDevOrLinuxCi("perMachine, no run after finish", ({ expect }) =>
app(
expect,
{
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32),
config: {
productName: "TestApp",
fileAssociations: [
{
ext: "foo",
name: "Test Foo",
},
],
nsis: {
perMachine: true,
runAfterFinish: false,
},
publish: {
provider: "generic",
url: "https://develar.s3.amazonaws.com/test/${os}/${arch}",
},
win: {
electronUpdaterCompatibility: ">=2.16",
},
},
},
{
projectDirCreated: projectDir => {
return Promise.all([
copyTestAsset("headerIcon.ico", path.join(projectDir, "build", "foo test space.ico")),
copyTestAsset("license.txt", path.join(projectDir, "build", "license.txt")),
])
},
packed: async context => {
await expectUpdateMetadata(expect, context)
await checkHelpers(expect, context.getResources(Platform.WINDOWS, Arch.ia32), true)
await doTest(expect, context.outDir, false)
},
}
)
)
test.skip("installerHeaderIcon", ({ expect }) => {
let headerIconPath: string | null = null
return assertPack(
expect,
"test-app-one",
{
targets: nsisTarget,
effectiveOptionComputed: async it => {
const defines = it[0]
expect(defines.HEADER_ICO).toEqual(headerIconPath)
return false
},
},
{
projectDirCreated: projectDir => {
headerIconPath = path.join(projectDir, "build", "installerHeaderIcon.ico")
return Promise.all([copyTestAsset("headerIcon.ico", headerIconPath), copyTestAsset("headerIcon.ico", path.join(projectDir, "build", "uninstallerIcon.ico"))])
},
}
)
})
test.ifDevOrLinuxCi("custom include", ({ expect }) =>
app(
expect,
{ targets: nsisTarget },
{
projectDirCreated: projectDir => copyTestAsset("installer.nsh", path.join(projectDir, "build", "installer.nsh")),
packed: context =>
Promise.all([
assertThat(expect, path.join(context.projectDir, "build", "customHeader")).isFile(),
assertThat(expect, path.join(context.projectDir, "build", "customInit")).isFile(),
assertThat(expect, path.join(context.projectDir, "build", "customInstall")).isFile(),
]),
}
)
)
test.skip("big file pack", ({ expect }) =>
app(
expect,
{
targets: nsisTarget,
config: {
extraResources: ["**/*.mov"],
nsis: {
differentialPackage: false,
},
},
},
{
projectDirCreated: async projectDir => {
await copyFile("/Volumes/Pegasus/15.02.18.m4v", path.join(projectDir, "foo/bar/video.mov"))
},
}
))
test.ifDevOrLinuxCi("custom script", ({ expect }) =>
app(
expect,
{ targets: nsisTarget },
{
projectDirCreated: projectDir => copyTestAsset("installer.nsi", path.join(projectDir, "build", "installer.nsi")),
packed: context => assertThat(expect, path.join(context.projectDir, "build", "customInstallerScript")).isFile(),
}
)
)
test("menuCategory", ({ expect }) =>
app(
expect,
{
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32),
config: {
extraMetadata: {
name: "test-menu-category",
productName: "Test Menu Category",
},
publish: null,
nsis: {
oneClick: false,
menuCategory: true,
artifactName: "${productName} CustomName ${version}.${ext}",
},
},
},
{
projectDirCreated: projectDir =>
modifyPackageJson(projectDir, data => {
data.name = "test-menu-category"
}),
packed: context => {
return doTest(expect, context.outDir, false, "Test Menu Category", "test-menu-category", "Foo Bar")
},
}
))
test("string menuCategory", ({ expect }) =>
app(
expect,
{
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32),
config: {
extraMetadata: {
name: "test-menu-category",
productName: "Test Menu Category '",
},
publish: null,
nsis: {
oneClick: false,
runAfterFinish: false,
menuCategory: "Foo/Bar",
artifactName: "${productName} CustomName ${version}.${ext}",
},
},
},
{
projectDirCreated: projectDir =>
modifyPackageJson(projectDir, data => {
data.name = "test-menu-category"
}),
packed: async context => {
await doTest(expect, context.outDir, false, "Test Menu Category", "test-menu-category", "Foo Bar")
},
}
))
test.ifDevOrLinuxCi("file associations per user", ({ expect }) =>
app(expect, {
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32),
config: {
publish: null,
fileAssociations: [
{
ext: "foo",
name: "Test Foo",
},
],
},
})
)
test.ifWindows.skip("custom exec name", ({ expect }) =>
app(expect, {
targets: nsisTarget,
config: {
productName: "foo",
win: {
executableName: "Boo",
},
electronFuses: {
runAsNode: true,
enableCookieEncryption: true,
enableNodeOptionsEnvironmentVariable: true,
enableNodeCliInspectArguments: true,
enableEmbeddedAsarIntegrityValidation: true,
onlyLoadAppFromAsar: true,
loadBrowserProcessSpecificV8Snapshot: true,
grantFileProtocolExtraPrivileges: undefined,
},
},
effectiveOptionComputed: async it => {
expect(pickSnapshotDefines(it[0])).toMatchSnapshot()
return false
},
})
)
test.ifWindows.skip("top-level custom exec name", ({ expect }) =>
app(expect, {
targets: nsisTarget,
config: {
publish: null,
productName: "foo",
executableName: "Boo",
},
effectiveOptionComputed: async it => {
expect(pickSnapshotDefines(it[0])).toMatchSnapshot()
return false
},
})
)