@grafana/plugin-e2e 3.0.0-canary.2093.18159570680.0 → 3.0.0-canary.2242.18774949404.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fixtures/page.js +4 -4
- package/dist/fixtures/scripts/overrideGrafanaBootData.js +30 -0
- package/dist/index.d.ts +131 -65
- package/dist/models/pages/PanelEditPage.js +2 -0
- package/dist/options.js +1 -0
- package/package.json +4 -4
- package/dist/fixtures/scripts/overrideFeatureToggles.js +0 -21
package/dist/fixtures/page.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var overrideGrafanaBootData = require('./scripts/overrideGrafanaBootData.js');
|
|
4
4
|
|
|
5
|
-
const page = async ({ page: page2, featureToggles }, use) => {
|
|
6
|
-
if (Object.keys(featureToggles).length > 0) {
|
|
5
|
+
const page = async ({ page: page2, featureToggles, userPreferences }, use) => {
|
|
6
|
+
if (Object.keys(featureToggles).length > 0 || Object.keys(userPreferences).length > 0) {
|
|
7
7
|
try {
|
|
8
|
-
await page2.addInitScript(
|
|
8
|
+
await page2.addInitScript(overrideGrafanaBootData.overrideGrafanaBootData, { featureToggles, userPreferences });
|
|
9
9
|
} catch (error) {
|
|
10
10
|
console.error("Failed to set feature toggles", error);
|
|
11
11
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const overrideGrafanaBootData = ({ featureToggles, userPreferences }) => {
|
|
4
|
+
const timeout = 1;
|
|
5
|
+
const waitForGrafanaBootData = (cb) => {
|
|
6
|
+
if (window?.grafanaBootData?.user) {
|
|
7
|
+
cb();
|
|
8
|
+
} else {
|
|
9
|
+
setTimeout(() => waitForGrafanaBootData(cb), timeout);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
waitForGrafanaBootData(() => {
|
|
13
|
+
if (Object.keys(featureToggles).length > 0) {
|
|
14
|
+
console.log("@grafana/plugin-e2e: setting the following feature toggles", featureToggles);
|
|
15
|
+
window.grafanaBootData.settings.featureToggles = {
|
|
16
|
+
...window.grafanaBootData.settings.featureToggles,
|
|
17
|
+
...featureToggles
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (Object.keys(userPreferences).length > 0) {
|
|
21
|
+
console.log("@grafana/plugin-e2e: setting the following user preferences", userPreferences);
|
|
22
|
+
window.grafanaBootData.user = {
|
|
23
|
+
...window.grafanaBootData.user,
|
|
24
|
+
...userPreferences
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
exports.overrideGrafanaBootData = overrideGrafanaBootData;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as _playwright_test from '@playwright/test';
|
|
2
2
|
import { Locator, Request, Response as Response$1, APIRequestContext, TestInfo, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, MatcherReturnType } from '@playwright/test';
|
|
3
3
|
export { selectors } from '@playwright/test';
|
|
4
|
-
import * as playwright_core from 'playwright-core';
|
|
5
4
|
import { SelectorsOf, versionedPages, versionedComponents } from '@grafana/e2e-selectors';
|
|
5
|
+
import * as playwright_core from 'playwright-core';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Base class for all Grafana pages.
|
|
@@ -57,6 +57,58 @@ declare class DataSourcePicker extends GrafanaPage {
|
|
|
57
57
|
set(name: string): Promise<void>;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
declare class AlertRuleQuery extends GrafanaPage {
|
|
61
|
+
readonly ctx: PluginTestCtx;
|
|
62
|
+
readonly locator: Locator;
|
|
63
|
+
datasource: DataSourcePicker;
|
|
64
|
+
constructor(ctx: PluginTestCtx, locator: Locator);
|
|
65
|
+
getByGrafanaSelector(selector: string, options?: getByGrafanaSelectorOptions): Locator;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare class AlertRuleEditPage extends GrafanaPage {
|
|
69
|
+
readonly ctx: PluginTestCtx;
|
|
70
|
+
readonly args?: AlertRuleArgs | undefined;
|
|
71
|
+
constructor(ctx: PluginTestCtx, args?: AlertRuleArgs | undefined);
|
|
72
|
+
/**
|
|
73
|
+
* Navigates to the annotation edit page. If a dashboard uid was not provided, it's assumed that it's a new dashboard.
|
|
74
|
+
*/
|
|
75
|
+
goto(options?: NavigateOptions): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Returns a locator for hte alert rule name field
|
|
78
|
+
*/
|
|
79
|
+
get alertRuleNameField(): _playwright_test.Locator;
|
|
80
|
+
get advancedModeSwitch(): _playwright_test.Locator;
|
|
81
|
+
isAdvancedModeSupported(): Promise<boolean>;
|
|
82
|
+
enableAdvancedQueryMode(): Promise<void>;
|
|
83
|
+
disableAdvancedQueryMode(): Promise<void>;
|
|
84
|
+
getQueryRow(refId?: string): Promise<AlertRuleQuery>;
|
|
85
|
+
/**
|
|
86
|
+
* @deprecated Use getQueryRow instead
|
|
87
|
+
* Returns an instance of the {@link AlertRuleQuery} class for a query in the query and expression step (step 2)
|
|
88
|
+
*
|
|
89
|
+
* @param refId is optional. If not provided, it will return query row with refId 'A' in Grafana versions <11.6.
|
|
90
|
+
* In Grafana versions >=11.6 where advanced mode is supported, it will return the default query if advanced mode
|
|
91
|
+
* is not enabled. If advanced mode is enabled, it will return the a query by refId.
|
|
92
|
+
*/
|
|
93
|
+
getAlertRuleQueryRow(refId?: string): AlertRuleQuery;
|
|
94
|
+
/**
|
|
95
|
+
* Clicks the "Add query" button and returns an instance of the {@link AlertRuleQuery} class for the new query row.
|
|
96
|
+
*
|
|
97
|
+
* Since Grafana 11.6, this method is only available if advanced mode is enabled. Use enableQueryAdvancedMode() method to enable it.
|
|
98
|
+
*/
|
|
99
|
+
clickAddQueryRow(): Promise<AlertRuleQuery>;
|
|
100
|
+
/**
|
|
101
|
+
* Clicks the evaluate button and waits for the evaluation to complete. If the evaluation is successful, the status code of the response is 200.
|
|
102
|
+
* If one or more queries are invalid, an error status code is returned.
|
|
103
|
+
*
|
|
104
|
+
* Note that this method intercepts the response of the alerting evaluation endpoint and returns the status code of the first failed query.
|
|
105
|
+
* This means that any mocks defined with page.route in your tests will be overriden.
|
|
106
|
+
*
|
|
107
|
+
* Only supported for Grafana version 9.5.0 ad later.
|
|
108
|
+
*/
|
|
109
|
+
evaluate(options?: RequestOptions): Promise<_playwright_test.Response>;
|
|
110
|
+
}
|
|
111
|
+
|
|
60
112
|
declare class AnnotationEditPage extends GrafanaPage {
|
|
61
113
|
readonly ctx: PluginTestCtx;
|
|
62
114
|
readonly args: DashboardEditViewArgs<string>;
|
|
@@ -378,6 +430,17 @@ declare class ExplorePage extends GrafanaPage {
|
|
|
378
430
|
runQuery(options?: RequestOptions): Promise<_playwright_test.Response>;
|
|
379
431
|
}
|
|
380
432
|
|
|
433
|
+
declare class GrafanaAPIClient {
|
|
434
|
+
private request;
|
|
435
|
+
constructor(request: APIRequestContext);
|
|
436
|
+
getUserIdByUsername(userName: string): Promise<any>;
|
|
437
|
+
createUser(user: User): Promise<void>;
|
|
438
|
+
getDataSourceSettingsByUID(uid: string): Promise<DataSourceSettings<{}, {}>>;
|
|
439
|
+
createDataSource(datasource: CreateDataSourceArgs, dsName: string): Promise<_playwright_test.APIResponse>;
|
|
440
|
+
getDataSourceByName(name: string): Promise<_playwright_test.APIResponse>;
|
|
441
|
+
deleteDataSourceByUID(uid: string): Promise<_playwright_test.APIResponse>;
|
|
442
|
+
}
|
|
443
|
+
|
|
381
444
|
type VariableType = 'Query' | 'Constant' | 'Custom';
|
|
382
445
|
declare class VariableEditPage extends GrafanaPage {
|
|
383
446
|
readonly ctx: PluginTestCtx;
|
|
@@ -416,69 +479,6 @@ declare class VariablePage extends GrafanaPage {
|
|
|
416
479
|
clickAddNew(): Promise<VariableEditPage>;
|
|
417
480
|
}
|
|
418
481
|
|
|
419
|
-
declare class AlertRuleQuery extends GrafanaPage {
|
|
420
|
-
readonly ctx: PluginTestCtx;
|
|
421
|
-
readonly locator: Locator;
|
|
422
|
-
datasource: DataSourcePicker;
|
|
423
|
-
constructor(ctx: PluginTestCtx, locator: Locator);
|
|
424
|
-
getByGrafanaSelector(selector: string, options?: getByGrafanaSelectorOptions): Locator;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
declare class AlertRuleEditPage extends GrafanaPage {
|
|
428
|
-
readonly ctx: PluginTestCtx;
|
|
429
|
-
readonly args?: AlertRuleArgs | undefined;
|
|
430
|
-
constructor(ctx: PluginTestCtx, args?: AlertRuleArgs | undefined);
|
|
431
|
-
/**
|
|
432
|
-
* Navigates to the annotation edit page. If a dashboard uid was not provided, it's assumed that it's a new dashboard.
|
|
433
|
-
*/
|
|
434
|
-
goto(options?: NavigateOptions): Promise<void>;
|
|
435
|
-
/**
|
|
436
|
-
* Returns a locator for hte alert rule name field
|
|
437
|
-
*/
|
|
438
|
-
get alertRuleNameField(): _playwright_test.Locator;
|
|
439
|
-
get advancedModeSwitch(): _playwright_test.Locator;
|
|
440
|
-
isAdvancedModeSupported(): Promise<boolean>;
|
|
441
|
-
enableAdvancedQueryMode(): Promise<void>;
|
|
442
|
-
disableAdvancedQueryMode(): Promise<void>;
|
|
443
|
-
getQueryRow(refId?: string): Promise<AlertRuleQuery>;
|
|
444
|
-
/**
|
|
445
|
-
* @deprecated Use getQueryRow instead
|
|
446
|
-
* Returns an instance of the {@link AlertRuleQuery} class for a query in the query and expression step (step 2)
|
|
447
|
-
*
|
|
448
|
-
* @param refId is optional. If not provided, it will return query row with refId 'A' in Grafana versions <11.6.
|
|
449
|
-
* In Grafana versions >=11.6 where advanced mode is supported, it will return the default query if advanced mode
|
|
450
|
-
* is not enabled. If advanced mode is enabled, it will return the a query by refId.
|
|
451
|
-
*/
|
|
452
|
-
getAlertRuleQueryRow(refId?: string): AlertRuleQuery;
|
|
453
|
-
/**
|
|
454
|
-
* Clicks the "Add query" button and returns an instance of the {@link AlertRuleQuery} class for the new query row.
|
|
455
|
-
*
|
|
456
|
-
* Since Grafana 11.6, this method is only available if advanced mode is enabled. Use enableQueryAdvancedMode() method to enable it.
|
|
457
|
-
*/
|
|
458
|
-
clickAddQueryRow(): Promise<AlertRuleQuery>;
|
|
459
|
-
/**
|
|
460
|
-
* Clicks the evaluate button and waits for the evaluation to complete. If the evaluation is successful, the status code of the response is 200.
|
|
461
|
-
* If one or more queries are invalid, an error status code is returned.
|
|
462
|
-
*
|
|
463
|
-
* Note that this method intercepts the response of the alerting evaluation endpoint and returns the status code of the first failed query.
|
|
464
|
-
* This means that any mocks defined with page.route in your tests will be overriden.
|
|
465
|
-
*
|
|
466
|
-
* Only supported for Grafana version 9.5.0 ad later.
|
|
467
|
-
*/
|
|
468
|
-
evaluate(options?: RequestOptions): Promise<_playwright_test.Response>;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
declare class GrafanaAPIClient {
|
|
472
|
-
private request;
|
|
473
|
-
constructor(request: APIRequestContext);
|
|
474
|
-
getUserIdByUsername(userName: string): Promise<any>;
|
|
475
|
-
createUser(user: User): Promise<void>;
|
|
476
|
-
getDataSourceSettingsByUID(uid: string): Promise<DataSourceSettings<{}, {}>>;
|
|
477
|
-
createDataSource(datasource: CreateDataSourceArgs, dsName: string): Promise<_playwright_test.APIResponse>;
|
|
478
|
-
getDataSourceByName(name: string): Promise<_playwright_test.APIResponse>;
|
|
479
|
-
deleteDataSourceByUID(uid: string): Promise<_playwright_test.APIResponse>;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
482
|
declare const versionedAPIs: {
|
|
483
483
|
Alerting: {
|
|
484
484
|
eval: {
|
|
@@ -584,6 +584,29 @@ type PluginOptions = {
|
|
|
584
584
|
* });
|
|
585
585
|
*/
|
|
586
586
|
featureToggles: Record<string, boolean>;
|
|
587
|
+
/**
|
|
588
|
+
* Optionally, you can add or override user preferences for the Grafana user.
|
|
589
|
+
* The user preferences you specify here will be applied to window.grafanaBootData.user.preferences object.
|
|
590
|
+
* Since all tests receive a new, isolated browser context, the user preferences will be reset for each test.
|
|
591
|
+
*
|
|
592
|
+
* This is only supported for Grafana 11 and later.
|
|
593
|
+
*
|
|
594
|
+
* @example
|
|
595
|
+
* ```typescript
|
|
596
|
+
* export default defineConfig({
|
|
597
|
+
* use: {
|
|
598
|
+
* userPreferences: {
|
|
599
|
+
* theme: 'dark',
|
|
600
|
+
* timezone: 'browser',
|
|
601
|
+
* weekStart: 'monday',
|
|
602
|
+
* language: 'en-US',
|
|
603
|
+
* regionalFormat: 'en',
|
|
604
|
+
* },
|
|
605
|
+
* },
|
|
606
|
+
* });
|
|
607
|
+
* ```
|
|
608
|
+
*/
|
|
609
|
+
userPreferences: UserPreferences;
|
|
587
610
|
/**
|
|
588
611
|
* The Grafana user to use for the tests. If no user is provided, the default admin/admin user will be used.
|
|
589
612
|
*
|
|
@@ -1094,6 +1117,49 @@ interface AlertPageOptions {
|
|
|
1094
1117
|
hasText?: string | RegExp;
|
|
1095
1118
|
}
|
|
1096
1119
|
type OrgRole = 'None' | 'Viewer' | 'Editor' | 'Admin';
|
|
1120
|
+
/**
|
|
1121
|
+
* User preferences configuration for tests.
|
|
1122
|
+
*
|
|
1123
|
+
* These preferences control various aspects of the Grafana user's
|
|
1124
|
+
* appearance and behavior during test execution.
|
|
1125
|
+
*/
|
|
1126
|
+
interface UserPreferences {
|
|
1127
|
+
/**
|
|
1128
|
+
* The theme to use for the user.
|
|
1129
|
+
*
|
|
1130
|
+
* @default 'dark'
|
|
1131
|
+
* @example 'dark' | 'light'
|
|
1132
|
+
*/
|
|
1133
|
+
theme?: 'dark' | 'light';
|
|
1134
|
+
/**
|
|
1135
|
+
* The timezone setting for the organization.
|
|
1136
|
+
*
|
|
1137
|
+
* @default 'browser'
|
|
1138
|
+
* @example 'browser' | 'utc' | 'America/New_York'
|
|
1139
|
+
*/
|
|
1140
|
+
timezone?: string;
|
|
1141
|
+
/**
|
|
1142
|
+
* The first day of the week for date pickers and calendars.
|
|
1143
|
+
*
|
|
1144
|
+
* @default 'sunday'
|
|
1145
|
+
* @example 'sunday' | 'monday'
|
|
1146
|
+
*/
|
|
1147
|
+
weekStart?: 'sunday' | 'monday';
|
|
1148
|
+
/**
|
|
1149
|
+
* The language/locale for the organization's UI.
|
|
1150
|
+
*
|
|
1151
|
+
* @default 'en-US'
|
|
1152
|
+
* @example 'en-US' | 'sv-SE' | 'de-DE'
|
|
1153
|
+
*/
|
|
1154
|
+
language?: string;
|
|
1155
|
+
/**
|
|
1156
|
+
* The regional format for numbers, dates, and currencies.
|
|
1157
|
+
*
|
|
1158
|
+
* @default 'en'
|
|
1159
|
+
* @example 'en' | 'sv' | 'de'
|
|
1160
|
+
*/
|
|
1161
|
+
regionalFormat?: string;
|
|
1162
|
+
}
|
|
1097
1163
|
/**
|
|
1098
1164
|
* Panel visualization types
|
|
1099
1165
|
*/
|
|
@@ -1222,4 +1288,4 @@ declare global {
|
|
|
1222
1288
|
}
|
|
1223
1289
|
|
|
1224
1290
|
export { AnnotationEditPage, AnnotationPage, AppConfigPage, AppPage, DashboardPage, DataSourceConfigPage, DataSourcePicker, ExplorePage, GrafanaPage, Panel, PanelEditPage, PluginConfigPage, TimeRange, VariableEditPage, VariablePage, expect, test };
|
|
1225
|
-
export type { AlertPageOptions, AlertRule, AlertRuleArgs, AlertVariant$1 as AlertVariant, AppPageNavigateOptions, ContainTextOptions, CreateDataSourceArgs, CreateDataSourcePageArgs, Credentials, Dashboard, DashboardEditViewArgs, DashboardPageArgs, DataSourceSettings, E2ESelectorGroups, GotoAppConfigPageArgs, GotoAppPageArgs, GrafanaPageArgs, NavigateOptions, OrgRole, PlaywrightArgs, PluginFixture, PluginOptions, PluginPageArgs, PluginTestCtx, ReadProvisionedAlertRuleArgs, ReadProvisionedDashboardArgs, ReadProvisionedDataSourceArgs, RequestOptions, TimeRangeArgs, TriggerRequestOptions, User, Visualization, getByGrafanaSelectorOptions };
|
|
1291
|
+
export type { AlertPageOptions, AlertRule, AlertRuleArgs, AlertVariant$1 as AlertVariant, AppPageNavigateOptions, ContainTextOptions, CreateDataSourceArgs, CreateDataSourcePageArgs, Credentials, Dashboard, DashboardEditViewArgs, DashboardPageArgs, DataSourceSettings, E2ESelectorGroups, GotoAppConfigPageArgs, GotoAppPageArgs, GrafanaPageArgs, NavigateOptions, OrgRole, PlaywrightArgs, PluginFixture, PluginOptions, PluginPageArgs, PluginTestCtx, ReadProvisionedAlertRuleArgs, ReadProvisionedDashboardArgs, ReadProvisionedDataSourceArgs, RequestOptions, TimeRangeArgs, TriggerRequestOptions, User, UserPreferences, Visualization, getByGrafanaSelectorOptions };
|
|
@@ -177,6 +177,8 @@ class PanelEditPage extends GrafanaPage.GrafanaPage {
|
|
|
177
177
|
root: this.getByGrafanaSelector(this.ctx.selectors.components.PanelEditor.General.content)
|
|
178
178
|
});
|
|
179
179
|
try {
|
|
180
|
+
await test.expect(refreshPanelButton).toBeVisible();
|
|
181
|
+
await test.expect(refreshPanelButton).toHaveText(/refresh/i, { timeout: 2e3 });
|
|
180
182
|
await refreshPanelButton.click({ timeout: 2e3 });
|
|
181
183
|
} catch (error) {
|
|
182
184
|
await this.getByGrafanaSelector(this.ctx.selectors.components.PanelEditor.toggleVizOptions).click();
|
package/dist/options.js
CHANGED
|
@@ -6,6 +6,7 @@ const DEFAULT_ADMIN_USER = {
|
|
|
6
6
|
password: process.env.GRAFANA_ADMIN_PASSWORD || "admin"
|
|
7
7
|
};
|
|
8
8
|
const options = {
|
|
9
|
+
userPreferences: [{}, { option: true, scope: "worker" }],
|
|
9
10
|
featureToggles: [{}, { option: true, scope: "worker" }],
|
|
10
11
|
provisioningRootDir: [path.join(process.cwd(), "provisioning"), { option: true, scope: "worker" }],
|
|
11
12
|
user: [DEFAULT_ADMIN_USER, { option: true, scope: "worker" }],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grafana/plugin-e2e",
|
|
3
|
-
"version": "3.0.0-canary.
|
|
3
|
+
"version": "3.0.0-canary.2242.18774949404.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"playwright:test": "npx playwright test"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
|
-
"node": ">=
|
|
34
|
+
"node": ">=20 <=24"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@playwright/test": "^1.52.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@playwright/test": "^1.55.
|
|
40
|
+
"@playwright/test": "^1.55.1",
|
|
41
41
|
"@types/uuid": "^11.0.0",
|
|
42
42
|
"dotenv": "^17.2.2"
|
|
43
43
|
},
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"uuid": "^13.0.0",
|
|
48
48
|
"yaml": "^2.3.4"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "5132fdd12fa7057c8d7166bd9e50b2105f9eed44"
|
|
51
51
|
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const overrideFeatureToggles = (featureToggles) => {
|
|
4
|
-
const timeout = 1;
|
|
5
|
-
const waitForGrafanaBootData = (cb) => {
|
|
6
|
-
if (window?.grafanaBootData?.settings?.featureToggles) {
|
|
7
|
-
cb();
|
|
8
|
-
} else {
|
|
9
|
-
setTimeout(() => waitForGrafanaBootData(cb), timeout);
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
waitForGrafanaBootData(() => {
|
|
13
|
-
console.log("@grafana/plugin-e2e: setting the following feature toggles", featureToggles);
|
|
14
|
-
window.grafanaBootData.settings.featureToggles = {
|
|
15
|
-
...window.grafanaBootData.settings.featureToggles,
|
|
16
|
-
...featureToggles
|
|
17
|
-
};
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
exports.overrideFeatureToggles = overrideFeatureToggles;
|