Skip to content

Commit 52e6214

Browse files
authored
chore(e2e): make sure setEnv works the same way in browser and desktop (#7542)
* chore(e2e): make sure setEnv works the same way in browser and desktop * chore(e2e): account for smoke tests not having new ipc event handler * fix(e2e): add skip in another init in autoupdate tests
1 parent deeea51 commit 52e6214

File tree

9 files changed

+102
-56
lines changed

9 files changed

+102
-56
lines changed
Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { CompassBrowser } from '../compass-browser';
2-
import { isTestingWeb } from '../test-runner-context';
2+
import { inspect } from 'util';
33

44
/**
5-
* Sets an environment variable override in Compass Web.
6-
* This is only supported in Compass Web tests, not in Compass Desktop.
5+
* Sets an environment variable override in Compass, both web and desktop.
6+
* Requires an application to be running already to be used, so make sure that
7+
* the env variables you are changing are accessed dynamically in the
8+
* application runtime after initialization
79
*
810
* @example
911
* // Set the Atlas service URL override in a test
@@ -12,32 +14,64 @@ import { isTestingWeb } from '../test-runner-context';
1214
* mockAtlasServer.endpoint
1315
* );
1416
*
15-
* @param browser - The CompassBrowser instance
16-
* @param key - The environment variable name
17-
* @param value - The environment variable value
17+
* @param browser The CompassBrowser instance
18+
* @param key The environment variable name
19+
* @param value The environment variable value
20+
* @param dangerouslySkipWaitFor If true will not wait for process.env value in the app to
21+
* equal requested value. This is not recommended, don't use it unless you know
22+
* what you're doing
1823
*/
1924
export async function setEnv(
2025
browser: CompassBrowser,
2126
key: string,
22-
value: string
27+
value: string,
28+
dangerouslySkipWaitFor?: boolean
2329
): Promise<void> {
24-
if (isTestingWeb()) {
25-
// When running in Compass web we use a global function to set env vars
26-
await browser.execute(
27-
(_key, _value) => {
28-
const kSandboxSetEnvFn = Symbol.for('@compass-web-sandbox-set-env');
29-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
30-
(globalThis as any)[kSandboxSetEnvFn]?.(_key, _value);
31-
},
32-
key,
33-
value
30+
let latestValue: string | undefined;
31+
try {
32+
await browser.waitUntil(async () => {
33+
try {
34+
latestValue = await browser.execute(
35+
async (_key, _value) => {
36+
// If process is available in global scope, we're in desktop
37+
if ('process' in globalThis) {
38+
process.env[_key] = _value;
39+
// eslint-disable-next-line @typescript-eslint/no-require-imports
40+
return await require('electron').ipcRenderer.invoke(
41+
'compass:set-process-env',
42+
_key,
43+
_value
44+
);
45+
} else {
46+
const kProcessEnv = Symbol.for(
47+
'@compass-web-sandbox-process-env'
48+
);
49+
(globalThis as any)[kProcessEnv][_key] = _value;
50+
return (globalThis as any)[kProcessEnv][_key];
51+
}
52+
},
53+
key,
54+
value
55+
);
56+
// null and undefined are the same when sending values through
57+
// browser.execute
58+
// eslint-disable-next-line eqeqeq
59+
return latestValue == value;
60+
} catch {
61+
// Either ipcRenderer.invoke or trying to set the value on undefined
62+
// will fail inside browser.execute, this is a good indicator that the
63+
// app is not ready yet for setEnv to be called. Return `false` to wait
64+
// a bit more
65+
return dangerouslySkipWaitFor ?? false;
66+
}
67+
});
68+
} catch (err) {
69+
throw new Error(
70+
`Failed to set process.env.${key}: expected new value to be ${inspect(
71+
value
72+
)}, got ${inspect(latestValue)}. Original error:\n\n${
73+
(err as Error).message
74+
}`
3475
);
35-
return;
3676
}
37-
38-
// When running in Compass desktop, we can't dynamically change env vars
39-
// after the process has started, so we throw an error
40-
throw new Error(
41-
'setEnv is only supported in Compass web. For Compass desktop, set environment variables before starting the app.'
42-
);
4377
}

packages/compass-e2e-tests/helpers/compass.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ interface StartCompassOptions {
425425
firstRun?: boolean;
426426
extraSpawnArgs?: string[];
427427
wrapBinary?: (binary: string) => Promise<string> | string;
428+
dangerouslySkipSharedConfigWaitFor?: boolean;
428429
}
429430

430431
let defaultUserDataDir: string | undefined;
@@ -655,10 +656,6 @@ async function startCompassElectron(
655656
process.env.HADRON_PRODUCT_NAME_OVERRIDE = 'MongoDB Compass WebdriverIO';
656657
}
657658

658-
// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
659-
// browser.scrollToVirtualItem() to work with it
660-
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING = 'true';
661-
662659
const options = {
663660
automationProtocol: 'webdriver' as const,
664661
capabilities: {
@@ -1076,7 +1073,10 @@ function augmentError(error: Error, stack: string) {
10761073
error.stack = `${error.stack ?? ''}\nvia ${strippedLines.join('\n')}`;
10771074
}
10781075

1079-
async function setSharedConfigOnStart(browser: CompassBrowser) {
1076+
async function setSharedConfigOnStart(
1077+
browser: CompassBrowser,
1078+
dangerouslySkipSharedConfigWaitFor = false
1079+
) {
10801080
// Guide cues might affect too many tests in a way where the auto showing of
10811081
// the cue prevents clicks from working on elements. Dealing with this
10821082
// case-by-case is way too much work, so we disable the cues completely for
@@ -1094,6 +1094,14 @@ async function setSharedConfigOnStart(browser: CompassBrowser) {
10941094
// Compass in a way where changing this config is not allowed
10951095
return true;
10961096
});
1097+
1098+
// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
1099+
// browser.scrollToVirtualItem() to work with it
1100+
await browser.setEnv(
1101+
'COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING',
1102+
'true',
1103+
dangerouslySkipSharedConfigWaitFor
1104+
);
10971105
}
10981106

10991107
export async function init(
@@ -1112,7 +1120,10 @@ export async function init(
11121120

11131121
const { browser } = compass;
11141122

1115-
await setSharedConfigOnStart(browser);
1123+
await setSharedConfigOnStart(
1124+
browser,
1125+
opts.dangerouslySkipSharedConfigWaitFor
1126+
);
11161127

11171128
if (TEST_COMPASS_WEB) {
11181129
// larger window for more consistent results

packages/compass-e2e-tests/helpers/test-runner-global-fixtures.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,6 @@ export async function mochaGlobalSetup(this: Mocha.Runner) {
9393
if (isTestingWeb(context) && !isTestingAtlasCloudExternal(context)) {
9494
debug('Starting Compass Web server ...');
9595

96-
// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
97-
// browser.scrollToVirtualItem() to work with it
98-
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING = 'true';
99-
10096
if (isTestingAtlasCloudSandbox(context)) {
10197
const compassWeb = await spawnCompassWebSandboxAndSignInToAtlas(
10298
{

packages/compass-e2e-tests/tests/auto-update.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ describe('Auto-update', function () {
2424

2525
// run the app and wait for it to auto-update
2626
console.log('starting compass the first time');
27-
const compass = await init(testName, { firstRun: true });
27+
const compass = await init(testName, {
28+
firstRun: true,
29+
// smoketests that are running this suite are using the version of the
30+
// compass that doesn't have the methods needed to set env in shared
31+
// config. It's safe to skip taking into account the test being used
32+
dangerouslySkipSharedConfigWaitFor: true,
33+
});
2834
const { browser } = compass;
2935
try {
3036
await browser.$(Selectors.AutoUpdateToast).waitForDisplayed();
@@ -77,6 +83,10 @@ describe('Auto-update', function () {
7783
// run the app again and check that the version changed
7884
const compass = await init(`${testName} restart`, {
7985
firstRun: false,
86+
// smoketests that are running this suite are using the version of the
87+
// compass that doesn't have the methods needed to set env in shared
88+
// config. It's safe to skip taking into account the test being used
89+
dangerouslySkipSharedConfigWaitFor: true,
8090
});
8191
const { browser } = compass;
8292
try {

packages/compass-web/polyfills/process/index.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,4 @@ import hrtime from 'browser-process-hrtime';
66
(process as any).platform = 'Unknown';
77
(process as any).arch = 'Unknown';
88

9-
// Allow e2e tests to override environment variables
10-
if (process.env.APP_ENV === 'webdriverio') {
11-
const kSandboxSetEnvFn = Symbol.for('@compass-web-sandbox-set-env');
12-
// eslint-disable-next-line no-console
13-
console.info(
14-
`[compass-web sandbox] call window[Symbol.for('@compass-web-sandbox-set-env')]('KEY', 'value') to dynamically set environment variables`
15-
);
16-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17-
(globalThis as any)[kSandboxSetEnvFn] = (key: string, value: string) => {
18-
process.env[key] = value;
19-
};
20-
}
21-
229
export { process };

packages/compass-web/sandbox/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { useAtlasProxySignIn } from './sandbox-atlas-sign-in';
1414
import { sandboxConnectionStorage } from './sandbox-connection-storage';
1515
import { useWorkspaceTabRouter } from './sandbox-workspace-tab-router';
1616
import { SandboxPreferencesGlobalAccessProvider } from '../src/preferences';
17+
import './sandbox-process';
1718

1819
const sandboxContainerStyles = css({
1920
width: '100%',
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const kSandboxProcessEnv = Symbol.for('@compass-web-sandbox-process-env');
2+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3+
(globalThis as any)[kSandboxProcessEnv] = process.env;
4+
// eslint-disable-next-line no-console
5+
console.info(
6+
`[compass-web sandbox] call window[Symbol.for('@compass-web-sandbox-process-env')] to get access to process.env`
7+
);

packages/compass-web/webpack.config.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,6 @@ module.exports = (env, args) => {
165165
),
166166
}
167167
: {}),
168-
...(process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING
169-
? {
170-
'process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING':
171-
JSON.stringify(
172-
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING
173-
),
174-
}
175-
: {}),
176168
}),
177169

178170
new webpack.ProvidePlugin({

packages/compass/src/main/application.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,14 @@ class CompassApplication {
295295
ipcMain?.handle('compass:mainProcessPid', () => {
296296
return process.pid;
297297
});
298+
299+
ipcMain?.handle(
300+
'compass:set-process-env',
301+
(_evt, key: string, value: string) => {
302+
process.env[key] = value;
303+
return process.env[key];
304+
}
305+
);
298306
}
299307

300308
private static async setupLogging(): Promise<void> {

0 commit comments

Comments
 (0)