@wdio/config 6.4.6 → 6.7.3

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.
@@ -0,0 +1,57 @@
1
+ export function DEFAULT_CONFIGS(): {
2
+ specs: never[];
3
+ suites: {};
4
+ exclude: never[];
5
+ outputDir: undefined;
6
+ logLevel: string;
7
+ logLevels: {};
8
+ excludeDriverLogs: never[];
9
+ bail: number;
10
+ waitforInterval: number;
11
+ waitforTimeout: number;
12
+ framework: string;
13
+ reporters: never[];
14
+ services: never[];
15
+ maxInstances: number;
16
+ maxInstancesPerCapability: number;
17
+ filesToWatch: never[];
18
+ connectionRetryTimeout: number;
19
+ connectionRetryCount: number;
20
+ execArgv: never[];
21
+ runnerEnv: {};
22
+ runner: string;
23
+ mochaOpts: {
24
+ timeout: number;
25
+ };
26
+ jasmineNodeOpts: {
27
+ defaultTimeoutInterval: number;
28
+ };
29
+ cucumberOpts: {
30
+ timeout: number;
31
+ };
32
+ onPrepare: never[];
33
+ onWorkerStart: never[];
34
+ before: never[];
35
+ beforeSession: never[];
36
+ beforeSuite: never[];
37
+ beforeHook: never[];
38
+ beforeTest: never[];
39
+ beforeCommand: never[];
40
+ afterCommand: never[];
41
+ afterTest: never[];
42
+ afterHook: never[];
43
+ afterSuite: never[];
44
+ afterSession: never[];
45
+ after: never[];
46
+ onComplete: never[];
47
+ onReload: never[];
48
+ beforeFeature: never[];
49
+ beforeScenario: never[];
50
+ beforeStep: never[];
51
+ afterStep: never[];
52
+ afterScenario: never[];
53
+ afterFeature: never[];
54
+ };
55
+ export const SUPPORTED_HOOKS: string[];
56
+ export const SUPPORTED_FILE_EXTENSIONS: string[];
57
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.js"],"names":[],"mappings":"AAIO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiEL;AAEF,uCAKC;AAED,iDAEC"}
@@ -1,68 +1,67 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
2
+ Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.SUPPORTED_FILE_EXTENSIONS = exports.SUPPORTED_HOOKS = exports.DEFAULT_CONFIGS = void 0;
7
4
  const DEFAULT_TIMEOUT = 10000;
