webdriverio 9.0.0-alpha.114 → 9.0.0-alpha.321

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.
Files changed (81) hide show
  1. package/build/commands/browser/downloadFile.d.ts +34 -0
  2. package/build/commands/browser/downloadFile.d.ts.map +1 -0
  3. package/build/commands/browser/downloadFile.js +79 -0
  4. package/build/commands/browser/getCookies.d.ts +2 -1
  5. package/build/commands/browser/getCookies.d.ts.map +1 -1
  6. package/build/commands/browser/getPuppeteer.d.ts.map +1 -1
  7. package/build/commands/browser/getPuppeteer.js +9 -10
  8. package/build/commands/browser/mock.d.ts +2 -2
  9. package/build/commands/browser/mock.d.ts.map +1 -1
  10. package/build/commands/browser/reloadSession.d.ts +20 -0
  11. package/build/commands/browser/reloadSession.d.ts.map +1 -1
  12. package/build/commands/browser/reloadSession.js +21 -1
  13. package/build/commands/browser.d.ts +1 -0
  14. package/build/commands/browser.d.ts.map +1 -1
  15. package/build/commands/browser.js +1 -0
  16. package/build/commands/element/dragAndDrop.d.ts +2 -1
  17. package/build/commands/element/dragAndDrop.d.ts.map +1 -1
  18. package/build/commands/element/isExisting.d.ts.map +1 -1
  19. package/build/commands/element/isExisting.js +3 -1
  20. package/build/commands/element/nextElement.d.ts +1 -1
  21. package/build/commands/element/nextElement.d.ts.map +1 -1
  22. package/build/commands/element/parentElement.d.ts +1 -1
  23. package/build/commands/element/parentElement.d.ts.map +1 -1
  24. package/build/commands/element/previousElement.d.ts +1 -1
  25. package/build/commands/element/previousElement.d.ts.map +1 -1
  26. package/build/commands/element/shadow$$.d.ts +1 -1
  27. package/build/commands/element/shadow$$.d.ts.map +1 -1
  28. package/build/commands/element/shadow$.d.ts +1 -1
  29. package/build/commands/element/shadow$.d.ts.map +1 -1
  30. package/build/commands/mock/redirect.d.ts +22 -0
  31. package/build/commands/mock/redirect.d.ts.map +1 -0
  32. package/build/commands/mock/redirect.js +22 -0
  33. package/build/commands/mock/request.d.ts +37 -0
  34. package/build/commands/mock/request.d.ts.map +1 -0
  35. package/build/commands/mock/request.js +37 -0
  36. package/build/commands/mock/requestOnce.d.ts +37 -0
  37. package/build/commands/mock/requestOnce.d.ts.map +1 -0
  38. package/build/commands/mock/requestOnce.js +37 -0
  39. package/build/commands/mock/restore.d.ts +1 -1
  40. package/build/commands/mock/restore.js +1 -1
  41. package/build/constants.d.ts +2 -2
  42. package/build/constants.d.ts.map +1 -1
  43. package/build/{cjs/index.js → index.cjs} +3 -3
  44. package/build/index.d.cts +2 -0
  45. package/build/index.d.cts.map +1 -0
  46. package/build/index.d.ts +10 -5
  47. package/build/index.d.ts.map +1 -1
  48. package/build/index.js +2 -1
  49. package/build/protocol-stub.d.ts +2 -2
  50. package/build/protocol-stub.d.ts.map +1 -1
  51. package/build/protocol-stub.js +4 -3
  52. package/build/shadowRoot.d.ts.map +1 -1
  53. package/build/shadowRoot.js +2 -3
  54. package/build/types.d.ts +34 -25
  55. package/build/types.d.ts.map +1 -1
  56. package/build/utils/actions/pointer.d.ts +3 -1
  57. package/build/utils/actions/pointer.d.ts.map +1 -1
  58. package/build/utils/actions/wheel.d.ts +1 -1
  59. package/build/utils/actions/wheel.d.ts.map +1 -1
  60. package/build/utils/detectBackend.d.ts +1 -1
  61. package/build/utils/detectBackend.d.ts.map +1 -1
  62. package/build/utils/detectBackend.js +2 -3
  63. package/build/utils/driver.d.ts +5 -6
  64. package/build/utils/driver.d.ts.map +1 -1
  65. package/build/utils/driver.js +1 -1
  66. package/build/utils/findStrategy.js +2 -2
  67. package/build/utils/implicitWait.js +1 -1
  68. package/build/utils/index.js +1 -1
  69. package/build/utils/interception/index.d.ts +17 -9
  70. package/build/utils/interception/index.d.ts.map +1 -1
  71. package/build/utils/interception/index.js +117 -49
  72. package/build/utils/interception/types.d.ts +0 -3
  73. package/build/utils/interception/types.d.ts.map +1 -1
  74. package/build/utils/interception/utils.d.ts +1 -8
  75. package/build/utils/interception/utils.d.ts.map +1 -1
  76. package/build/utils/interception/utils.js +18 -21
  77. package/build/utils/refetchElement.js +2 -2
  78. package/package.json +13 -12
  79. package/build/cjs/index.d.ts +0 -2
  80. package/build/cjs/index.d.ts.map +0 -1
  81. package/build/cjs/package.json +0 -5
