Skip to content

Commit 4602aa9

Browse files
feat: add support for async fetching inside config (#823)
* read config file async * fix test * update test * added tests * fix tests and code * update type * Update src/common_types.ts --------- Co-authored-by: vigneshshanmugam <[email protected]>
1 parent f81aa09 commit 4602aa9

File tree

7 files changed

+139
-22
lines changed

7 files changed

+139
-22
lines changed

__tests__/config.test.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ const FIXTURES_DIR = join(__dirname, 'fixtures');
3333
describe('Config', () => {
3434
it('read config based on environment', async () => {
3535
const configPath = join(FIXTURES_DIR, 'synthetics.config.ts');
36-
expect(readConfig('development', configPath)).toMatchObject({
36+
expect(await readConfig('development', configPath)).toMatchObject({
3737
params: {
3838
url: 'dev',
3939
},
4040
playwrightOptions: {
4141
...devices['Galaxy S9+'],
4242
},
4343
});
44-
expect(readConfig('testing', configPath)).toMatchObject({
44+
expect(await readConfig('testing', configPath)).toMatchObject({
4545
params: {
4646
url: 'non-dev',
4747
},
@@ -50,15 +50,35 @@ describe('Config', () => {
5050

5151
it('throw error when config does not exist', async () => {
5252
const tempPath = generateTempPath();
53-
function getConfig() {
54-
readConfig('development', tempPath);
55-
}
56-
expect(getConfig).toThrowError(
53+
expect(readConfig('development', tempPath)).rejects.toThrow(
5754
new Error('Synthetics config file does not exist: ' + tempPath)
5855
);
5956
});
6057

6158
it('recursively look for configs and exit', async () => {
62-
expect(readConfig('development')).toEqual({});
59+
expect(await readConfig('development')).toEqual({});
60+
});
61+
62+
describe('read config async', () => {
63+
it('merge async config', async () => {
64+
const configPath = join(FIXTURES_DIR, 'async-params.config.ts');
65+
expect(await readConfig('development', configPath)).toMatchObject({
66+
params: {
67+
url: 'dev',
68+
},
69+
});
70+
expect(await readConfig('testing', configPath)).toMatchObject({
71+
params: {
72+
url: 'non-dev',
73+
},
74+
});
75+
});
76+
77+
it('catch errors on async config', async () => {
78+
const configPath = join(FIXTURES_DIR, 'async-params-err.config.ts');
79+
expect(readConfig('development', configPath)).rejects.toThrow(
80+
'failed to fetch params'
81+
);
82+
});
6383
});
6484
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* MIT License
3+
*
4+
* Copyright (c) 2020-present, Elastic NV
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
*/
25+
26+
import type { SyntheticsConfig } from '../../src';
27+
28+
const getParams = async () => {
29+
// return delayed error promise to simulate async
30+
return new Promise<Record<string, string>>((_, reject) => {
31+
reject(new Error('failed to fetch params'));
32+
});
33+
};
34+
35+
module.exports = async env => {
36+
const config: SyntheticsConfig = {
37+
params: await getParams(),
38+
};
39+
if (env !== 'development' && config.params) {
40+
config.params.url = 'non-dev';
41+
}
42+
return config;
43+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* MIT License
3+
*
4+
* Copyright (c) 2020-present, Elastic NV
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
*/
25+
26+
import type { SyntheticsConfig } from '../../src';
27+
28+
const getParams = async () => {
29+
// resolve with delayed promise to simulate async
30+
return new Promise<Record<string, string>>(resolve => {
31+
setTimeout(() => resolve({ url: 'dev' }));
32+
});
33+
};
34+
35+
export default async env => {
36+
const config: SyntheticsConfig = {
37+
params: await getParams(),
38+
};
39+
if (env !== 'development' && config.params) {
40+
config.params.url = 'non-dev';
41+
}
42+
return config;
43+
};

__tests__/options.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { normalizeOptions } from '../src/options';
2828
import { join } from 'path';
2929

3030
describe('options', () => {
31-
it('normalize', () => {
31+
it('normalize', async () => {
3232
const cliArgs: CliArgs = {
3333
params: {
3434
foo: 'bar',
@@ -43,12 +43,12 @@ describe('options', () => {
4343
pauseOnError: true,
4444
config: join(__dirname, 'fixtures', 'synthetics.config.ts'),
4545
};
46-
expect(normalizeOptions({})).toMatchObject({
46+
expect(await normalizeOptions({})).toMatchObject({
4747
environment: 'test',
4848
params: {},
4949
screenshots: 'on',
5050
});
51-
expect(normalizeOptions(cliArgs)).toMatchObject({
51+
expect(await normalizeOptions(cliArgs)).toMatchObject({
5252
dryRun: true,
5353
environment: 'test',
5454
match: 'check*',
@@ -76,9 +76,9 @@ describe('options', () => {
7676
});
7777
});
7878

79-
it('normalize monitor configs', () => {
79+
it('normalize monitor configs', async () => {
8080
const config = join(__dirname, 'fixtures', 'synthetics.config.ts');
81-
expect(normalizeOptions({ config }, 'push')).toMatchObject({
81+
expect(await normalizeOptions({ config }, 'push')).toMatchObject({
8282
screenshots: 'off',
8383
schedule: 10,
8484
privateLocations: ['test-location'],
@@ -94,7 +94,7 @@ describe('options', () => {
9494
});
9595

9696
expect(
97-
normalizeOptions(
97+
await normalizeOptions(
9898
{
9999
config,
100100
schedule: 3,
@@ -120,14 +120,14 @@ describe('options', () => {
120120
});
121121
});
122122

123-
it('cli arg headless override playwright headless arg', () => {
123+
it('cli arg headless override playwright headless arg', async () => {
124124
const cliArgs: CliArgs = {
125125
playwrightOptions: {
126126
headless: false,
127127
},
128128
headless: true,
129129
};
130-
expect(normalizeOptions(cliArgs)).toMatchObject({
130+
expect(await normalizeOptions(cliArgs)).toMatchObject({
131131
playwrightOptions: {
132132
headless: true,
133133
},

src/cli.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ program
134134
.action(async (cliArgs: CliArgs) => {
135135
const tearDown = await globalSetup(cliArgs, program.args);
136136
try {
137-
const options = normalizeOptions(cliArgs, 'run');
137+
const options = await normalizeOptions(cliArgs, 'run');
138138
const results = await run(options);
139139
/**
140140
* Exit with error status if any journey fails
@@ -196,14 +196,14 @@ program
196196
]);
197197
try {
198198
const settings = await loadSettings();
199-
const options = normalizeOptions(
199+
const options = (await normalizeOptions(
200200
{
201201
...program.opts(),
202202
...settings,
203203
...cmdOpts,
204204
},
205205
'push'
206-
) as PushOptions;
206+
)) as PushOptions;
207207
await validatePush(options, settings);
208208
const monitors = runner.buildMonitors(options);
209209
if ((options as CliArgs).throttling == null) {

src/config.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ import { isAbsolute, resolve, dirname } from 'path';
2727
import { SyntheticsConfig } from './common_types';
2828
import { isFile } from './helpers';
2929

30-
export function readConfig(env: string, config?: string): SyntheticsConfig {
30+
export async function readConfig(
31+
env: string,
32+
config?: string
33+
): Promise<SyntheticsConfig> {
3134
let options = {};
3235
const cwd = process.cwd();
3336
/**
@@ -47,6 +50,14 @@ export function readConfig(env: string, config?: string): SyntheticsConfig {
4750
}
4851
if (typeof options === 'function') {
4952
options = options(env);
53+
const optionsPromise = options as Promise<SyntheticsConfig>;
54+
if (
55+
optionsPromise != null &&
56+
typeof optionsPromise.then === 'function' &&
57+
typeof optionsPromise.catch === 'function'
58+
) {
59+
options = await optionsPromise;
60+
}
5061
}
5162
return options;
5263
}

src/options.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ import { THROTTLING_WARNING_MSG, error, warn } from './helpers';
3131

3232
type Mode = 'run' | 'push';
3333

34-
export function normalizeOptions(
34+
export async function normalizeOptions(
3535
cliArgs: CliArgs,
3636
mode: Mode = 'run'
37-
): RunOptions {
37+
): Promise<RunOptions> {
3838
const options: RunOptions = {
3939
...cliArgs,
4040
environment: process.env['NODE_ENV'] || 'development',
@@ -85,7 +85,7 @@ export function normalizeOptions(
8585
*/
8686
const config =
8787
cliArgs.config || !cliArgs.inline
88-
? readConfig(options.environment, cliArgs.config)
88+
? await readConfig(options.environment, cliArgs.config)
8989
: {};
9090

9191
/**

0 commit comments

Comments
 (0)