@wdio/webdriver-mock-service 10.0.0-alpha.150 → 10.0.0-alpha.18
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/build/WebDriverMock.d.ts +5 -30
- package/build/WebDriverMock.d.ts.map +1 -1
- package/build/index.d.ts +1 -5
- package/build/index.d.ts.map +1 -1
- package/build/index.js +32 -109
- package/package.json +11 -9
package/build/WebDriverMock.d.ts
CHANGED
|
@@ -1,45 +1,20 @@
|
|
|
1
|
-
import
|
|
1
|
+
import nock from 'nock';
|
|
2
2
|
export interface CommandMock {
|
|
3
|
-
[commandName: string]: (...args: unknown[]) =>
|
|
4
|
-
}
|
|
5
|
-
export interface MockInterceptor {
|
|
6
|
-
times(n: number): MockInterceptor;
|
|
7
|
-
once(): MockInterceptor;
|
|
8
|
-
twice(): MockInterceptor;
|
|
9
|
-
reply(statusCode: number, data?: unknown | (() => unknown)): void;
|
|
10
|
-
}
|
|
11
|
-
declare class UndiciMockInterceptor implements MockInterceptor {
|
|
12
|
-
#private;
|
|
13
|
-
private readonly pool;
|
|
14
|
-
private readonly opts;
|
|
15
|
-
constructor(pool: Interceptable, opts: {
|
|
16
|
-
path: (path: string) => boolean;
|
|
17
|
-
method: string;
|
|
18
|
-
body?: (body: Record<string, unknown>) => boolean;
|
|
19
|
-
});
|
|
20
|
-
times(n: number): this;
|
|
21
|
-
once(): this;
|
|
22
|
-
twice(): this;
|
|
23
|
-
reply(statusCode: number, data?: unknown | (() => unknown)): void;
|
|
3
|
+
[commandName: string]: (...args: unknown[]) => nock.Interceptor;
|
|
24
4
|
}
|
|
25
5
|
export default class WebDriverMock {
|
|
26
|
-
#private;
|
|
27
6
|
path: string;
|
|
28
7
|
command: CommandMock;
|
|
8
|
+
scope: nock.Scope;
|
|
29
9
|
constructor(host?: string, port?: number, path?: string);
|
|
30
10
|
/**
|
|
31
11
|
* To allow random session IDs in url paths we have to set up a custom
|
|
32
12
|
* matcher that strips out the sessionID part from the expected url
|
|
33
13
|
* and actual url and replaces it with a constant session id
|
|
34
14
|
* @param {String} expectedPath path to match against
|
|
35
|
-
* @returns {Function} to be called by
|
|
15
|
+
* @returns {Function} to be called by Nock to match actual path
|
|
36
16
|
*/
|
|
37
17
|
static pathMatcher(expectedPath: string): (path: string) => boolean;
|
|
38
|
-
get(_obj: unknown, commandName: string): (...args: unknown[]) =>
|
|
39
|
-
/**
|
|
40
|
-
* Clear all interceptors and recreate the shared MockAgent.
|
|
41
|
-
*/
|
|
42
|
-
static reset(): void;
|
|
18
|
+
get(_obj: unknown, commandName: string): (...args: unknown[]) => nock.Interceptor;
|
|
43
19
|
}
|
|
44
|
-
export {};
|
|
45
20
|
//# sourceMappingURL=WebDriverMock.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebDriverMock.d.ts","sourceRoot":"","sources":["../src/WebDriverMock.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"WebDriverMock.d.ts","sourceRoot":"","sources":["../src/WebDriverMock.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAmBvB,MAAM,WAAW,WAAW;IACxB,CAAC,WAAW,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,WAAW,CAAA;CAClE;AAUD,MAAM,CAAC,OAAO,OAAO,aAAa;IAGsC,IAAI,EAAE,MAAM;IAFhF,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAA;gBACL,IAAI,GAAE,MAAoB,EAAE,IAAI,GAAE,MAAa,EAAS,IAAI,GAAE,MAAY;IAOtF;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,CAAC,IAAI,EAAC,MAAM,KAAI,OAAO;IAqBjE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,IAI1B,GAAG,MAAM,OAAO,EAAE;CAoCjC"}
|
package/build/index.d.ts
CHANGED
|
@@ -18,17 +18,13 @@ export default class WebdriverMockService implements Services.ServiceInstance {
|
|
|
18
18
|
waitForExistScenario(): void;
|
|
19
19
|
asyncIterationScenario(): string[];
|
|
20
20
|
parentNextPreviousElementChaining(): void;
|
|
21
|
-
|
|
21
|
+
multiremoteFetch(): void;
|
|
22
22
|
customCommandScenario(times?: number): void;
|
|
23
23
|
customSelectorScenario(): void;
|
|
24
24
|
waitForDisplayedScenario(): void;
|
|
25
25
|
cucumberScenario(): void;
|
|
26
26
|
executeMemLeakScenario(executeCalls: number): () => void;
|
|
27
27
|
requestRetryScenario(): void;
|
|
28
|
-
/**
|
|
29
|
-
* Reset all mock interceptors and re-register the default command stubs.
|
|
30
|
-
* Kept as `nockReset` for compatibility with smoke tests that call it by name.
|
|
31
|
-
*/
|
|
32
28
|
nockReset(): void;
|
|
33
29
|
}
|
|
34
30
|
/**
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,aAAa,MAAM,oBAAoB,CAAA;AAW9C,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,QAAQ,CAAC,eAAe;IACzE,OAAO,CAAC,QAAQ,CAAC,CAAsD;IACvE,OAAO,CAAC,KAAK,CAAsB;;IAMnC,IAAI;IAiBJ,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,IAAI;IAK/C,MAAM,CACF,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB;IA4BjE,aAAa;IAQb,kBAAkB;IASlB,qBAAqB;IAKrB,sBAAsB;IAYtB,wBAAwB;IAUxB,6BAA6B;IAU7B,2BAA2B;IA+B3B,sBAAsB;IAgBtB,oBAAoB;IAQpB,sBAAsB;IAStB,iCAAiC;IAQjC,gBAAgB;IAShB,qBAAqB,CAAC,KAAK,SAAI;IAa/B,sBAAsB;IAUtB,wBAAwB;IASxB,gBAAgB;IAShB,sBAAsB,CAAC,YAAY,EAAE,MAAM;IAa3C,oBAAoB;IAOpB,SAAS;CAKZ;AAED;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,eAAO,MAAM,QAAQ;;0BACC,WAAW,CAAC,MAAM;;CAQvC,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import nock2 from "nock";
|
|
3
|
+
import { v4 as uuidv4 } from "uuid";
|
|
4
|
+
|
|
1
5
|
// src/WebDriverMock.ts
|
|
2
|
-
import
|
|
6
|
+
import nock from "nock";
|
|
3
7
|
import {
|
|
4
8
|
WebDriverProtocol,
|
|
9
|
+
MJsonWProtocol,
|
|
5
10
|
AppiumProtocol,
|
|
6
11
|
ChromiumProtocol,
|
|
7
12
|
SauceLabsProtocol,
|
|
@@ -11,6 +16,7 @@ var REGEXP_SESSION_ID = /\/[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0
|
|
|
11
16
|
var SESSION_ID = "XXX";
|
|
12
17
|
var protocols = [
|
|
13
18
|
WebDriverProtocol,
|
|
19
|
+
MJsonWProtocol,
|
|
14
20
|
AppiumProtocol,
|
|
15
21
|
ChromiumProtocol,
|
|
16
22
|
SauceLabsProtocol,
|
|
@@ -24,79 +30,23 @@ for (const protocol of protocols) {
|
|
|
24
30
|
}
|
|
25
31
|
}
|
|
26
32
|
}
|
|
27
|
-
var sharedAgent;
|
|
28
|
-
function configureNetConnect(agent) {
|
|
29
|
-
agent.disableNetConnect();
|
|
30
|
-
agent.enableNetConnect((host) => !String(host).endsWith(":4444"));
|
|
31
|
-
}
|
|
32
|
-
function getOrCreateAgent() {
|
|
33
|
-
if (!sharedAgent) {
|
|
34
|
-
sharedAgent = new MockAgent();
|
|
35
|
-
configureNetConnect(sharedAgent);
|
|
36
|
-
setGlobalDispatcher(sharedAgent);
|
|
37
|
-
}
|
|
38
|
-
return sharedAgent;
|
|
39
|
-
}
|
|
40
|
-
var UndiciMockInterceptor = class {
|
|
41
|
-
constructor(pool, opts) {
|
|
42
|
-
this.pool = pool;
|
|
43
|
-
this.opts = opts;
|
|
44
|
-
}
|
|
45
|
-
pool;
|
|
46
|
-
opts;
|
|
47
|
-
#times = null;
|
|
48
|
-
times(n) {
|
|
49
|
-
this.#times = n;
|
|
50
|
-
return this;
|
|
51
|
-
}
|
|
52
|
-
once() {
|
|
53
|
-
return this.times(1);
|
|
54
|
-
}
|
|
55
|
-
twice() {
|
|
56
|
-
return this.times(2);
|
|
57
|
-
}
|
|
58
|
-
reply(statusCode, data) {
|
|
59
|
-
const interceptOpts = {
|
|
60
|
-
path: this.opts.path,
|
|
61
|
-
method: this.opts.method
|
|
62
|
-
};
|
|
63
|
-
if (this.opts.body) {
|
|
64
|
-
interceptOpts.body = (body) => {
|
|
65
|
-
try {
|
|
66
|
-
const parsed = typeof body === "string" ? JSON.parse(body) : body;
|
|
67
|
-
return this.opts.body(parsed);
|
|
68
|
-
} catch {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
const dataOrFn = typeof data === "function" ? () => data() : data;
|
|
74
|
-
const mock = this.pool.intercept(interceptOpts).reply(statusCode, dataOrFn);
|
|
75
|
-
if (this.#times === Infinity) {
|
|
76
|
-
mock.persist();
|
|
77
|
-
} else if (this.#times !== null && this.#times > 0) {
|
|
78
|
-
mock.times(this.#times);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
33
|
var WebDriverMock = class _WebDriverMock {
|
|
83
34
|
constructor(host = "localhost", port = 4444, path = "/") {
|
|
84
35
|
this.path = path;
|
|
85
|
-
this
|
|
86
|
-
|
|
87
|
-
|
|
36
|
+
this.scope = nock(`http://${host}:${port}`, {
|
|
37
|
+
encodedQueryParams: true
|
|
38
|
+
});
|
|
88
39
|
this.command = new Proxy({}, { get: this.get.bind(this) });
|
|
89
40
|
}
|
|
90
41
|
path;
|
|
91
42
|
command;
|
|
92
|
-
|
|
93
|
-
#pool;
|
|
43
|
+
scope;
|
|
94
44
|
/**
|
|
95
45
|
* To allow random session IDs in url paths we have to set up a custom
|
|
96
46
|
* matcher that strips out the sessionID part from the expected url
|
|
97
47
|
* and actual url and replaces it with a constant session id
|
|
98
48
|
* @param {String} expectedPath path to match against
|
|
99
|
-
* @returns {Function} to be called by
|
|
49
|
+
* @returns {Function} to be called by Nock to match actual path
|
|
100
50
|
*/
|
|
101
51
|
static pathMatcher(expectedPath) {
|
|
102
52
|
return (path) => {
|
|
@@ -104,9 +54,9 @@ var WebDriverMock = class _WebDriverMock {
|
|
|
104
54
|
if (!sessionId) {
|
|
105
55
|
return path === expectedPath;
|
|
106
56
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return
|
|
57
|
+
expectedPath = expectedPath.replace(":sessionId", SESSION_ID);
|
|
58
|
+
path = path.replace(`${sessionId[0].slice(1)}`, SESSION_ID);
|
|
59
|
+
return path === expectedPath;
|
|
110
60
|
};
|
|
111
61
|
}
|
|
112
62
|
get(_obj, commandName) {
|
|
@@ -116,42 +66,24 @@ var WebDriverMock = class _WebDriverMock {
|
|
|
116
66
|
for (const [i, param] of Object.entries(commandData.variables || [])) {
|
|
117
67
|
urlPath = urlPath.replace(`:${param.name}`, args[parseInt(i)]);
|
|
118
68
|
}
|
|
119
|
-
const path = _WebDriverMock.pathMatcher(urlPath);
|
|
120
69
|
if (method === "POST") {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (param.required && typeof body[param.name] === "undefined") {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
70
|
+
const reqMethod2 = method.toLowerCase();
|
|
71
|
+
return this.scope[reqMethod2](_WebDriverMock.pathMatcher(urlPath), (body) => {
|
|
72
|
+
for (const param of commandData.parameters) {
|
|
73
|
+
if (!body[param.name]) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (param.required && typeof body[param.name] === "undefined") {
|
|
77
|
+
return false;
|
|
132
78
|
}
|
|
133
|
-
return true;
|
|
134
79
|
}
|
|
80
|
+
return true;
|
|
135
81
|
});
|
|
136
82
|
}
|
|
137
|
-
|
|
83
|
+
const reqMethod = method.toLowerCase();
|
|
84
|
+
return this.scope[reqMethod](_WebDriverMock.pathMatcher(urlPath));
|
|
138
85
|
};
|
|
139
86
|
}
|
|
140
|
-
/**
|
|
141
|
-
* Clear all interceptors and recreate the shared MockAgent.
|
|
142
|
-
*/
|
|
143
|
-
static reset() {
|
|
144
|
-
const previous = sharedAgent;
|
|
145
|
-
sharedAgent = new MockAgent();
|
|
146
|
-
configureNetConnect(sharedAgent);
|
|
147
|
-
setGlobalDispatcher(sharedAgent);
|
|
148
|
-
if (previous) {
|
|
149
|
-
void previous.close();
|
|
150
|
-
}
|
|
151
|
-
if (getGlobalDispatcher().constructor.name !== "MockAgent") {
|
|
152
|
-
setGlobalDispatcher(sharedAgent);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
87
|
};
|
|
156
88
|
|
|
157
89
|
// src/constants.ts
|
|
@@ -206,7 +138,7 @@ var WebdriverMockService = class {
|
|
|
206
138
|
init() {
|
|
207
139
|
this._mock.command.status().times(Infinity).reply(200, { value: {} });
|
|
208
140
|
this._mock.command.newSession().times(Infinity).reply(200, () => {
|
|
209
|
-
newSession.value.sessionId =
|
|
141
|
+
newSession.value.sessionId = uuidv4();
|
|
210
142
|
return newSession;
|
|
211
143
|
});
|
|
212
144
|
this._mock.command.deleteSession().times(2).reply(200, deleteSession);
|
|
@@ -235,7 +167,7 @@ var WebdriverMockService = class {
|
|
|
235
167
|
this._browser.addCommand("clickScenario", this.clickScenario.bind(this));
|
|
236
168
|
this._browser.addCommand("isExistingScenario", this.isExistingScenario.bind(this));
|
|
237
169
|
this._browser.addCommand("isNotExistingScenario", this.isNotExistingScenario.bind(this));
|
|
238
|
-
this._browser.addCommand("
|
|
170
|
+
this._browser.addCommand("multiremoteFetch", this.multiremoteFetch.bind(this));
|
|
239
171
|
this._browser.addCommand("asyncIterationScenario", this.asyncIterationScenario.bind(this));
|
|
240
172
|
this._browser.addCommand("parentElementChaining", this.parentNextPreviousElementChaining.bind(this));
|
|
241
173
|
this._browser.addCommand("refetchElementScenario", this.refetchElementScenario.bind(this));
|
|
@@ -338,7 +270,7 @@ var WebdriverMockService = class {
|
|
|
338
270
|
this._mock.command.executeScript().reply(200, { value: elemParentResponse });
|
|
339
271
|
this._mock.command.getElementText(ELEMENT_REFETCHED).reply(200, { value: "some element text" });
|
|
340
272
|
}
|
|
341
|
-
|
|
273
|
+
multiremoteFetch() {
|
|
342
274
|
const elemResponse = { [ELEM_PROP]: ELEMENT_ID };
|
|
343
275
|
const elem2Response = { [ELEM_PROP]: ELEMENT_REFETCHED };
|
|
344
276
|
this._mock.command.findElement().twice().reply(200, { value: elemResponse });
|
|
@@ -389,13 +321,9 @@ var WebdriverMockService = class {
|
|
|
389
321
|
this._mock.command.navigateTo().times(3).reply(500, {});
|
|
390
322
|
this._mock.command.navigateTo().reply(200, { value: null });
|
|
391
323
|
}
|
|
392
|
-
/**
|
|
393
|
-
* Reset all mock interceptors and re-register the default command stubs.
|
|
394
|
-
* Kept as `nockReset` for compatibility with smoke tests that call it by name.
|
|
395
|
-
*/
|
|
396
324
|
nockReset() {
|
|
397
|
-
|
|
398
|
-
|
|
325
|
+
nock2.cleanAll();
|
|
326
|
+
nock2.abortPendingRequests();
|
|
399
327
|
this.init();
|
|
400
328
|
}
|
|
401
329
|
};
|
|
@@ -405,12 +333,7 @@ var launcher = class WebdriverMockLauncher {
|
|
|
405
333
|
config.port = 4444;
|
|
406
334
|
config.runnerEnv = {
|
|
407
335
|
...config.runnerEnv || {},
|
|
408
|
-
|
|
409
|
-
* Opt workers into undici + MockAgent instead of native fetch + nock.
|
|
410
|
-
* `WDIO_UNIT_TESTS` alone still selects the web fetch implementation for
|
|
411
|
-
* Vitest unit tests that stub `globalThis.fetch`.
|
|
412
|
-
*/
|
|
413
|
-
WDIO_USE_UNDICI_MOCK: "true"
|
|
336
|
+
WDIO_USE_NATIVE_FETCH: "true"
|
|
414
337
|
};
|
|
415
338
|
}
|
|
416
339
|
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/webdriver-mock-service",
|
|
3
|
-
"version": "10.0.0-alpha.
|
|
3
|
+
"version": "10.0.0-alpha.18+dbf0f4971",
|
|
4
4
|
"description": "A WebdriverIO service to stub all endpoints for internal testing purposes.",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-webdriver-mock-service",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"engines": {
|
|
9
|
-
"node": ">=
|
|
9
|
+
"node": ">=18.20.0"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -25,18 +25,20 @@
|
|
|
25
25
|
"import": "./build/index.js"
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
|
-
"typeScriptVersion": "
|
|
28
|
+
"typeScriptVersion": "3.8.3",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@
|
|
31
|
-
"@wdio/
|
|
32
|
-
"
|
|
33
|
-
"
|
|
30
|
+
"@types/uuid": "^10.0.0",
|
|
31
|
+
"@wdio/protocols": "9.31.5",
|
|
32
|
+
"@wdio/types": "9.32.0",
|
|
33
|
+
"nock": "14.0.15",
|
|
34
|
+
"uuid": "^11.1.0",
|
|
35
|
+
"webdriverio": "9.32.0"
|
|
34
36
|
},
|
|
35
37
|
"devDependencies": {
|
|
36
|
-
"@wdio/globals": "10.0.0-alpha.
|
|
38
|
+
"@wdio/globals": "10.0.0-alpha.18+dbf0f4971"
|
|
37
39
|
},
|
|
38
40
|
"publishConfig": {
|
|
39
41
|
"access": "public"
|
|
40
42
|
},
|
|
41
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "dbf0f497130676040ce4212d9cf6459adfe16c42"
|
|
42
44
|
}
|