@@ -2,7 +2,7 @@
2
2
  import { type JsonCompatible } from '@wdio/types';
3
3
  import { type local } from 'webdriver';
4
4
  import { URLPattern } from 'urlpattern-polyfill';
5
- import type { MockOptions, RespondWithOptions } from './types.js';
5
+ import type { MockFilterOptions, RequestWithOptions, RespondWithOptions } from './types.js';
6
6
  import type { WaitForOptions } from '../../types.js';
7
7
  type RespondBody = string | JsonCompatible | Buffer;
8
8
  /**
@@ -14,11 +14,7 @@ type RespondBody = string | JsonCompatible | Buffer;
14
14
  export default class WebDriverInterception {
15
15
  #private;
16
16
  private constructor();
17
- static initiate(url: string,
18
- /**
19
- * ToDo(Christian): incorporate filterOptions
20
- */
21
- filterOptions: MockOptions, browser: WebdriverIO.Browser): Promise<WebDriverInterception>;
17
+ static initiate(url: string, filterOptions: MockFilterOptions, browser: WebdriverIO.Browser): Promise<WebDriverInterception>;
22
18
  /**
23
19
  * allows access to all requests made with given pattern
24
20
  */
@@ -38,11 +34,23 @@ export default class WebDriverInterception {
38
34
  * Restored mock does not emit events and could not mock responses
39
35
  */
40
36
  restore(): Promise<this>;
37
+ /**
38
+ * Always use request modification for the next request done by the browser.
39
+ * @param payload payload to overwrite the request
40
+ * @param once apply overwrite only once for the next request
41
+ * @returns this instance to chain commands
42
+ */
43
+ request(overwrite: RequestWithOptions, once?: boolean): this;
44
+ /**
45
+ * alias for `mock.request(…, true)`
46
+ */
47
+ requestOnce(payload: RequestWithOptions): this;
41
48
  /**
42
49
  * Always respond with same overwrite
43
- * @param {*} overwrites payload to overwrite the response
44
- * @param {*} params additional respond parameters to overwrite
45
- * @param {boolean} once apply overwrite only once for the next request
50
+ * @param {*} payload payload to overwrite the response
51
+ * @param {*} params additional respond parameters to overwrite
52
+ * @param {boolean} once apply overwrite only once for the next request
53
+ * @returns this instance to chain commands
46
54
  */
47
55
  respond(payload: RespondBody, params?: Omit<RespondWithOptions, 'body'>, once?: boolean): this;
48
56
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/interception/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAKhD,OAAO,KAAK,EAAE,WAAW,EAAsB,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAMpD,KAAK,WAAW,GAAG,MAAM,GAAG,cAAc,GAAG,MAAM,CAAA;AAEnD;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;;IAetC,OAAO;WAgBM,QAAQ,CACjB,GAAG,EAAE,MAAM;IACX;;OAEG;IACH,aAAa,EAAE,WAAW,EAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;IA6JhC;;OAEG;IACH,IAAI,KAAK,+CAER;IAED;;OAEG;IACH,KAAK;IAKL;;;OAGG;IACH,KAAK;IAML;;;;OAIG;IACG,OAAO;IAgBb;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,GAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAY3F;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,GAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAM;IAI/E;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO;IAMpB;;OAEG;IACH,SAAS;IAIT;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAO5C;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM;IAIhC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,kCAAkC,KAAK,IAAI,GAAG,qBAAqB;IAClH,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,kCAAkC,KAAK,IAAI,GAAG,qBAAqB;IAC9G,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,qBAAqB;IACnF,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,qBAAqB;IAC/E,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,kCAAkC,KAAK,IAAI,GAAG,qBAAqB;IAYrH,eAAe,CAAE,EACb,OAA8C,EAC9C,QAAgD,EAChD,UAAU,GACb,GAAE,cAAmB;CA2BzB;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,cAqBvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/interception/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAKhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAMpD,KAAK,WAAW,GAAG,MAAM,GAAG,cAAc,GAAG,MAAM,CAAA;AAOnD;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;;IAYtC,OAAO;WAkBM,QAAQ,CACjB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,iBAAiB,EAChC,OAAO,EAAE,WAAW,CAAC,OAAO;IAsNhC;;OAEG;IACH,IAAI,KAAK,+CAER;IAED;;OAEG;IACH,KAAK;IAKL;;;OAGG;IACH,KAAK;IAOL;;;;OAIG;IACG,OAAO;IAgBb;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,OAAO;IAMrD;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,kBAAkB;IAIvC;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,GAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAY3F;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,GAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAM;IAI/E;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO;IAMpB;;OAEG;IACH,SAAS;IAIT;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAO5C;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM;IAIhC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,kCAAkC,KAAK,IAAI,GAAG,qBAAqB;IAClH,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,kCAAkC,KAAK,IAAI,GAAG,qBAAqB;IAC9G,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,qBAAqB;IACnF,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,qBAAqB;IAC/E,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,kCAAkC,KAAK,IAAI,GAAG,qBAAqB;IAYrH,eAAe,CAAE,EACb,OAA8C,EAC9C,QAAgD,EAChD,UAAU,GACb,GAAE,cAAmB;CA2BzB;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,cAqBvD"}
@@ -16,14 +16,17 @@ let hasSubscribedToEvents = false;
16
16
  export default class WebDriverInterception {
17
17
  #pattern;
18
18
  #mockId;
19
+ #filterOptions;
19
20
  #browser;
20
21
  #emitter = new EventEmitter();
21
22
  #restored = false;
23
+ #requestOverwrites = [];
22
24
  #respondOverwrites = [];
23
25
  #calls = [];
24
- constructor(pattern, mockId, browser) {
26
+ constructor(pattern, mockId, filterOptions, browser) {
25
27
  this.#pattern = pattern;
26
28
  this.#mockId = mockId;
29
+ this.#filterOptions = filterOptions;
27
30
  this.#browser = browser;
28
31
  /**
29
32
  * attach network listener to this mock
@@ -31,11 +34,7 @@ export default class WebDriverInterception {
31
34
  browser.on('network.beforeRequestSent', this.#handleBeforeRequestSent.bind(this));
32
35
  browser.on('network.responseStarted', this.#handleResponseStarted.bind(this));
33
36
  }
34
- static async initiate(url,
35
- /**
36
- * ToDo(Christian): incorporate filterOptions
37
- */
38
- filterOptions, browser) {
37
+ static async initiate(url, filterOptions, browser) {
39
38
  const pattern = parseUrlPattern(url);
40
39
  if (!hasSubscribedToEvents) {
41
40
  await browser.sessionSubscribe({
@@ -61,7 +60,7 @@ export default class WebDriverInterception {
61
60
  search: getPatternParam(pattern, 'search')
62
61
  }]
63
62
  });
64
- return new WebDriverInterception(pattern, interception.intercept, browser);
63
+ return new WebDriverInterception(pattern, interception.intercept, filterOptions, browser);
65
64
  }
66
65
  #handleBeforeRequestSent(request) {
67
66
  /**
@@ -73,49 +72,33 @@ export default class WebDriverInterception {
73
72
  return;
74
73
  }
75
74
  /**
76
- * continue the request without modifications, if:
77
- */
78
- const continueRequest = (
79
- /**
80
- * - mock has no request/respond overwrites
81
- * - no request modifications are set
82
- * - no errorReason is set
83
- * - no requestWith is set
84
- */
85
- this.#respondOverwrites.length === 0 ||
86
- (!this.#respondOverwrites[0].abort &&
87
- !this.#respondOverwrites[0].requestWith));
88
- /**
89
- * check if request matches the mock url
75
+ * check if request matches filter option and do nothing if not
90
76
  */
91
- if (continueRequest) {
92
- this.#emitter.emit('continue', request.request.request);
77
+ if (!this.#matchesFilterOptions(request)) {
93
78
  return this.#browser.networkContinueRequest({
94
79
  request: request.request.request
95
80
  });
96
81
  }
97
82
  this.#emitter.emit('request', request);
98
- const { requestWith, abort } = this.#respondOverwrites[0].once
99
- ? this.#respondOverwrites.shift() || {}
100
- : this.#respondOverwrites[0];
101
- /**
102
- * check if should abort the request
103
- */
104
- if (abort) {
105
- this.#emitter.emit('fail', request.request.request);
106
- return this.#browser.networkFailRequest({ request: request.request.request });
107
- }
108
- /**
109
- * continue request (possibly with overwrites)
110
- */
111
- if (requestWith) {
83
+ const hasRequestOverwrites = this.#requestOverwrites.length > 0;
84
+ if (hasRequestOverwrites) {
85
+ const { overwrite, abort } = this.#requestOverwrites[0].once
86
+ ? this.#requestOverwrites.shift() || {}
87
+ : this.#requestOverwrites[0];
88
+ if (abort) {
89
+ this.#emitter.emit('fail', request.request.request);
90
+ return this.#browser.networkFailRequest({ request: request.request.request });
91
+ }
112
92
  this.#emitter.emit('overwrite', request);
113
93
  return this.#browser.networkContinueRequest({
114
94
  request: request.request.request,
115
- ...parseOverwrite(requestWith, request)
95
+ ...(overwrite ? parseOverwrite(overwrite, request) : {})
116
96
  });
117
97
  }
118
- throw new Error('This should never happen');
98
+ this.#emitter.emit('continue', request.request.request);
99
+ return this.#browser.networkContinueRequest({
100
+ request: request.request.request
101
+ });
119
102
  }
120
103
  #handleResponseStarted(request) {
121
104
  /**
@@ -134,7 +117,8 @@ export default class WebDriverInterception {
134
117
  * - mock has no request/respond overwrites
135
118
  * - no request modifications are set, e.g. no overwrite is set
136
119
  */
137
- this.#respondOverwrites.length === 0 ||
120
+ !this.#matchesFilterOptions(request) ||
121
+ this.#respondOverwrites.length === 0 ||
138
122
  !this.#respondOverwrites[0].overwrite);
139
123
  /**
140
124
  * check if request matches the mock url
@@ -143,7 +127,7 @@ export default class WebDriverInterception {
143
127
  this.#emitter.emit('continue', request.request.request);
144
128
  return this.#browser.networkProvideResponse({
145
129
  request: request.request.request
146
- });
130
+ }).catch(this.#handleNetworkProvideResponseError);
147
131
  }
148
132
  this.#calls.push(request);
149
133
  const { overwrite } = this.#respondOverwrites[0].once
@@ -157,7 +141,7 @@ export default class WebDriverInterception {
157
141
  return this.#browser.networkProvideResponse({
158
142
  request: request.request.request,
159
143
  ...parseOverwrite(overwrite, request)
160
- });
144
+ }).catch(this.#handleNetworkProvideResponseError);
161
145
  }
162
146
  /**
163
147
  * continue request as is
@@ -165,11 +149,76 @@ export default class WebDriverInterception {
165
149
  this.#emitter.emit('continue', request.request.request);
166
150
  return this.#browser.networkProvideResponse({
167
151
  request: request.request.request
168
- });
152
+ }).catch(this.#handleNetworkProvideResponseError);
153
+ }
154
+ /**
155
+ * It appears that the networkProvideResponse method may throw an "no such request" error even though the request
156
+ * is marked as "blocked", in these cases we can safely ignore the error.
157
+ * @param err Bidi message error
158
+ */
159
+ #handleNetworkProvideResponseError(err) {
160
+ if (err.message.endsWith('no such request')) {
161
+ return;
162
+ }
163
+ throw err;
169
164
  }
