11import 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 */
1924export 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}
0 commit comments