Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 58 additions & 24 deletions packages/compass-e2e-tests/helpers/commands/set-env.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { CompassBrowser } from '../compass-browser';
import { isTestingWeb } from '../test-runner-context';
import { inspect } from 'util';

/**
* Sets an environment variable override in Compass Web.
* This is only supported in Compass Web tests, not in Compass Desktop.
* Sets an environment variable override in Compass, both web and desktop.
* Requires an application to be running already to be used, so make sure that
* the env variables you are changing are accessed dynamically in the
* application runtime after initialization
*
* @example
* // Set the Atlas service URL override in a test
Expand All @@ -12,32 +14,64 @@ import { isTestingWeb } from '../test-runner-context';
* mockAtlasServer.endpoint
* );
*
* @param browser - The CompassBrowser instance
* @param key - The environment variable name
* @param value - The environment variable value
* @param browser The CompassBrowser instance
* @param key The environment variable name
* @param value The environment variable value
* @param dangerouslySkipWaitFor If true will not wait for process.env value in the app to
* equal requested value. This is not recommended, don't use it unless you know
* what you're doing
*/
export async function setEnv(
browser: CompassBrowser,
key: string,
value: string
value: string,
dangerouslySkipWaitFor?: boolean
): Promise<void> {
if (isTestingWeb()) {
// When running in Compass web we use a global function to set env vars
await browser.execute(
(_key, _value) => {
const kSandboxSetEnvFn = Symbol.for('@compass-web-sandbox-set-env');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any)[kSandboxSetEnvFn]?.(_key, _value);
},
key,
value
let latestValue: string | undefined;
try {
await browser.waitUntil(async () => {
try {
latestValue = await browser.execute(
async (_key, _value) => {
// If process is available in global scope, we're in desktop
if ('process' in globalThis) {
process.env[_key] = _value;
// eslint-disable-next-line @typescript-eslint/no-require-imports
return await require('electron').ipcRenderer.invoke(
'compass:set-process-env',
_key,
_value
);
} else {
const kProcessEnv = Symbol.for(
'@compass-web-sandbox-process-env'
);
(globalThis as any)[kProcessEnv][_key] = _value;
return (globalThis as any)[kProcessEnv][_key];
}
},
key,
value
);
// null and undefined are the same when sending values through
// browser.execute
// eslint-disable-next-line eqeqeq
return latestValue == value;
} catch {
// Either ipcRenderer.invoke or trying to set the value on undefined
// will fail inside browser.execute, this is a good indicator that the
// app is not ready yet for setEnv to be called. Return `false` to wait
// a bit more
return dangerouslySkipWaitFor ?? false;
}
});
} catch (err) {
throw new Error(
`Failed to set process.env.${key}: expected new value to be ${inspect(
value
)}, got ${inspect(latestValue)}. Original error:\n\n${
(err as Error).message
}`
);
return;
}

// When running in Compass desktop, we can't dynamically change env vars
// after the process has started, so we throw an error
throw new Error(
'setEnv is only supported in Compass web. For Compass desktop, set environment variables before starting the app.'
);
}
23 changes: 17 additions & 6 deletions packages/compass-e2e-tests/helpers/compass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ interface StartCompassOptions {
firstRun?: boolean;
extraSpawnArgs?: string[];
wrapBinary?: (binary: string) => Promise<string> | string;
dangerouslySkipSharedConfigWaitFor?: boolean;
}

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

// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
// browser.scrollToVirtualItem() to work with it
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING = 'true';

const options = {
automationProtocol: 'webdriver' as const,
capabilities: {
Expand Down Expand Up @@ -1076,7 +1073,10 @@ function augmentError(error: Error, stack: string) {
error.stack = `${error.stack ?? ''}\nvia ${strippedLines.join('\n')}`;
}

async function setSharedConfigOnStart(browser: CompassBrowser) {
async function setSharedConfigOnStart(
browser: CompassBrowser,
dangerouslySkipSharedConfigWaitFor = false
) {
// Guide cues might affect too many tests in a way where the auto showing of
// the cue prevents clicks from working on elements. Dealing with this
// case-by-case is way too much work, so we disable the cues completely for
Expand All @@ -1094,6 +1094,14 @@ async function setSharedConfigOnStart(browser: CompassBrowser) {
// Compass in a way where changing this config is not allowed
return true;
});

// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
// browser.scrollToVirtualItem() to work with it
await browser.setEnv(
'COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING',
'true',
dangerouslySkipSharedConfigWaitFor
);
}

export async function init(
Expand All @@ -1112,7 +1120,10 @@ export async function init(

const { browser } = compass;

await setSharedConfigOnStart(browser);
await setSharedConfigOnStart(
browser,
opts.dangerouslySkipSharedConfigWaitFor
);

if (TEST_COMPASS_WEB) {
// larger window for more consistent results
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,6 @@ export async function mochaGlobalSetup(this: Mocha.Runner) {
if (isTestingWeb(context) && !isTestingAtlasCloudExternal(context)) {
debug('Starting Compass Web server ...');

// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
// browser.scrollToVirtualItem() to work with it
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING = 'true';

if (isTestingAtlasCloudSandbox(context)) {
const compassWeb = await spawnCompassWebSandboxAndSignInToAtlas(
{
Expand Down
12 changes: 11 additions & 1 deletion packages/compass-e2e-tests/tests/auto-update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ describe('Auto-update', function () {

// run the app and wait for it to auto-update
console.log('starting compass the first time');
const compass = await init(testName, { firstRun: true });
const compass = await init(testName, {
firstRun: true,
// smoketests that are running this suite are using the version of the
// compass that doesn't have the methods needed to set env in shared
// config. It's safe to skip taking into account the test being used
dangerouslySkipSharedConfigWaitFor: true,
});
const { browser } = compass;
try {
await browser.$(Selectors.AutoUpdateToast).waitForDisplayed();
Expand Down Expand Up @@ -77,6 +83,10 @@ describe('Auto-update', function () {
// run the app again and check that the version changed
const compass = await init(`${testName} restart`, {
firstRun: false,
// smoketests that are running this suite are using the version of the
// compass that doesn't have the methods needed to set env in shared
// config. It's safe to skip taking into account the test being used
dangerouslySkipSharedConfigWaitFor: true,
});
const { browser } = compass;
try {
Expand Down
13 changes: 0 additions & 13 deletions packages/compass-web/polyfills/process/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,4 @@ import hrtime from 'browser-process-hrtime';
(process as any).platform = 'Unknown';
(process as any).arch = 'Unknown';

// Allow e2e tests to override environment variables
if (process.env.APP_ENV === 'webdriverio') {
const kSandboxSetEnvFn = Symbol.for('@compass-web-sandbox-set-env');
// eslint-disable-next-line no-console
console.info(
`[compass-web sandbox] call window[Symbol.for('@compass-web-sandbox-set-env')]('KEY', 'value') to dynamically set environment variables`
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any)[kSandboxSetEnvFn] = (key: string, value: string) => {
process.env[key] = value;
};
}

export { process };
1 change: 1 addition & 0 deletions packages/compass-web/sandbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useAtlasProxySignIn } from './sandbox-atlas-sign-in';
import { sandboxConnectionStorage } from './sandbox-connection-storage';
import { useWorkspaceTabRouter } from './sandbox-workspace-tab-router';
import { SandboxPreferencesGlobalAccessProvider } from '../src/preferences';
import './sandbox-process';

const sandboxContainerStyles = css({
width: '100%',
Expand Down
7 changes: 7 additions & 0 deletions packages/compass-web/sandbox/sandbox-process.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const kSandboxProcessEnv = Symbol.for('@compass-web-sandbox-process-env');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any)[kSandboxProcessEnv] = process.env;
// eslint-disable-next-line no-console
console.info(
`[compass-web sandbox] call window[Symbol.for('@compass-web-sandbox-process-env')] to get access to process.env`
);
8 changes: 0 additions & 8 deletions packages/compass-web/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,6 @@ module.exports = (env, args) => {
),
}
: {}),
...(process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING
? {
'process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING':
JSON.stringify(
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING
),
}
: {}),
}),

new webpack.ProvidePlugin({
Expand Down
8 changes: 8 additions & 0 deletions packages/compass/src/main/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,14 @@ class CompassApplication {
ipcMain?.handle('compass:mainProcessPid', () => {
return process.pid;
});

ipcMain?.handle(
'compass:set-process-env',
(_evt, key: string, value: string) => {
process.env[key] = value;
return process.env[key];
}
);
}

private static async setupLogging(): Promise<void> {
Expand Down
Loading