170
165
  #isRequestMatching(request) {
171
166
  return request.isBlocked && this.#pattern && this.#pattern.test(request.request.url);
172
167
  }
168
+ #matchesFilterOptions(request) {
169
+ let isRequestMatching = true;
170
+ if (this.#filterOptions.method) {
171
+ isRequestMatching = typeof this.#filterOptions.method === 'function'
172
+ ? this.#filterOptions.method(request.request.method)
173
+ : this.#filterOptions.method === request.request.method;
174
+ }
175
+ if (this.#filterOptions.requestHeaders) {
176
+ isRequestMatching = typeof this.#filterOptions.requestHeaders === 'function'
177
+ ? this.#filterOptions.requestHeaders(request.request.headers.reduce((acc, { name, value }) => {
178
+ acc[name] = value.type === 'string' ? value.value : Buffer.from(value.value, 'base64').toString();
179
+ return acc;
180
+ }, {}))
181
+ : Object.entries(this.#filterOptions.requestHeaders).every(([key, value]) => {
182
+ const header = request.request.headers.find(({ name }) => name === key);
183
+ if (!header) {
184
+ return false;
185
+ }
186
+ return header.value.type === 'string'
187
+ ? header.value.value === value
188
+ : Buffer.from(header.value.value, 'base64').toString() === value;
189
+ });
190
+ }
191
+ if (this.#filterOptions.responseHeaders && 'response' in request) {
192
+ isRequestMatching = typeof this.#filterOptions.responseHeaders === 'function'
193
+ ? this.#filterOptions.responseHeaders(request.response.headers.reduce((acc, { name, value }) => {
194
+ acc[name] = value.type === 'string' ? value.value : Buffer.from(value.value, 'base64').toString();
195
+ return acc;
196
+ }, {}))
197
+ : Object.entries(this.#filterOptions.responseHeaders).every(([key, value]) => {
198
+ const header = request.response.headers.find(({ name }) => name === key);
199
+ if (!header) {
200
+ return false;
201
+ }
202
+ return header.value.type === 'string'
203
+ ? header.value.value === value
204
+ : Buffer.from(header.value.value, 'base64').toString() === value;
205
+ });
206
+ }
207
+ if (this.#filterOptions.statusCode && 'response' in request) {
208
+ isRequestMatching = typeof this.#filterOptions.statusCode === 'function'
209
+ ? this.#filterOptions.statusCode(request.response.status)
210
+ : this.#filterOptions.statusCode === request.response.status;
211
+ }
212
+ return isRequestMatching;
213
+ }
214
+ #setOverwrite = (overwriteProp, { overwrite, abort, once }) => {
215
+ return once
216
+ ? [
217
+ ...overwriteProp.filter(({ once }) => once),
218
+ { overwrite, abort, once }
219
+ ]
220
+ : [{ overwrite, abort }];
221
+ };
173
222
  /**
174
223
  * allows access to all requests made with given pattern
175
224
  */
