Skip to content

Commit 68ba830

Browse files
authored
Merge pull request #633 from mountaindude/sea
2 parents ca9f7f9 + d0d9c0f commit 68ba830

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2716
-1970
lines changed

README.md

Lines changed: 311 additions & 254 deletions
Large diffs are not rendered by default.

src/butler-sheet-icons.js

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,25 @@ const program = new Command();
7979
'--port <port>',
8080
'Qlik Sense http/https port. 443 is default for https, 80 for http'
8181
)
82-
.requiredOption('--schemaversion <string>', 'Qlik Sense engine schema version', '12.612.0')
83-
.requiredOption('--appid <id>', 'Qlik Sense app whose sheet icons should be modified.', '')
82+
.addOption(
83+
new Option('--schemaversion <version>', 'Qlik Sense engine schema version')
84+
.choices([
85+
'12.170.2',
86+
'12.612.0',
87+
'12.936.0',
88+
'12.1306.0',
89+
'12.1477.0',
90+
'12.1657.0',
91+
'12.1823.0',
92+
'12.2015.0',
93+
])
94+
.default('12.612.0')
95+
)
8496
.requiredOption(
8597
'--certfile <file>',
8698
'Qlik Sense certificate file (exported from QMC)',
8799
'./cert/client.pem'
88100
)
89-
.option(
90-
'--qliksensetag <value>',
91-
'Used to control which Sense apps should have their sheets updated with new icons. All apps with this tag will be updated.',
92-
''
93-
)
94101
.requiredOption(
95102
'--certkeyfile <file>',
96103
'Qlik Sense certificate key file (exported from QMC)',
@@ -101,7 +108,6 @@ const program = new Command();
101108
'Ignore warnings when Sense certificate does not match the --host paramater',
102109
false
103110
)
104-
.requiredOption('--prefix <prefix>', 'Qlik Sense virtual proxy prefix', '')
105111
.requiredOption(
106112
'--secure <true|false>',
107113
'Connection to Qlik Sense engine is via https',
@@ -124,6 +130,13 @@ const program = new Command();
124130
'User ID for user to connect with when logging into web UI'
125131
)
126132
.requiredOption('--logonpwd <password>', 'password for user to connect with')
133+
.requiredOption('--appid <id>', 'Qlik Sense app whose sheet icons should be modified.', '')
134+
.option(
135+
'--qliksensetag <value>',
136+
'Used to control which Sense apps should have their sheets updated with new icons. All apps with this tag will be updated.',
137+
''
138+
)
139+
.requiredOption('--prefix <prefix>', 'Qlik Sense virtual proxy prefix', '')
127140
.requiredOption(
128141
'--headless <true|false>',
129142
'Headless (=not visible) browser (true, false)',
@@ -205,8 +218,9 @@ const program = new Command();
205218
'2023-Nov',
206219
'2024-Feb',
207220
'2024-May',
221+
'2024-Nov',
208222
])
209-
.default('2024-May')
223+
.default('2024-Nov')
210224
)
211225
.addOption(
212226
new Option(
@@ -259,7 +273,20 @@ const program = new Command();
259273
'--port <port>',
260274
'Qlik Sense http/https port. 443 is default for https, 80 for http'
261275
)
262-
.requiredOption('--schemaversion <string>', 'Qlik Sense engine schema version', '12.612.0')
276+
.addOption(
277+
new Option('--schemaversion <version>', 'Qlik Sense engine schema version')
278+
.choices([
279+
'12.170.2',
280+
'12.612.0',
281+
'12.936.0',
282+
'12.1306.0',
283+
'12.1477.0',
284+
'12.1657.0',
285+
'12.1823.0',
286+
'12.2015.0',
287+
])
288+
.default('12.612.0')
289+
)
263290
.requiredOption('--appid <id>', 'Qlik Sense app whose sheet icons should be modified.', '')
264291
.option(
265292
'--qliksensetag <value>',
@@ -341,10 +368,19 @@ const program = new Command();
341368
.choices(['error', 'warn', 'info', 'verbose', 'debug', 'silly'])
342369
.default('info')
343370
)
344-
.requiredOption(
345-
'--schemaversion <string>',
346-
'Qlik Sense engine schema version',
347-
'12.612.0'
371+
.addOption(
372+
new Option('--schemaversion <version>', 'Qlik Sense engine schema version')
373+
.choices([
374+
'12.170.2',
375+
'12.612.0',
376+
'12.936.0',
377+
'12.1306.0',
378+
'12.1477.0',
379+
'12.1657.0',
380+
'12.1823.0',
381+
'12.2015.0',
382+
])
383+
.default('12.612.0')
348384
)
349385
.requiredOption(
350386
'--tenanturl <url>',
@@ -505,10 +541,19 @@ const program = new Command();
505541
.choices(['error', 'warn', 'info', 'verbose', 'debug', 'silly'])
506542
.default('info')
507543
)
508-
.requiredOption(
509-
'--schemaversion <string>',
510-
'Qlik Sense engine schema version',
511-
'12.612.0'
544+
.addOption(
545+
new Option('--schemaversion <version>', 'Qlik Sense engine schema version')
546+
.choices([
547+
'12.170.2',
548+
'12.612.0',
549+
'12.936.0',
550+
'12.1306.0',
551+
'12.1477.0',
552+
'12.1657.0',
553+
'12.1823.0',
554+
'12.2015.0',
555+
])
556+
.default('12.612.0')
512557
)
513558
.requiredOption(
514559
'--tenanturl <url>',

src/globals.js

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
11
const winston = require('winston');
22
const upath = require('upath');
3+
const sea = require('node:sea');
4+
const { readFileSync } = require('node:fs');
35

46
// Get app version from package.json file
5-
const appVersion = require('./package.json').version;
7+
const filenamePackage = `./src/package.json`;
8+
let a;
9+
let b;
10+
let c;
11+
let appVersion;
12+
13+
// Are we running as a packaged app?
14+
if (sea.isSea()) {
15+
// Get contents of package.json file
16+
packageJson = sea.getAsset('package.json', 'utf8');
17+
const version = JSON.parse(packageJson).version;
18+
19+
appVersion = version;
20+
} else {
21+
// Get path to JS file
22+
a = __filename;
23+
24+
// Strip off the filename
25+
b = upath.dirname(a);
26+
27+
// Add path to package.json file
28+
c = upath.join(b, '..', filenamePackage);
29+
30+
const { version } = JSON.parse(readFileSync(c));
31+
appVersion = version;
32+
}
633

734
// Set up logger with timestamps and colors, and optional logging to disk file
835
const logTransports = [];
@@ -31,7 +58,7 @@ const logger = winston.createLogger({
3158
});
3259

3360
// Suppported Chromium version: https://pptr.dev/chromium-support
34-
// Correlate with Correlate with https://chromium.woolyss.com to get revision number to get revision number
61+
// Correlate with https://chromium.woolyss.com to get revision number
3562
// const chromiumRevision = '1056772';
3663
// const chromiumRevisionLinux = '1056772';
3764
const chromiumRevisionLinux = '1109227';
@@ -67,18 +94,20 @@ const getChromiumRevision = () => {
6794
const getLoggingLevel = () => logTransports.find((transport) => transport.name === 'console').level;
6895

6996
/**
70-
*
97+
* Set the console logging level
7198
* @param {*} newLevel
7299
*/
73100
const setLoggingLevel = (newLevel) => {
74101
logTransports.find((transport) => transport.name === 'console').level = newLevel;
75102
};
76103

77-
const isPkg = typeof process.pkg !== 'undefined';
78-
const bsiExecutablePath = isPkg ? upath.dirname(process.execPath) : __dirname;
104+
/**
105+
* Booleann to indicate if we are running as a standalone app or not
106+
*/
107+
const isSea = sea.isSea();
108+
const bsiExecutablePath = isSea ? upath.dirname(process.execPath) : process.cwd();
79109

80110
function sleep(ms) {
81-
// eslint-disable-next-line no-promise-executor-return
82111
return new Promise((resolve) => setTimeout(resolve, ms));
83112
}
84113

@@ -87,7 +116,7 @@ module.exports = {
87116
appVersion,
88117
getLoggingLevel,
89118
setLoggingLevel,
90-
isPkg,
119+
isSea,
91120
bsiExecutablePath,
92121
getChromiumRevision,
93122
sleep,

src/img/do-not-delete

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
const { test, expect, describe } = require('@jest/globals');
2+
3+
const { browserInstalled } = require('../browser-installed.js');
4+
const { browserInstall } = require('../browser-install.js');
5+
const { browserUninstallAll } = require('../browser-uninstall.js');
6+
const defaultTestTimeout = process.env.BSI_TEST_TIMEOUT || 1800000; // 20 minute default timeout
7+
8+
console.log(`Jest timeout: ${defaultTestTimeout}`);
9+
10+
const options = {
11+
loglevel: process.env.BSI_LOG_LEVEL || 'info',
12+
};
13+
14+
describe('complex scenarios', () => {
15+
/**
16+
* Remove all installed browsers
17+
* Should return true.
18+
*
19+
* Install four differenct browsers (3 chrome versions, 1 firefox).
20+
* There should now be four installed browsers
21+
*
22+
* Remove all installed browsers.
23+
* Should return true.
24+
*
25+
* There should then be zero installed browsers.
26+
*/
27+
test(
28+
'install and uninstall several browsers',
29+
async () => {
30+
// Remove all installed browsers
31+
const uninstallRes1 = await browserUninstallAll(options);
32+
expect(uninstallRes1).toEqual(true);
33+
34+
// There should now be zero installed browsers
35+
const installedBrowsers1 = await browserInstalled(options);
36+
expect(installedBrowsers1.length).toEqual(0);
37+
38+
// Install four different browsers
39+
40+
// Latest Chrome from stable channel
41+
const browserInstallRes1 = await browserInstall({
42+
browser: 'chrome',
43+
browserVersion: 'latest',
44+
});
45+
expect(browserInstallRes1).toBeTruthy();
46+
47+
// From the beta channel
48+
const browserInstallRes2 = await browserInstall({
49+
browser: 'chrome',
50+
browserVersion: '121.0.6167.16',
51+
});
52+
expect(browserInstallRes2).toBeTruthy();
53+
54+
// From the dev channel
55+
const browserInstallRes3 = await browserInstall({
56+
browser: 'chrome',
57+
browserVersion: '123.0.6286.0',
58+
});
59+
expect(browserInstallRes3).toBeTruthy();
60+
61+
const browserInstallRes4 = await browserInstall({
62+
browser: 'firefox',
63+
browserVersion: 'latest',
64+
}); // Same as previous, should not install another browser
65+
expect(browserInstallRes4).toBeTruthy();
66+
67+
// There should now be four installed browsers
68+
const installedBrowsers2 = await browserInstalled(options);
69+
expect(installedBrowsers2.length).toEqual(4);
70+
71+
// Remove all installed browsers
72+
const uninstallRes2 = await browserUninstallAll(options);
73+
expect(uninstallRes2).toEqual(true);
74+
75+
// There should now be zero installed browsers
76+
const installedBrowsers3 = await browserInstalled(options);
77+
expect(installedBrowsers3.length).toEqual(0);
78+
},
79+
defaultTestTimeout
80+
);
81+
});
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
const { test, expect, describe } = require('@jest/globals');
2+
3+
// Mock the browser-install module
4+
// jest.mock('../browser-install', () => ({
5+
// browserInstall: jest.fn(),
6+
// }));
7+
8+
// Also mock the browser-installed module
9+
// jest.mock('../browser-installed', () => ({
10+
// browserInstalled: jest.fn().mockResolvedValue([]),
11+
// }));
12+
13+
const { browserInstalled } = require('../browser-installed.js');
14+
const { browserInstall } = require('../browser-install.js');
15+
const { browserUninstallAll } = require('../browser-uninstall.js');
16+
const defaultTestTimeout = process.env.BSI_TEST_TIMEOUT || 1800000; // 20 minute default timeout
17+
18+
console.log(`Jest timeout: ${defaultTestTimeout}`);
19+
20+
const options = {
21+
loglevel: process.env.BSI_LOG_LEVEL || 'info',
22+
};
23+
24+
describe('edge cases and error handling', () => {
25+
/**
26+
* Test invalid browser input
27+
* Should throw an error.
28+
*/
29+
test(
30+
'install an invalid browser name',
31+
async () => {
32+
await expect(
33+
browserInstall({ browser: 'invalid-browser', browserVersion: 'latest' })
34+
).rejects.toThrow();
35+
},
36+
defaultTestTimeout
37+
);
38+
39+
/**
40+
* Test missing environment variables
41+
* Should use default values.
42+
*/
43+
test(
44+
'missing environment variables',
45+
async () => {
46+
delete process.env.BSI_TEST_TIMEOUT;
47+
delete process.env.BSI_LOG_LEVEL;
48+
49+
const installedBrowsers = await browserInstalled({});
50+
expect(installedBrowsers).toBeDefined();
51+
},
52+
defaultTestTimeout
53+
);
54+
55+
/**
56+
* Test concurrent browser installations
57+
* Should handle concurrency correctly.
58+
*/
59+
test(
60+
'concurrent browser installations',
61+
async () => {
62+
const installPromises = [
63+
browserInstall({ browser: 'chrome', browserVersion: 'latest' }),
64+
browserInstall({ browser: 'firefox', browserVersion: 'latest' }),
65+
];
66+
67+
const results = await Promise.all(installPromises);
68+
results.forEach((result) => expect(result).toBeTruthy());
69+
70+
const installedBrowsers = await browserInstalled(options);
71+
expect(installedBrowsers.length).toBeGreaterThanOrEqual(2);
72+
73+
// Cleanup
74+
await browserUninstallAll(options);
75+
},
76+
defaultTestTimeout
77+
);
78+
});

0 commit comments

Comments
 (0)