8
-
9
- const DEFAULT_CONFIGS = () => ({
10
- specs: [],
11
- suites: {},
12
- exclude: [],
13
- outputDir: undefined,
14
- logLevel: 'info',
15
- logLevels: {},
16
- excludeDriverLogs: [],
17
- bail: 0,
18
- waitforInterval: 500,
19
- waitforTimeout: 5000,
20
- framework: 'mocha',
21
- reporters: [],
22
- services: [],
23
- maxInstances: 100,
24
- maxInstancesPerCapability: 100,
25
- filesToWatch: [],
26
- connectionRetryTimeout: 120000,
27
- connectionRetryCount: 3,
28
- execArgv: [],
29
- runnerEnv: {},
30
- runner: 'local',
31
- mochaOpts: {
32
- timeout: DEFAULT_TIMEOUT
33
- },
34
- jasmineNodeOpts: {
35
- defaultTimeoutInterval: DEFAULT_TIMEOUT
36
- },
37
- cucumberOpts: {
38
- timeout: DEFAULT_TIMEOUT
39
- },
40
- onPrepare: [],
41
- onWorkerStart: [],
42
- before: [],
43
- beforeSession: [],
44
- beforeSuite: [],
45
- beforeHook: [],
46
- beforeTest: [],
47
- beforeCommand: [],
48
- afterCommand: [],
49
- afterTest: [],
50
- afterHook: [],
51
- afterSuite: [],
52
- afterSession: [],
53
- after: [],
54
- onComplete: [],
55
- onReload: [],
56
- beforeFeature: [],
57
- beforeScenario: [],
58
- beforeStep: [],
59
- afterStep: [],
60
- afterScenario: [],
61
- afterFeature: []
5
+ exports.DEFAULT_CONFIGS = () => ({
6
+ specs: [],
7
+ suites: {},
8
+ exclude: [],
9
+ outputDir: undefined,
10
+ logLevel: 'info',
11
+ logLevels: {},
12
+ excludeDriverLogs: [],
13
+ bail: 0,
14
+ waitforInterval: 500,
15
+ waitforTimeout: 5000,
16
+ framework: 'mocha',
17
+ reporters: [],
18
+ services: [],
19
+ maxInstances: 100,
20
+ maxInstancesPerCapability: 100,
21
+ filesToWatch: [],
22
+ connectionRetryTimeout: 120000,
23
+ connectionRetryCount: 3,
24
+ execArgv: [],
25
+ runnerEnv: {},
26
+ runner: 'local',
27
+ mochaOpts: {
28
+ timeout: DEFAULT_TIMEOUT
29
+ },
30
+ jasmineNodeOpts: {
31
+ defaultTimeoutInterval: DEFAULT_TIMEOUT
32
+ },
33
+ cucumberOpts: {
34
+ timeout: DEFAULT_TIMEOUT
35
+ },
36
+ onPrepare: [],
37
+ onWorkerStart: [],
38
+ before: [],
39
+ beforeSession: [],
40
+ beforeSuite: [],
41
+ beforeHook: [],
42
+ beforeTest: [],
43
+ beforeCommand: [],
44
+ afterCommand: [],
45
+ afterTest: [],
46
+ afterHook: [],
47
+ afterSuite: [],
48
+ afterSession: [],
49
+ after: [],
50
+ onComplete: [],
51
+ onReload: [],
52
+ beforeFeature: [],
53
+ beforeScenario: [],
54
+ beforeStep: [],
55
+ afterStep: [],
56
+ afterScenario: [],
57
+ afterFeature: [],
62
58
  });
63
-
64
- exports.DEFAULT_CONFIGS = DEFAULT_CONFIGS;
65
- const SUPPORTED_HOOKS = ['before', 'beforeSession', 'beforeSuite', 'beforeHook', 'beforeTest', 'beforeCommand', 'afterCommand', 'afterTest', 'afterHook', 'afterSuite', 'afterSession', 'after', 'beforeFeature', 'beforeScenario', 'beforeStep', 'afterStep', 'afterScenario', 'afterFeature', 'onReload', 'onPrepare', 'onWorkerStart', 'onComplete'];
66
- exports.SUPPORTED_HOOKS = SUPPORTED_HOOKS;
67
- const SUPPORTED_FILE_EXTENSIONS = ['.js', '.mjs', '.es6', '.ts', '.feature', '.coffee', '.cjs'];
68
- exports.SUPPORTED_FILE_EXTENSIONS = SUPPORTED_FILE_EXTENSIONS;
59
+ exports.SUPPORTED_HOOKS = [
60
+ 'before', 'beforeSession', 'beforeSuite', 'beforeHook', 'beforeTest', 'beforeCommand',
61
+ 'afterCommand', 'afterTest', 'afterHook', 'afterSuite', 'afterSession', 'after',
62
+ 'beforeFeature', 'beforeScenario', 'beforeStep', 'afterStep', 'afterScenario', 'afterFeature',
63
+ 'onReload', 'onPrepare', 'onWorkerStart', 'onComplete'
64
+ ];
65
+ exports.SUPPORTED_FILE_EXTENSIONS = [
66
+ '.js', '.mjs', '.es6', '.ts', '.feature', '.coffee', '.cjs'
67
+ ];
@@ -0,0 +1,8 @@
1
+ import { validateConfig } from "./utils";
2
+ import { getSauceEndpoint } from "./utils";
3
+ import { detectBackend } from "./utils";
4
+ import { isCloudCapability } from "./utils";
5
+ import ConfigParser from "./lib/ConfigParser";
6
+ import { DEFAULT_CONFIGS } from "./constants";
7
+ export { validateConfig, getSauceEndpoint, detectBackend, isCloudCapability, ConfigParser, DEFAULT_CONFIGS };
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":""}
package/build/index.js CHANGED
@@ -1,43 +1,15 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "ConfigParser", {
7
- enumerable: true,
8
- get: function () {
9
- return _ConfigParser.default;
10
- }
11
- });
12
- Object.defineProperty(exports, "validateConfig", {
13
- enumerable: true,
14
- get: function () {
15
- return _utils.validateConfig;
16
- }
17
- });
18
- Object.defineProperty(exports, "getSauceEndpoint", {
19
- enumerable: true,
20
- get: function () {
21
- return _utils.getSauceEndpoint;
22
- }
23
- });
24
- Object.defineProperty(exports, "detectBackend", {
25
- enumerable: true,
26
- get: function () {
27
- return _utils.detectBackend;
28
- }
29
- });
30
- Object.defineProperty(exports, "DEFAULT_CONFIGS", {
31
- enumerable: true,
32
- get: function () {
33
- return _constants.DEFAULT_CONFIGS;
34
- }
35
- });
36
-
37
- var _ConfigParser = _interopRequireDefault(require("./lib/ConfigParser"));
38
-
39
- var _utils = require("./utils");
40
-
41
- var _constants = require("./constants");
42
-
43
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_CONFIGS = exports.ConfigParser = exports.isCloudCapability = exports.detectBackend = exports.getSauceEndpoint = exports.validateConfig = void 0;
7
+ const ConfigParser_1 = __importDefault(require("./lib/ConfigParser"));
8
+ exports.ConfigParser = ConfigParser_1.default;
9
+ const utils_1 = require("./utils");
10
+ Object.defineProperty(exports, "validateConfig", { enumerable: true, get: function () { return utils_1.validateConfig; } });
11
+ Object.defineProperty(exports, "getSauceEndpoint", { enumerable: true, get: function () { return utils_1.getSauceEndpoint; } });
12
+ Object.defineProperty(exports, "detectBackend", { enumerable: true, get: function () { return utils_1.detectBackend; } });
13
+ Object.defineProperty(exports, "isCloudCapability", { enumerable: true, get: function () { return utils_1.isCloudCapability; } });
14
+ const constants_1 = require("./constants");
15
+ Object.defineProperty(exports, "DEFAULT_CONFIGS", { enumerable: true, get: function () { return constants_1.DEFAULT_CONFIGS; } });
@@ -0,0 +1,119 @@
1
+ export default class ConfigParser {
2
+ static getFilePaths(patterns: any, omitWarnings: any): string[];
3
+ _config: {
4
+ specs: never[];
5
+ suites: {};
6
+ exclude: never[];
7
+ outputDir: undefined;
8
+ logLevel: string;
9
+ logLevels: {};
10
+ excludeDriverLogs: never[];
11
+ bail: number;
12
+ waitforInterval: number;
13
+ waitforTimeout: number;
14
+ framework: string;
15
+ reporters: never[];
16
+ services: never[];
17
+ maxInstances: number;
18
+ maxInstancesPerCapability: number;
19
+ filesToWatch: never[];
20
+ connectionRetryTimeout: number;
21
+ connectionRetryCount: number;
22
+ execArgv: never[];
23
+ runnerEnv: {};
24
+ runner: string;
25
+ mochaOpts: {
26
+ timeout: number;
27
+ };
28
+ jasmineNodeOpts: {
29
+ defaultTimeoutInterval: number;
30
+ };
31
+ cucumberOpts: {
32
+ timeout: number;
33
+ };
34
+ onPrepare: never[];
35
+ onWorkerStart: never[];
36
+ before: never[];
37
+ beforeSession: never[];
38
+ beforeSuite: never[];
39
+ beforeHook: never[];
40
+ beforeTest: never[];
41
+ beforeCommand: never[];
42
+ afterCommand: never[];
43
+ afterTest: never[];
44
+ afterHook: never[];
45
+ afterSuite: never[];
46
+ afterSession: never[];
47
+ after: never[];
48
+ onComplete: never[];
49
+ onReload: never[];
50
+ beforeFeature: never[];
51
+ beforeScenario: never[];
52
+ beforeStep: never[];
53
+ afterStep: never[];
54
+ afterScenario: never[];
55
+ afterFeature: never[];
56
+ };
57
+ _capabilities: any[];
58
+ addConfigFile(filename: string): void;
59
+ merge(object?: Object): void;
60
+ addService(service: Object): void;
61
+ getSpecs(capSpecs: any, capExclude: any): string[];
62
+ setFilePathToFilterOptions(cliArgFileList: string, config: Object): string[];
63
+ getConfig(): {
64
+ specs: never[];
65
+ suites: {};
66
+ exclude: never[];
67
+ outputDir: undefined;
68
+ logLevel: string;
69
+ logLevels: {};
70
+ excludeDriverLogs: never[];
71
+ bail: number;
72
+ waitforInterval: number;
73
+ waitforTimeout: number;
74
+ framework: string;
75
+ reporters: never[];
76
+ services: never[];
77
+ maxInstances: number;
78
+ maxInstancesPerCapability: number;
79
+ filesToWatch: never[];
80
+ connectionRetryTimeout: number;
81
+ connectionRetryCount: number;
82
+ execArgv: never[];
83
+ runnerEnv: {};
84
+ runner: string;
85
+ mochaOpts: {
86
+ timeout: number;
87
+ };
88
+ jasmineNodeOpts: {
89
+ defaultTimeoutInterval: number;
90
+ };
91
+ cucumberOpts: {
92
+ timeout: number;
93
+ };
94
+ onPrepare: never[];
95
+ onWorkerStart: never[];
96
+ before: never[];
97
+ beforeSession: never[];
98
+ beforeSuite: never[];
99
+ beforeHook: never[];
100
+ beforeTest: never[];
101
+ beforeCommand: never[];
102
+ afterCommand: never[];
103
+ afterTest: never[];
104
+ afterHook: never[];
105
+ afterSuite: never[];
106
+ afterSession: never[];
107
+ after: never[];
108
+ onComplete: never[];
109
+ onReload: never[];
110
+ beforeFeature: never[];
111
+ beforeScenario: never[];
112
+ beforeStep: never[];
113
+ afterStep: never[];
114
+ afterScenario: never[];
115
+ afterFeature: never[];
116
+ };
117
+ getCapabilities(i: any): any;
118
+ }
119
+ //# sourceMappingURL=ConfigParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigParser.d.ts","sourceRoot":"","sources":["../../src/lib/ConfigParser.js"],"names":[],"mappings":"AAcA;IAsQI,uDAFY,QAAQ,CAkCnB;IApSG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAAgC;IAEhC,qBAAuB;IAO3B,sCAoDC;IAMD,eAFY,MAAM,QA2DjB;IAMD,oBAFW,MAAM,QAkBhB;IAKD,mDAkDC;IAWD,2DAJY,MAAM,GAEN,QAAQ,CAwBnB;IAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAEC;IAKD,6BAMC;CAyCJ"}
@@ -1,237 +1,186 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _fs = _interopRequireDefault(require("fs"));
9
-
10
- var _path = _interopRequireDefault(require("path"));
11
-
12
- var _glob = _interopRequireDefault(require("glob"));
13
-
14
- var _deepmerge = _interopRequireDefault(require("deepmerge"));
15
-
16
- var _logger = _interopRequireDefault(require("@wdio/logger"));
17
-
18
- var _utils = require("../utils");
19
-
20
- var _constants = require("../constants");
21
-
22
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
-
24
- const log = (0, _logger.default)('@wdio/config:ConfigParser');
25
- const MERGE_OPTIONS = {
26
- clone: false
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
-
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const glob_1 = __importDefault(require("glob"));
9
+ const deepmerge_1 = __importDefault(require("deepmerge"));
10
+ const logger_1 = __importDefault(require("@wdio/logger"));
11
+ const utils_1 = require("../utils");
12
+ const constants_1 = require("../constants");
13
+ const log = logger_1.default('@wdio/config:ConfigParser');
14
+ const MERGE_OPTIONS = { clone: false };
29
15
  class ConfigParser {
30
- constructor() {
31
- this._config = (0, _constants.DEFAULT_CONFIGS)();
32
- this._capabilities = [];
33
- }
34
-
35
- addConfigFile(filename) {
36
- if (typeof filename !== 'string') {
37
- throw new Error('addConfigFile requires filepath');
16
+ constructor() {
17
+ this._config = constants_1.DEFAULT_CONFIGS();
18
+ this._capabilities = [];
38
19
  }
39
-
40
- const filePath = _path.default.resolve(process.cwd(), filename);
41
-
42
- try {
43
- const fileConfig = (0, _deepmerge.default)(require(filePath).config, {}, MERGE_OPTIONS);
44
- const defaultTo = Array.isArray(this._capabilities) ? [] : {};
45
- this._capabilities = (0, _deepmerge.default)(this._capabilities, fileConfig.capabilities || defaultTo, MERGE_OPTIONS);
46
- delete fileConfig.capabilities;
47
- this.addService(fileConfig);
48
-
49
- for (let hookName of _constants.SUPPORTED_HOOKS) {
50
- delete fileConfig[hookName];
51
- }
52
-
53
- this._config = (0, _deepmerge.default)(this._config, fileConfig, MERGE_OPTIONS);
54
-
55
- const isRDC = Array.isArray(this._capabilities) && this._capabilities.some(capability => 'testobject_api_key' in capability);
56
-
57
- this._config = (0, _deepmerge.default)((0, _utils.detectBackend)(this._config, isRDC), this._config, MERGE_OPTIONS);
58
- delete this._config.watch;
59
- } catch (e) {
60
- log.error(`Failed loading configuration file: ${filePath}:`, e.message);
61
- throw e;
62
- }
63
- }
64
-
65
- merge(object = {}) {
66
- const spec = Array.isArray(object.spec) ? object.spec : [];
67
- const exclude = Array.isArray(object.exclude) ? object.exclude : [];
68
- this._config = (0, _deepmerge.default)(this._config, object, MERGE_OPTIONS);
69
-
70
- if (object.specs && object.specs.length > 0) {
71
- this._config.specs = object.specs;
72
- } else if (object.exclude && object.exclude.length > 0) {
73
- this._config.exclude = object.exclude;
74
- }
75
-
76
- this._capabilities = (0, _utils.validObjectOrArray)(this._config.capabilities) ? this._config.capabilities : this._capabilities;
77
-
78
- if (this._config.spec && (0, _utils.isCucumberFeatureWithLineNumber)(this._config.spec)) {
79
- this._config.cucumberFeaturesWithLineNumbers = Array.isArray(this._config.spec) ? [...this._config.spec] : [this._config.spec];
80
- }
81
-
82
- if (spec.length > 0) {
83
- this._config.specs = [...this.setFilePathToFilterOptions(spec, this._config.specs)];
84
- }
85
-
86
- if (exclude.length > 0) {
87
- this._config.exclude = [...this.setFilePathToFilterOptions(exclude, this._config.exclude)];
88
- }
89
-
90
- let defaultBackend = (0, _utils.detectBackend)({});
91
-
92
- if (this._config.protocol === defaultBackend.protocol && this._config.hostname === defaultBackend.hostname && this._config.port === defaultBackend.port && this._config.path === defaultBackend.path) {
93
- delete this._config.protocol;
94
- delete this._config.hostname;
95
- delete this._config.port;
96
- delete this._config.path;
97
- }
98
-
99
- this._config = (0, _deepmerge.default)((0, _utils.detectBackend)(this._config), this._config, MERGE_OPTIONS);
100
- }
101
-
102
- addService(service) {
103
- for (let hookName of _constants.SUPPORTED_HOOKS) {
104
- if (!service[hookName]) {
105
- continue;
106
- }
107
-
108
- if (typeof service[hookName] === 'function') {
109
- this._config[hookName].push(service[hookName].bind(service));
110
- } else if (Array.isArray(service[hookName])) {
111
- for (let hook of service[hookName]) {
112
- if (typeof hook === 'function') {
113
- this._config[hookName].push(hook.bind(service));
114
- }
115
- }
116
- }
117
- }
118
- }
119
-
120
- getSpecs(capSpecs, capExclude) {
121
- let specs = ConfigParser.getFilePaths(this._config.specs);
122
- let spec = Array.isArray(this._config.spec) ? this._config.spec : [];
123
- let exclude = ConfigParser.getFilePaths(this._config.exclude);
124
- let suites = Array.isArray(this._config.suite) ? this._config.suite : [];
125
-
126
- if (suites.length > 0) {
127
- let suiteSpecs = [];
128
-
129
- for (let suiteName of suites) {
130
- let suite = this._config.suites[suiteName];
131
-
132
- if (suite && Array.isArray(suite)) {
133
- suiteSpecs = suiteSpecs.concat(ConfigParser.getFilePaths(suite));
134
- }
135
- }
136
-
137
- if (suiteSpecs.length === 0) {
138
- throw new Error(`The suite(s) "${suites.join('", "')}" you specified don't exist ` + 'in your config file or doesn\'t contain any files!');
139
- }
140
-
141
- let tmpSpecs = spec.length > 0 ? [...specs, ...suiteSpecs] : suiteSpecs;
142
-
143
- if (Array.isArray(capSpecs)) {
144
- tmpSpecs = ConfigParser.getFilePaths(capSpecs);
145
- }
146
-
147
- if (Array.isArray(capExclude)) {
148
- exclude = ConfigParser.getFilePaths(capExclude);
149
- }
150
-
151
- specs = [...new Set(tmpSpecs)];
152
- return specs.filter(spec => !exclude.includes(spec));
153
- }
154
-
155
- if (Array.isArray(capSpecs)) {
156
- specs = ConfigParser.getFilePaths(capSpecs);
20
+ addConfigFile(filename) {
21
+ if (typeof filename !== 'string') {
22
+ throw new Error('addConfigFile requires filepath');
23
+ }
24
+ const filePath = path_1.default.resolve(process.cwd(), filename);
25
+ try {
26
+ const fileConfig = deepmerge_1.default(require(filePath).config, {}, MERGE_OPTIONS);
27
+ const defaultTo = Array.isArray(this._capabilities) ? [] : {};
28
+ this._capabilities = deepmerge_1.default(this._capabilities, fileConfig.capabilities || defaultTo, MERGE_OPTIONS);
29
+ delete fileConfig.capabilities;
30
+ this.addService(fileConfig);
31
+ for (let hookName of constants_1.SUPPORTED_HOOKS) {
32
+ delete fileConfig[hookName];
33
+ }
34
+ this._config = deepmerge_1.default(this._config, fileConfig, MERGE_OPTIONS);
35
+ const isRDC = Array.isArray(this._capabilities) && this._capabilities.some(capability => 'testobject_api_key' in capability);
36
+ this._config = deepmerge_1.default(utils_1.detectBackend(this._config, isRDC), this._config, MERGE_OPTIONS);
37
+ delete this._config.watch;
38
+ }
39
+ catch (e) {
40
+ log.error(`Failed loading configuration file: ${filePath}:`, e.message);
41
+ throw e;
42
+ }
157
43
  }
158
-
159
- if (Array.isArray(capExclude)) {
160
- exclude = ConfigParser.getFilePaths(capExclude);
44
+ merge(object = {}) {
45
+ const spec = Array.isArray(object.spec) ? object.spec : [];
46
+ const exclude = Array.isArray(object.exclude) ? object.exclude : [];
47
+ this._config = deepmerge_1.default(this._config, object, MERGE_OPTIONS);
48
+ if (object.specs && object.specs.length > 0) {
49
+ this._config.specs = object.specs;
50
+ }
51
+ else if (object.exclude && object.exclude.length > 0) {
52
+ this._config.exclude = object.exclude;
53
+ }
54
+ this._capabilities = utils_1.validObjectOrArray(this._config.capabilities) ? this._config.capabilities : this._capabilities;
55
+ if (this._config.spec && utils_1.isCucumberFeatureWithLineNumber(this._config.spec)) {
56
+ this._config.cucumberFeaturesWithLineNumbers = Array.isArray(this._config.spec) ? [...this._config.spec] : [this._config.spec];
57
+ }
58
+ if (spec.length > 0) {
59
+ this._config.specs = [...this.setFilePathToFilterOptions(spec, this._config.specs)];
60
+ }
61
+ if (exclude.length > 0) {
62
+ this._config.exclude = [...this.setFilePathToFilterOptions(exclude, this._config.exclude)];
63
+ }
64
+ let defaultBackend = utils_1.detectBackend({});
65
+ if ((this._config.protocol === defaultBackend.protocol) &&
66
+ (this._config.hostname === defaultBackend.hostname) &&
67
+ (this._config.port === defaultBackend.port) &&
68
+ (this._config.path === defaultBackend.path)) {
69
+ delete this._config.protocol;
70
+ delete this._config.hostname;
71
+ delete this._config.port;
72
+ delete this._config.path;
73
+ }
74
+ this._config = deepmerge_1.default(utils_1.detectBackend(this._config), this._config, MERGE_OPTIONS);
75
+ }
76
+ addService(service) {
77
+ for (let hookName of constants_1.SUPPORTED_HOOKS) {
78
+ if (!service[hookName]) {
79
+ continue;
80
+ }
81
+ if (typeof service[hookName] === 'function') {
82
+ this._config[hookName].push(service[hookName].bind(service));
83
+ }
84
+ else if (Array.isArray(service[hookName])) {
85
+ for (let hook of service[hookName]) {
86
+ if (typeof hook === 'function') {
87
+ this._config[hookName].push(hook.bind(service));
88
+ }
89
+ }
90
+ }
91
+ }
161
92
  }
162
-
163
- return specs.filter(spec => !exclude.includes(spec));
164
- }
165
-
166
- setFilePathToFilterOptions(cliArgFileList, config) {
167
- const filesToFilter = new Set();
168
- const fileList = ConfigParser.getFilePaths(config);
169
- cliArgFileList.forEach(filteredFile => {
170
- filteredFile = (0, _utils.removeLineNumbers)(filteredFile);
171
- let globMatchedFiles = ConfigParser.getFilePaths(_glob.default.sync(filteredFile));
172
-
173
- if (_fs.default.existsSync(filteredFile) && _fs.default.lstatSync(filteredFile).isFile()) {
174
- filesToFilter.add(_path.default.resolve(process.cwd(), filteredFile));
175
- } else if (globMatchedFiles.length) {
176
- globMatchedFiles.forEach(file => filesToFilter.add(file));
177
- } else {
178
- fileList.forEach(file => {
179
- if (file.match(filteredFile)) {
180
- filesToFilter.add(file);
181
- }
93
+ getSpecs(capSpecs, capExclude) {
94
+ let specs = ConfigParser.getFilePaths(this._config.specs);
95
+ let spec = Array.isArray(this._config.spec) ? this._config.spec : [];
96
+ let exclude = ConfigParser.getFilePaths(this._config.exclude);
97
+ let suites = Array.isArray(this._config.suite) ? this._config.suite : [];
98
+ if (suites.length > 0) {
99
+ let suiteSpecs = [];
100
+ for (let suiteName of suites) {
101
+ let suite = this._config.suites[suiteName];
102
+ if (suite && Array.isArray(suite)) {
103
+ suiteSpecs = suiteSpecs.concat(ConfigParser.getFilePaths(suite));
104
+ }
105
+ }
106
+ if (suiteSpecs.length === 0) {
107
+ throw new Error(`The suite(s) "${suites.join('", "')}" you specified don't exist ` +
108
+ 'in your config file or doesn\'t contain any files!');
109
+ }
110
+ let tmpSpecs = spec.length > 0 ? [...specs, ...suiteSpecs] : suiteSpecs;
111
+ if (Array.isArray(capSpecs)) {
112
+ tmpSpecs = ConfigParser.getFilePaths(capSpecs);
113
+ }
114
+ if (Array.isArray(capExclude)) {
115
+ exclude = ConfigParser.getFilePaths(capExclude);
116
+ }
117
+ specs = [...new Set(tmpSpecs)];
118
+ return specs.filter(spec => !exclude.includes(spec));
119
+ }
120
+ if (Array.isArray(capSpecs)) {
121
+ specs = ConfigParser.getFilePaths(capSpecs);
122
+ }
123
+ if (Array.isArray(capExclude)) {
124
+ exclude = ConfigParser.getFilePaths(capExclude);
125
+ }
126
+ return specs.filter(spec => !exclude.includes(spec));
127
+ }
128
+ setFilePathToFilterOptions(cliArgFileList, config) {
129
+ const filesToFilter = new Set();
130
+ const fileList = ConfigParser.getFilePaths(config);
131
+ cliArgFileList.forEach(filteredFile => {
132
+ filteredFile = utils_1.removeLineNumbers(filteredFile);
133
+ let globMatchedFiles = ConfigParser.getFilePaths(glob_1.default.sync(filteredFile));
134
+ if (fs_1.default.existsSync(filteredFile) && fs_1.default.lstatSync(filteredFile).isFile()) {
135
+ filesToFilter.add(path_1.default.resolve(process.cwd(), filteredFile));
136
+ }
137
+ else if (globMatchedFiles.length) {
138
+ globMatchedFiles.forEach(file => filesToFilter.add(file));
139
+ }
140
+ else {
141
+ fileList.forEach(file => {
142
+ if (file.match(filteredFile)) {
143
+ filesToFilter.add(file);
144
+ }
145
+ });
146
+ }
182
147
  });
183
- }
184
- });
185
-
186
- if (filesToFilter.size === 0) {
187
- throw new Error(`spec file(s) ${cliArgFileList.join(', ')} not found`);
188
- }
189
-
190
- return filesToFilter;
191
- }
192
-
193
- getConfig() {
194
- return this._config;
195
- }
196
-
197
- getCapabilities(i) {
198
- if (typeof i === 'number' && this._capabilities[i]) {
199
- return this._capabilities[i];
148
+ if (filesToFilter.size === 0) {
149
+ throw new Error(`spec file(s) ${cliArgFileList.join(', ')} not found`);
150
+ }
151
+ return filesToFilter;
200
152
  }
201
-
202
- return this._capabilities;
203
- }
204
-
205
- static getFilePaths(patterns, omitWarnings) {
206
- let files = [];
207
-
208
- if (typeof patterns === 'string') {
209
- patterns = (0, _utils.removeLineNumbers)(patterns);
210
- patterns = [patterns];
211
- } else {
212
- patterns = patterns.map(pattern => (0, _utils.removeLineNumbers)(pattern));
153
+ getConfig() {
154
+ return this._config;
213
155
  }
214
-
215
- if (!Array.isArray(patterns)) {
216
- throw new Error('specs or exclude property should be an array of strings');
156
+ getCapabilities(i) {
157
+ if (typeof i === 'number' && this._capabilities[i]) {
158
+ return this._capabilities[i];
159
+ }
160
+ return this._capabilities;
217
161
  }
218
-
219
- for (let pattern of patterns) {
220
- let filenames = _glob.default.sync(pattern);
221
-
222
- filenames = filenames.filter(filename => _constants.SUPPORTED_FILE_EXTENSIONS.find(ext => filename.endsWith(ext)));
223
- filenames = filenames.map(filename => _path.default.isAbsolute(filename) ? _path.default.normalize(filename) : _path.default.resolve(process.cwd(), filename));
224
-
225
- if (filenames.length === 0 && !omitWarnings) {
226
- log.warn('pattern', pattern, 'did not match any file');
227
- }
228
-
229
- files = (0, _deepmerge.default)(files, filenames, MERGE_OPTIONS);
162
+ static getFilePaths(patterns, omitWarnings) {
163
+ let files = [];
164
+ if (typeof patterns === 'string') {
165
+ patterns = utils_1.removeLineNumbers(patterns);
166
+ patterns = [patterns];
167
+ }
168
+ else {
169
+ patterns = patterns.map(pattern => utils_1.removeLineNumbers(pattern));
170
+ }
171
+ if (!Array.isArray(patterns)) {
172
+ throw new Error('specs or exclude property should be an array of strings');
173
+ }
174
+ for (let pattern of patterns) {
175
+ let filenames = glob_1.default.sync(pattern);
176
+ filenames = filenames.filter((filename) => constants_1.SUPPORTED_FILE_EXTENSIONS.find((ext) => filename.endsWith(ext)));
177
+ filenames = filenames.map(filename => path_1.default.isAbsolute(filename) ? path_1.default.normalize(filename) : path_1.default.resolve(process.cwd(), filename));
178
+ if (filenames.length === 0 && !omitWarnings) {
179
+ log.warn('pattern', pattern, 'did not match any file');
180
+ }
181
+ files = deepmerge_1.default(files, filenames, MERGE_OPTIONS);
182
+ }
183
+ return files;
230
184
  }
231
-
232
- return files;
233
- }
234
-
235
185
  }
236
-
237
- exports.default = ConfigParser;
186
+ exports.default = ConfigParser;
@@ -0,0 +1,13 @@
1
+ export function getSauceEndpoint(region: any, isRDC: any): string;
2
+ export function removeLineNumbers(filePath: string): string;
3
+ export function isCucumberFeatureWithLineNumber(spec: string | string[]): boolean;
4
+ export function isCloudCapability(cap: any): boolean;
5
+ export function detectBackend(options?: {}, isRDC?: boolean): {
6
+ protocol: any;
7
+ hostname: any;
8
+ port: any;
9
+ path: any;
10
+ };
11
+ export function validateConfig(defaults: Object, options: Object, keysToKeep?: any[]): Object;
12
+ export function validObjectOrArray(object: any): boolean;
13
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAgBA,kEAOC;AAQD,4CAHa,MAAM,GACN,MAAM,CAQlB;AAOD,sDAFW,MAAM,GAAC,MAAM,EAAE,WAKzB;AAED,qDAEC;AAKD;;;;;EAoFC;AAQD,yCAJY,MAAM,WACN,MAAM,uBACN,MAAM,CAgDjB;AArLM,yDAC2D"}
package/build/utils.js CHANGED
@@ -1,154 +1,122 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getSauceEndpoint = getSauceEndpoint;
7
- exports.removeLineNumbers = removeLineNumbers;
8
- exports.isCucumberFeatureWithLineNumber = isCucumberFeatureWithLineNumber;
9
- exports.detectBackend = detectBackend;
10
- exports.validateConfig = validateConfig;
11
- exports.validObjectOrArray = void 0;
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateConfig = exports.detectBackend = exports.isCloudCapability = exports.isCucumberFeatureWithLineNumber = exports.removeLineNumbers = exports.getSauceEndpoint = exports.validObjectOrArray = void 0;
12
4
  const DEFAULT_HOSTNAME = '127.0.0.1';
13
5
  const DEFAULT_PORT = 4444;
14
6
  const DEFAULT_PROTOCOL = 'http';
15
7
  const DEFAULT_PATH = '/';
16
8
  const LEGACY_PATH = '/wd/hub';
17
9
  const REGION_MAPPING = {
18
- 'us': 'us-west-1.',
19
- 'eu': 'eu-central-1.',
20
- 'eu-central-1': 'eu-central-1.',
21
- 'us-east-1': 'us-east-1.'
10
+ 'us': 'us-west-1.',
11
+ 'eu': 'eu-central-1.',
12
+ 'eu-central-1': 'eu-central-1.',
13
+ 'us-east-1': 'us-east-1.'
22
14
  };
23
-
24
- const validObjectOrArray = object => Array.isArray(object) && object.length > 0 || typeof object === 'object' && Object.keys(object).length > 0;
25
-
26
- exports.validObjectOrArray = validObjectOrArray;
27
-
15
+ exports.validObjectOrArray = (object) => (Array.isArray(object) && object.length > 0) ||
16
+ (typeof object === 'object' && Object.keys(object).length > 0);
28
17
  function getSauceEndpoint(region, isRDC) {
29
- const shortRegion = REGION_MAPPING[region] ? region : 'us';
30
-
31
- if (isRDC) {
32
- return `${shortRegion}1.appium.testobject.com`;
33
- }
34
-
35
- return `ondemand.${REGION_MAPPING[shortRegion]}saucelabs.com`;
18
+ const shortRegion = REGION_MAPPING[region] ? region : 'us';
19
+ if (isRDC) {
20
+ return `${shortRegion}1.appium.testobject.com`;
21
+ }
22
+ return `ondemand.${REGION_MAPPING[shortRegion]}saucelabs.com`;
36
23
  }
37
-
24
+ exports.getSauceEndpoint = getSauceEndpoint;
38
25
  function removeLineNumbers(filePath) {
39
- const matcher = filePath.match(/:\d+(:\d+$|$)/);
40
-
41
- if (matcher) {
42
- filePath = filePath.substring(0, matcher.index);
43
- }
44
-
45
- return filePath;
26
+ const matcher = filePath.match(/:\d+(:\d+$|$)/);
27
+ if (matcher) {
28
+ filePath = filePath.substring(0, matcher.index);
29
+ }
30
+ return filePath;
46
31
  }
47
-
32
+ exports.removeLineNumbers = removeLineNumbers;
48
33
  function isCucumberFeatureWithLineNumber(spec) {
49
- const specs = Array.isArray(spec) ? spec : [spec];
50
- return specs.some(s => s.match(/:\d+(:\d+$|$)/));
34
+ const specs = Array.isArray(spec) ? spec : [spec];
35
+ return specs.some((s) => s.match(/:\d+(:\d+$|$)/));
51
36
  }
52
-
53
- function detectBackend(options = {}, isRDC = false) {
54
- let {
55
- port,
56
- hostname,
57
- user,
58
- key,
59
- protocol,
60
- region,
61
- headless,
62
- path
63
- } = options;
64
-
65
- if (typeof user === 'string' && typeof key === 'string' && key.length === 20) {
66
- return {
67
- protocol: protocol || 'https',
68
- hostname: hostname || 'hub-cloud.browserstack.com',
69
- port: port || 443,
70
- path: path || LEGACY_PATH
71
- };
72
- }
73
-
74
- if (typeof user === 'string' && typeof key === 'string' && key.length === 32) {
75
- return {
76
- protocol: protocol || 'https',
77
- hostname: hostname || 'hub.testingbot.com',
78
- port: port || 443,
79
- path: path || LEGACY_PATH
80
- };
81
- }
82
-
83
- if (typeof user === 'string' && typeof key === 'string' && key.length === 36 || typeof user === 'string' && isRDC || isRDC) {
84
- const sauceRegion = headless ? 'us-east-1' : region;
85
- return {
86
- protocol: protocol || 'https',
87
- hostname: hostname || getSauceEndpoint(sauceRegion, isRDC),
88
- port: port || 443,
89
- path: path || LEGACY_PATH
90
- };
91
- }
92
-
93
- if ((typeof user === 'string' || typeof key === 'string') && !hostname) {
94
- throw new Error('A "user" or "key" was provided but could not be connected to a ' + 'known cloud service (Sauce Labs, Browerstack or Testingbot). ' + 'Please check if given user and key properties are correct!');
95
- }
96
-
97
- if (hostname || port || protocol || path) {
98
- return {
99
- hostname: hostname || DEFAULT_HOSTNAME,
100
- port: port || DEFAULT_PORT,
101
- protocol: protocol || DEFAULT_PROTOCOL,
102
- path: path || DEFAULT_PATH
103
- };
104
- }
105
-
106
- return {
107
- hostname,
108
- port,
109
- protocol,
110
- path
111
- };
37
+ exports.isCucumberFeatureWithLineNumber = isCucumberFeatureWithLineNumber;
38
+ function isCloudCapability(cap) {
39
+ return Boolean(cap && (cap['bstack:options'] || cap['sauce:options'] || cap['tb:options']));
112
40
  }
113
-
114
- function validateConfig(defaults, options, keysToKeep = []) {
115
- const params = {};
116
-
117
- for (const [name, expectedOption] of Object.entries(defaults)) {
118
- if (typeof options[name] === 'undefined' && !expectedOption.default && expectedOption.required) {
119
- throw new Error(`Required option "${name}" is missing`);
41
+ exports.isCloudCapability = isCloudCapability;
42
+ function detectBackend(options = {}, isRDC = false) {
43
+ let { port, hostname, user, key, protocol, region, headless, path } = options;
44
+ if (typeof user === 'string' && typeof key === 'string' && key.length === 20) {
45
+ return {
46
+ protocol: protocol || 'https',
47
+ hostname: hostname || 'hub-cloud.browserstack.com',
48
+ port: port || 443,
49
+ path: path || LEGACY_PATH
50
+ };
51
+ }
52
+ if (typeof user === 'string' && typeof key === 'string' && key.length === 32) {
53
+ return {
54
+ protocol: protocol || 'https',
55
+ hostname: hostname || 'hub.testingbot.com',
56
+ port: port || 443,
57
+ path: path || LEGACY_PATH
58
+ };
59
+ }
60
+ if ((typeof user === 'string' && typeof key === 'string' && key.length === 36) ||
61
+ (typeof user === 'string' && isRDC) ||
62
+ isRDC) {
63
+ const sauceRegion = headless ? 'us-east-1' : region;
64
+ return {
65
+ protocol: protocol || 'https',
66
+ hostname: hostname || getSauceEndpoint(sauceRegion, isRDC),
67
+ port: port || 443,
68
+ path: path || LEGACY_PATH
69
+ };
120
70
  }
121
-
122
- if (typeof options[name] === 'undefined' && expectedOption.default) {
123
- params[name] = expectedOption.default;
71
+ if ((typeof user === 'string' || typeof key === 'string') &&
72
+ !hostname) {
73
+ throw new Error('A "user" or "key" was provided but could not be connected to a ' +
74
+ 'known cloud service (Sauce Labs, Browerstack or Testingbot). ' +
75
+ 'Please check if given user and key properties are correct!');
124
76
  }
125
-
126
- if (typeof options[name] !== 'undefined') {
127
- if (typeof expectedOption.type === 'string' && typeof options[name] !== expectedOption.type) {
128
- throw new Error(`Expected option "${name}" to be type of ${expectedOption.type} but was ${typeof options[name]}`);
129
- }
130
-
131
- if (typeof expectedOption.type === 'function') {
132
- try {
133
- expectedOption.type(options[name]);
134
- } catch (e) {
135
- throw new Error(`Type check for option "${name}" failed: ${e.message}`);
77
+ if (hostname || port || protocol || path) {
78
+ return {
79
+ hostname: hostname || DEFAULT_HOSTNAME,
80
+ port: port || DEFAULT_PORT,
81
+ protocol: protocol || DEFAULT_PROTOCOL,
82
+ path: path || DEFAULT_PATH
83
+ };
84
+ }
85
+ return { hostname, port, protocol, path };
86
+ }
87
+ exports.detectBackend = detectBackend;
88
+ function validateConfig(defaults, options, keysToKeep = []) {
89
+ const params = {};
90
+ for (const [name, expectedOption] of Object.entries(defaults)) {
91
+ if (typeof options[name] === 'undefined' && !expectedOption.default && expectedOption.required) {
92
+ throw new Error(`Required option "${name}" is missing`);
93
+ }
94
+ if (typeof options[name] === 'undefined' && expectedOption.default) {
95
+ params[name] = expectedOption.default;
96
+ }
97
+ if (typeof options[name] !== 'undefined') {
98
+ if (typeof options[name] !== expectedOption.type) {
99
+ throw new Error(`Expected option "${name}" to be type of ${expectedOption.type} but was ${typeof options[name]}`);
100
+ }
101
+ if (typeof expectedOption.validate === 'function') {
102
+ try {
103
+ expectedOption.validate(options[name]);
104
+ }
105
+ catch (e) {
106
+ throw new Error(`Type check for option "${name}" failed: ${e.message}`);
107
+ }
108
+ }
109
+ if (expectedOption.match && !options[name].match(expectedOption.match)) {
110
+ throw new Error(`Option "${name}" doesn't match expected values: ${expectedOption.match}`);
111
+ }
112
+ params[name] = options[name];
136
113
  }
137
- }
138
-
139
- if (expectedOption.match && !options[name].match(expectedOption.match)) {
140
- throw new Error(`Option "${name}" doesn't match expected values: ${expectedOption.match}`);
141
- }
142
-
143
- params[name] = options[name];
144
114
  }
145
- }
146
-
147
- for (const [name, option] of Object.entries(options)) {
148
- if (keysToKeep.includes(name)) {
149
- params[name] = option;
115
+ for (const [name, option] of Object.entries(options)) {
116
+ if (keysToKeep.includes(name)) {
117
+ params[name] = option;
118
+ }
150
119
  }
151
- }
152
-
153
- return params;
154
- }
120
+ return params;
121
+ }
122
+ exports.validateConfig = validateConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/config",
3
- "version": "6.4.6",
3
+ "version": "6.7.3",
4
4
  "description": "A helper utility to parse and validate WebdriverIO options",
5
5
  "author": "Christian Bromann <christian@saucelabs.com>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/master/packages/wdio-config",
@@ -9,14 +9,6 @@
9
9
  "engines": {
10
10
  "node": ">=10.0.0"
11
11
  },
12
- "scripts": {
13
- "build": "run-s clean compile",
14
- "clean": "rimraf ./build",
15
- "compile": "babel src/ -d build/ --config-file ../../babel.config.js",
16
- "test": "run-s test:*",
17
- "test:eslint": "eslint src test",
18
- "test:unit": "jest"
19
- },
20
12
  "repository": {
21
13
  "type": "git",
22
14
  "url": "git://github.com/webdriverio/webdriverio.git"
@@ -30,12 +22,12 @@
30
22
  "url": "https://github.com/webdriverio/webdriverio/issues"
31
23
  },
32
24
  "dependencies": {
33
- "@wdio/logger": "6.0.16",
25
+ "@wdio/logger": "6.7.3",
34
26
  "deepmerge": "^4.0.0",
35
27
  "glob": "^7.1.2"
36
28
  },
37
29
  "publishConfig": {
38
30
  "access": "public"
39
31
  },
40
- "gitHead": "df7da4b57c2887b1da3fccfac6efc6f0e9ea1ffc"
32
+ "gitHead": "2d72a4f1be35727342bf31b750d76eab6c8b50e9"
41
33
  }