@@ -190,6 +239,7 @@ export default class WebDriverInterception {
190
239
  reset() {
191
240
  this.clear();
192
241
  this.#respondOverwrites = [];
242
+ this.#requestOverwrites = [];
193
243
  return this;
194
244
  }
195
245
  /**
@@ -209,11 +259,29 @@ export default class WebDriverInterception {
209
259
  }
210
260
  return this;
211
261
  }
262
+ /**
263
+ * Always use request modification for the next request done by the browser.
264
+ * @param payload payload to overwrite the request
265
+ * @param once apply overwrite only once for the next request
266
+ * @returns this instance to chain commands
267
+ */
268
+ request(overwrite, once) {
269
+ this.#ensureNotRestored();
270
+ this.#requestOverwrites = this.#setOverwrite(this.#requestOverwrites, { overwrite, once });
271
+ return this;
272
+ }
273
+ /**
274
+ * alias for `mock.request(…, true)`
275
+ */
276
+ requestOnce(payload) {
277
+ return this.request(payload, true);
278
+ }
212
279
  /**
213
280
  * Always respond with same overwrite
214
- * @param {*} overwrites payload to overwrite the response
215
- * @param {*} params additional respond parameters to overwrite
216
- * @param {boolean} once apply overwrite only once for the next request
281
+ * @param {*} payload payload to overwrite the response
282
+ * @param {*} params additional respond parameters to overwrite
283
+ * @param {boolean} once apply overwrite only once for the next request
284
+ * @returns this instance to chain commands
217
285
  */
218
286
  respond(payload, params = {}, once) {
219
287
  this.#ensureNotRestored();
@@ -223,7 +291,7 @@ export default class WebDriverInterception {
223
291
  ? payload.toString('base64')
224
292
  : JSON.stringify(payload);
225
293
  const overwrite = { body, ...params };
226
- this.#respondOverwrites.push({ overwrite, once });
294
+ this.#respondOverwrites = this.#setOverwrite(this.#respondOverwrites, { overwrite, once });
227
295
  return this;
228
296
  }
229
297
  /**
@@ -239,7 +307,7 @@ export default class WebDriverInterception {
239
307
  */
240
308
  abort(once) {
241
309
  this.#ensureNotRestored();
242
- this.#respondOverwrites.push({ abort: true, once });
310
+ this.#requestOverwrites = this.#setOverwrite(this.#requestOverwrites, { abort: true, once });
243
311
  return this;
244
312
  }
245
313
  /**
@@ -256,7 +324,7 @@ export default class WebDriverInterception {
256
324
  redirect(redirectUrl, once) {
257
325
  this.#ensureNotRestored();
258
326
  const requestWith = { url: redirectUrl };
259
- this.#respondOverwrites.push({ requestWith, once });
327
+ this.request(requestWith, once);
260
328
  return this;
261
329
  }
262
330
  /**
@@ -2,11 +2,9 @@ import type { local } from 'webdriver';
2
2
  import type { Cookie } from '@wdio/protocols';
3
3
  export type MockFilterOptions = {
4
4
  method?: string | ((method: string) => boolean);
5
- headers?: Record<string, string> | ((headers: Record<string, string>) => boolean);
6
5
  requestHeaders?: Record<string, string> | ((headers: Record<string, string>) => boolean);
7
6
  responseHeaders?: Record<string, string> | ((headers: Record<string, string>) => boolean);
8
7
  statusCode?: number | ((statusCode: number) => boolean);
9
- postData?: string | ((payload: string | undefined) => boolean);
10
8
  };
11
9
  type Overwrite<T, Request> = T | ((request: Request) => T);
12
10
  type Methods = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH' | 'OPTIONS' | 'HEAD';
@@ -23,6 +21,5 @@ export interface RespondWithOptions extends Omit<RequestWithOptions, 'url' | 'me
23
21
  export interface MockRequestOptions {
24
22
  requestWith?: RequestWithOptions;
25
23
  }
26
- export type MockOptions = MockFilterOptions & MockRequestOptions;
27
24
  export {};
28
25
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/interception/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,MAAM,MAAM,iBAAiB,GAAG;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAA;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAA;IACxF,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAA;IACzF,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;IACvD,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,CAAA;CACjE,CAAA;AAED,KAAK,SAAS,CAAE,CAAC,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC,CAAC,CAAA;AAC3D,KAAK,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE/E,MAAM,WAAW,kBAAkB;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IAC/D,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACvE,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACrF,MAAM,CAAC,EAAE,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACrE,GAAG,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;CACpE;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,KAAK,GAAG,QAAQ,CAAC;IAClF,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;CAC3E;AAED,MAAM,WAAW,kBAAkB;IAC/B,WAAW,CAAC,EAAE,kBAAkB,CAAA;CACnC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,kBAAkB,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/interception/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,MAAM,MAAM,iBAAiB,GAAG;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAA;IACxF,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAA;IACzF,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;CAC1D,CAAA;AAED,KAAK,SAAS,CAAE,CAAC,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC,CAAC,CAAA;AAC3D,KAAK,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE/E,MAAM,WAAW,kBAAkB;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IAC/D,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACvE,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACrF,MAAM,CAAC,EAAE,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACrE,GAAG,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;CACpE;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,KAAK,GAAG,QAAQ,CAAC;IAClF,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAA;CAC3E;AAED,MAAM,WAAW,kBAAkB;IAC/B,WAAW,CAAC,EAAE,kBAAkB,CAAA;CACnC"}
@@ -5,13 +5,6 @@ import type { RequestWithOptions, RespondWithOptions } from './types.js';
5
5
  * @param overwrite request or response overwrite
6
6
  * @returns object to pass to the protocol
7
7
  */
8
- export declare function parseOverwrite(overwrite: RequestWithOptions | RespondWithOptions, request: local.NetworkBeforeRequestSentParameters | local.NetworkResponseCompletedParameters): {
9
- body: remote.NetworkBytesValue | undefined;
10
- headers: remote.NetworkHeader[];
11
- cookies: remote.NetworkSetCookieHeader[];
12
- method: string | undefined;
13
- statusCode: number | undefined;
14
- url: string | undefined;
15
- };
8
+ export declare function parseOverwrite<T extends RequestWithOptions | RespondWithOptions>(overwrite: T, request: local.NetworkBeforeRequestSentParameters | local.NetworkResponseCompletedParameters): Omit<T extends RequestWithOptions ? remote.NetworkContinueRequestParameters : remote.NetworkContinueResponseParameters, "request">;
16
9
  export declare function getPatternParam(pattern: URLPattern, key: keyof Omit<remote.NetworkUrlPatternPattern, 'type'>): string | undefined;
17
10
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/interception/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAExE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,OAAO,EAAE,KAAK,CAAC,kCAAkC,GAAG,KAAK,CAAC,kCAAkC;;;;;;;EA6E9K;AAED,wBAAgB,eAAe,CAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,wBAAwB,EAAE,MAAM,CAAC,sBAU7G"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/interception/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAExE;;;;GAIG;AACH,wBAAgB,cAAc,CAC1B,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,EAEjD,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,KAAK,CAAC,kCAAkC,GAAG,KAAK,CAAC,kCAAkC,sIA4E/F;AAED,wBAAgB,eAAe,CAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,wBAAwB,EAAE,MAAM,CAAC,sBAU7G"}
@@ -4,12 +4,12 @@
4
4
  * @returns object to pass to the protocol
5
5
  */
6
6
  export function parseOverwrite(overwrite, request) {
7
- let body = undefined;
7
+ const result = {};
8
8
  if ('body' in overwrite && overwrite.body) {
9
9
  const bodyOverwrite = typeof overwrite.body === 'function'
10
10
  ? overwrite.body(request)
11
11
  : overwrite.body;
12
- body = typeof bodyOverwrite === 'string' ?
12
+ result.body = typeof bodyOverwrite === 'string' ?
13
13
  /**
14
14
  * if body is a string we can pass it as is
15
15
  */
@@ -28,22 +28,20 @@ export function parseOverwrite(overwrite, request) {
28
28
  : btoa(JSON.stringify(bodyOverwrite))
29
29
  };
30
30
  }
31
- let headers = [];
32
- const headersOverwrite = typeof overwrite.headers === 'function'
33
- ? overwrite.headers(request)
34
- : overwrite.headers;
35
- if (headersOverwrite) {
36
- headers = Object.entries(headersOverwrite).map(([name, value]) => ({
31
+ if ('headers' in overwrite) {
32
+ const headersOverwrite = typeof overwrite.headers === 'function'
33
+ ? overwrite.headers(request)
34
+ : overwrite.headers;
35
+ result.headers = Object.entries(headersOverwrite || {}).map(([name, value]) => ({
37
36
  name,
38
37
  value: { type: 'string', value }
39
38
  }));
40
39
  }
41
- let cookies = [];
42
40
  if ('cookies' in overwrite && overwrite.cookies) {
43
41
  const cookieOverwrite = typeof overwrite.cookies === 'function'
44
42
  ? overwrite.cookies(request) || []
45
43
  : overwrite.cookies;
46
- cookies = cookieOverwrite.map((cookie) => ({
44
+ result.cookies = cookieOverwrite.map((cookie) => ({
47
45
  name: cookie.name,
48
46
  value: {
49
47
  type: 'string',
@@ -57,24 +55,23 @@ export function parseOverwrite(overwrite, request) {
57
55
  sameSite: cookie.sameSite?.toLowerCase(),
58
56
  }));
59
57
  }
60
- let statusCode = undefined;
61
58
  if ('statusCode' in overwrite && overwrite.statusCode) {
62
59
  const statusCodeOverwrite = typeof overwrite.statusCode === 'function'
63
60
  ? overwrite.statusCode(request)
64
61
  : overwrite.statusCode;
65
- statusCode = statusCodeOverwrite;
62
+ result.statusCode = statusCodeOverwrite;
66
63
  }
67
- const method = 'method' in overwrite
68
- ? typeof overwrite.method === 'function'
64
+ if ('method' in overwrite) {
65
+ result.method = typeof overwrite.method === 'function'
69
66
  ? overwrite.method(request)
70
- : overwrite.method
71
- : undefined;
72
- const url = 'url' in overwrite
73
- ? typeof overwrite.url === 'function'
67
+ : overwrite.method;
68
+ }
69
+ if ('url' in overwrite) {
70
+ result.url = typeof overwrite.url === 'function'
74
71
  ? overwrite.url(request)
75
- : overwrite.url
76
- : undefined;
77
- return { body, headers, cookies, method, statusCode, url };
72
+ : overwrite.url;
73
+ }
74
+ return result;
78
75
  }
79
76
  export function getPatternParam(pattern, key) {
80
77
  if (key !== 'pathname' && pattern[key] === '*') {
@@ -19,8 +19,8 @@ export default async function refetchElement(currentElement, commandName) {
19
19
  */
20
20
  return selectors.reduce(async (elementPromise, { selector, index }, currentIndex) => {
21
21
  const resolvedElement = await elementPromise;
22
- let nextElement = index > 0 ? (await resolvedElement.$$(selector))[index] : null;
23
- nextElement = nextElement || await resolvedElement.$(selector);
22
+ let nextElement = index > 0 ? await resolvedElement.$$(selector)[index]?.getElement() : null;
23
+ nextElement = nextElement || await resolvedElement.$(selector).getElement();
24
24
  /**
25
25
  * For error purposes, changing command name to '$' if we aren't
26
26
  * on the last element of the array
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "webdriverio",
3
3
  "description": "Next-gen browser and mobile automation test framework for Node.js",
4
- "version": "9.0.0-alpha.114+b1a80c10f",
4
+ "version": "9.0.0-alpha.321+63953a607",
5
5
  "homepage": "https://webdriver.io",
6
6
  "author": "Christian Bromann <mail@bromann.dev>",
7
7
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "cucumber",
44
44
  "testingbot"
45
45
  ],
46
- "main": "./build/cjs/index.js",
46
+ "main": "./build/index.cjs",
47
47
  "type": "module",
48
48
  "module": "./build/index.js",
49
49
  "exports": {
@@ -51,9 +51,9 @@
51
51
  {
52
52
  "types": "./build/index.d.ts",
53
53
  "import": "./build/index.js",
54
- "require": "./build/cjs/index.js"
54
+ "require": "./build/index.cjs"
55
55
  },
56
- "./build/cjs/index.js"
56
+ "./build/index.cjs"
57
57
  ],
58
58
  "./package.json": "./package.json"
59
59
  },
@@ -68,12 +68,12 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "@types/node": "^20.11.30",
71
- "@wdio/config": "9.0.0-alpha.114+b1a80c10f",
72
- "@wdio/logger": "9.0.0-alpha.114+b1a80c10f",
73
- "@wdio/protocols": "9.0.0-alpha.114+b1a80c10f",
74
- "@wdio/repl": "9.0.0-alpha.114+b1a80c10f",
75
- "@wdio/types": "9.0.0-alpha.114+b1a80c10f",
76
- "@wdio/utils": "9.0.0-alpha.114+b1a80c10f",
71
+ "@wdio/config": "9.0.0-alpha.321+63953a607",
72
+ "@wdio/logger": "9.0.0-alpha.321+63953a607",
73
+ "@wdio/protocols": "9.0.0-alpha.321+63953a607",
74
+ "@wdio/repl": "9.0.0-alpha.321+63953a607",
75
+ "@wdio/types": "9.0.0-alpha.321+63953a607",
76
+ "@wdio/utils": "9.0.0-alpha.321+63953a607",
77
77
  "archiver": "^7.0.1",
78
78
  "aria-query": "^5.3.0",
79
79
  "cheerio": "^1.0.0-rc.12",
@@ -83,6 +83,7 @@
83
83
  "htmlfy": "^0.2.1",
84
84
  "import-meta-resolve": "^4.0.0",
85
85
  "is-plain-obj": "^4.1.0",
86
+ "jszip": "^3.10.1",
86
87
  "lodash.clonedeep": "^4.5.0",
87
88
  "lodash.zip": "^4.2.0",
88
89
  "minimatch": "^9.0.3",
@@ -91,7 +92,7 @@
91
92
  "rgb2hex": "0.2.5",
92
93
  "serialize-error": "^11.0.3",
93
94
  "urlpattern-polyfill": "^10.0.0",
94
- "webdriver": "9.0.0-alpha.114+b1a80c10f"
95
+ "webdriver": "9.0.0-alpha.321+63953a607"
95
96
  },
96
97
  "peerDependencies": {
97
98
  "puppeteer-core": "^22.3.0"
@@ -101,5 +102,5 @@
101
102
  "optional": true
102
103
  }
103
104
  },
104
- "gitHead": "b1a80c10f41091e6ecfd8c5abff14788a8de499b"
105
+ "gitHead": "63953a6079023cb390a113fe5ce1c1b01b8e4bb6"
105
106
  }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cjs/index.ts"],"names":[],"mappings":""}
@@ -1,5 +0,0 @@
1
- {
2
- "name": "webdriverio-cjs",
3
- "type": "commonjs",
4
- "private": true
5
- }