expect-webdriverio 4.2.8 → 4.4.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.
@@ -0,0 +1,26 @@
1
+ import { waitUntil, enhanceError, compareText, compareTextWithArray, executeCommand, wrapExpectedWithArray, updateElementsArray, } from '../../utils.js';
2
+ async function condition(el, label, options) {
3
+ const actualLabel = await el.getComputedLabel();
4
+ if (Array.isArray(label)) {
5
+ return compareTextWithArray(actualLabel, label, options);
6
+ }
7
+ return compareText(actualLabel, label, options);
8
+ }
9
+ export async function toHaveComputedLabel(received, label, options = {}) {
10
+ const isNot = this.isNot;
11
+ const { expectation = 'computed label', verb = 'have' } = this;
12
+ let el = await received;
13
+ let actualLabel;
14
+ const pass = await waitUntil(async () => {
15
+ const result = await executeCommand.call(this, el, condition, options, [label, options]);
16
+ el = result.el;
17
+ actualLabel = result.values;
18
+ return result.success;
19
+ }, isNot, options);
20
+ updateElementsArray(pass, received, el);
21
+ const message = enhanceError(el, wrapExpectedWithArray(el, actualLabel, label), actualLabel, this, verb, expectation, '', options);
22
+ return {
23
+ pass,
24
+ message: () => message,
25
+ };
26
+ }
@@ -0,0 +1,7 @@
1
+ import { toHaveComputedLabel } from './toHaveComputedLabel.js';
2
+ export function toHaveComputedLabelContaining(el, label, options = {}) {
3
+ return toHaveComputedLabel.call(this, el, label, {
4
+ ...options,
5
+ containing: true
6
+ });
7
+ }
@@ -0,0 +1,26 @@
1
+ import { waitUntil, enhanceError, compareText, compareTextWithArray, executeCommand, wrapExpectedWithArray, updateElementsArray, } from '../../utils.js';
2
+ async function condition(el, role, options) {
3
+ const actualRole = await el.getComputedRole();
4
+ if (Array.isArray(role)) {
5
+ return compareTextWithArray(actualRole, role, options);
6
+ }
7
+ return compareText(actualRole, role, options);
8
+ }
9
+ export async function toHaveComputedRole(received, role, options = {}) {
10
+ const isNot = this.isNot;
11
+ const { expectation = 'computed role', verb = 'have' } = this;
12
+ let el = await received;
13
+ let actualRole;
14
+ const pass = await waitUntil(async () => {
15
+ const result = await executeCommand.call(this, el, condition, options, [role, options]);
16
+ el = result.el;
17
+ actualRole = result.values;
18
+ return result.success;
19
+ }, isNot, options);
20
+ updateElementsArray(pass, received, el);
21
+ const message = enhanceError(el, wrapExpectedWithArray(el, actualRole, role), actualRole, this, verb, expectation, '', options);
22
+ return {
23
+ pass,
24
+ message: () => message,
25
+ };
26
+ }
@@ -0,0 +1,7 @@
1
+ import { toHaveComputedRole } from './toHaveComputedRole.js';
2
+ export function toHaveComputedRoleContaining(el, role, options = {}) {
3
+ return toHaveComputedRole.call(this, el, role, {
4
+ ...options,
5
+ containing: true
6
+ });
7
+ }
@@ -0,0 +1,26 @@
1
+ import { waitUntil, enhanceError, compareText, compareTextWithArray, executeCommand, wrapExpectedWithArray, updateElementsArray } from '../../utils.js';
2
+ async function condition(el, html, options) {
3
+ const actualHTML = await el.getHTML(options.includeSelectorTag);
4
+ if (Array.isArray(html)) {
5
+ return compareTextWithArray(actualHTML, html, options);
6
+ }
7
+ return compareText(actualHTML, html, options);
8
+ }
9
+ export async function toHaveHTML(received, html, options = {}) {
10
+ const isNot = this.isNot;
11
+ const { expectation = 'HTML', verb = 'have' } = this;
12
+ let el = await received;
13
+ let actualHTML;
14
+ const pass = await waitUntil(async () => {
15
+ const result = await executeCommand.call(this, el, condition, options, [html, options]);
16
+ el = result.el;
17
+ actualHTML = result.values;
18
+ return result.success;
19
+ }, isNot, options);
20
+ updateElementsArray(pass, received, el);
21
+ const message = enhanceError(el, wrapExpectedWithArray(el, actualHTML, html), actualHTML, this, verb, expectation, '', options);
22
+ return {
23
+ pass,
24
+ message: () => message
25
+ };
26
+ }
@@ -0,0 +1,7 @@
1
+ import { toHaveHTML } from './toHaveHTML.js';
2
+ export function toHaveHTMLContaining(el, html, options = {}) {
3
+ return toHaveHTML.call(this, el, html, {
4
+ ...options,
5
+ containing: true
6
+ });
7
+ }
@@ -0,0 +1,26 @@
1
+ import { waitUntil, enhanceError, executeCommand, wrapExpectedWithArray, updateElementsArray, } from '../../utils.js';
2
+ async function condition(el, height) {
3
+ const actualHeight = await el.getSize('height');
4
+ return {
5
+ value: actualHeight,
6
+ result: actualHeight === height,
7
+ };
8
+ }
9
+ export async function toHaveHeight(received, height, options = {}) {
10
+ const isNot = this.isNot;
11
+ const { expectation = 'height', verb = 'have' } = this;
12
+ let el = await received;
13
+ let actualHeight;
14
+ const pass = await waitUntil(async () => {
15
+ const result = await executeCommand.call(this, el, condition, options, [height, options]);
16
+ el = result.el;
17
+ actualHeight = result.values;
18
+ return result.success;
19
+ }, isNot, options);
20
+ updateElementsArray(pass, received, el);
21
+ const message = enhanceError(el, wrapExpectedWithArray(el, actualHeight, height), actualHeight, this, verb, expectation, '', options);
22
+ return {
23
+ pass,
24
+ message: () => message,
25
+ };
26
+ }
@@ -0,0 +1,23 @@
1
+ import { waitUntil, enhanceError, executeCommand, wrapExpectedWithArray, updateElementsArray, compareObject, } from '../../utils.js';
2
+ async function condition(el, size) {
3
+ const actualSize = await el.getSize();
4
+ return compareObject(actualSize, size);
5
+ }
6
+ export async function toHaveSize(received, size, options = {}) {
7
+ const isNot = this.isNot;
8
+ const { expectation = 'size', verb = 'have' } = this;
9
+ let el = await received;
10
+ let actualSize;
11
+ const pass = await waitUntil(async () => {
12
+ const result = await executeCommand.call(this, el, condition, options, [size, options]);
13
+ el = result.el;
14
+ actualSize = result.values;
15
+ return result.success;
16
+ }, isNot, options);
17
+ updateElementsArray(pass, received, el);
18
+ const message = enhanceError(el, wrapExpectedWithArray(el, actualSize, size), actualSize, this, verb, expectation, '', options);
19
+ return {
20
+ pass,
21
+ message: () => message,
22
+ };
23
+ }
@@ -0,0 +1,26 @@
1
+ import { waitUntil, enhanceError, executeCommand, wrapExpectedWithArray, updateElementsArray, } from '../../utils.js';
2
+ async function condition(el, width) {
3
+ const actualWidth = await el.getSize('width');
4
+ return {
5
+ value: actualWidth,
6
+ result: actualWidth === width,
7
+ };
8
+ }
9
+ export async function toHaveWidth(received, width, options = {}) {
10
+ const isNot = this.isNot;
11
+ const { expectation = 'width', verb = 'have' } = this;
12
+ let el = await received;
13
+ let actualWidth;
14
+ const pass = await waitUntil(async () => {
15
+ const result = await executeCommand.call(this, el, condition, options, [width, options]);
16
+ el = result.el;
17
+ actualWidth = result.values;
18
+ return result.success;
19
+ }, isNot, options);
20
+ updateElementsArray(pass, received, el);
21
+ const message = enhanceError(el, wrapExpectedWithArray(el, actualWidth, width), actualWidth, this, verb, expectation, '', options);
22
+ return {
23
+ pass,
24
+ message: () => message,
25
+ };
26
+ }
package/lib/utils.js CHANGED
@@ -1,3 +1,4 @@
1
+ import isEqual from 'lodash.isequal';
1
2
  import { executeCommand } from './util/executeCommand.js';
2
3
  import { wrapExpectedWithArray, updateElementsArray } from './util/elementsUtil.js';
3
4
  import { enhanceError, enhanceErrorBe, numberError } from './util/formatMessage.js';
@@ -67,7 +68,7 @@ const compareNumbers = (actual, options = {}) => {
67
68
  }
68
69
  return false;
69
70
  };
70
- export const compareText = (actual, expected, { ignoreCase = false, trim = true, containing = false }) => {
71
+ export const compareText = (actual, expected, { ignoreCase = false, trim = true, containing = false, atStart = false, atEnd = false, atIndex, replace }) => {
71
72
  if (typeof actual !== 'string') {
72
73
  return {
73
74
  value: actual,
@@ -77,6 +78,9 @@ export const compareText = (actual, expected, { ignoreCase = false, trim = true,
77
78
  if (trim) {
78
79
  actual = actual.trim();
79
80
  }
81
+ if (Array.isArray(replace)) {
82
+ actual = replaceActual(replace, actual);
83
+ }
80
84
  if (ignoreCase) {
81
85
  actual = actual.toLowerCase();
82
86
  if (!(expected instanceof RegExp)) {
@@ -95,12 +99,30 @@ export const compareText = (actual, expected, { ignoreCase = false, trim = true,
95
99
  result: actual.includes(expected)
96
100
  };
97
101
  }
102
+ if (atStart) {
103
+ return {
104
+ value: actual,
105
+ result: actual.startsWith(expected)
106
+ };
107
+ }
108
+ if (atEnd) {
109
+ return {
110
+ value: actual,
111
+ result: actual.endsWith(expected)
112
+ };
113
+ }
114
+ if (atIndex) {
115
+ return {
116
+ value: actual,
117
+ result: actual.substring(atIndex, actual.length).startsWith(expected)
118
+ };
119
+ }
98
120
  return {
99
121
  value: actual,
100
122
  result: actual === expected
101
123
  };
102
124
  };
103
- export const compareTextWithArray = (actual, expectedArray, { ignoreCase = false, trim = false, containing = false }) => {
125
+ export const compareTextWithArray = (actual, expectedArray, { ignoreCase = false, trim = false, containing = false, atStart = false, atEnd = false, atIndex, replace }) => {
104
126
  if (typeof actual !== 'string') {
105
127
  return {
106
128
  value: actual,
@@ -110,18 +132,48 @@ export const compareTextWithArray = (actual, expectedArray, { ignoreCase = false
110
132
  if (trim) {
111
133
  actual = actual.trim();
112
134
  }
135
+ if (Array.isArray(replace)) {
136
+ actual = replaceActual(replace, actual);
137
+ }
113
138
  if (ignoreCase) {
114
139
  actual = actual.toLowerCase();
115
140
  expectedArray = expectedArray.map(item => (item instanceof RegExp) ? item : item.toLowerCase());
116
141
  }
117
142
  const textInArray = expectedArray.some((expected) => {
118
- return expected instanceof RegExp ? !!actual.match(expected) : containing ? actual.includes(expected) : actual === expected;
143
+ if (expected instanceof RegExp) {
144
+ return !!actual.match(expected);
145
+ }
146
+ if (containing) {
147
+ return actual.includes(expected);
148
+ }
149
+ if (atStart) {
150
+ return actual.startsWith(expected);
151
+ }
152
+ if (atEnd) {
153
+ return actual.endsWith(expected);
154
+ }
155
+ if (atIndex) {
156
+ return actual.substring(atIndex, actual.length).startsWith(expected);
157
+ }
158
+ return actual === expected;
119
159
  });
120
160
  return {
121
161
  value: actual,
122
162
  result: textInArray
123
163
  };
124
164
  };
165
+ export const compareObject = (actual, expected) => {
166
+ if (typeof actual !== 'object' || Array.isArray(actual)) {
167
+ return {
168
+ value: actual,
169
+ result: false
170
+ };
171
+ }
172
+ return {
173
+ value: actual,
174
+ result: isEqual(actual, expected)
175
+ };
176
+ };
125
177
  export const compareStyle = async (actualEl, style, { ignoreCase = true, trim = false }) => {
126
178
  let result = true;
127
179
  const actual = {};
@@ -151,3 +203,17 @@ function aliasFn(fn, { verb, expectation } = {}, ...args) {
151
203
  return fn.apply(this, args);
152
204
  }
153
205
  export { updateElementsArray, wrapExpectedWithArray, enhanceError, numberError, executeCommand, executeCommandBe, waitUntil, compareNumbers, aliasFn };
206
+ function replaceActual(replace, actual) {
207
+ const hasMultipleReplacers = replace.every(r => Array.isArray(r));
208
+ const replacers = hasMultipleReplacers
209
+ ? replace
210
+ : [replace];
211
+ if (replacers.some(r => Array.isArray(r) && r.length !== 2)) {
212
+ throw new Error('Replacers need to have a searchValue and a replaceValue');
213
+ }
214
+ for (const replacer of replacers) {
215
+ const [searchValue, replaceValue] = replacer;
216
+ actual = actual.replace(searchValue, replaceValue);
217
+ }
218
+ return actual;
219
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expect-webdriverio",
3
- "version": "4.2.8",
3
+ "version": "4.4.0",
4
4
  "author": "Mykola Grybyk <mykola.grybyk@gmail.com>",
5
5
  "description": "WebdriverIO Assertion Library",
6
6
  "license": "MIT",
@@ -60,6 +60,7 @@
60
60
  "devDependencies": {
61
61
  "@types/debug": "^4.1.8",
62
62
  "@types/jest": "^29.5.4",
63
+ "@types/lodash.isequal": "^4.5.6",
63
64
  "@types/node": "^20.6.0",
64
65
  "@typescript-eslint/eslint-plugin": "^6.7.0",
65
66
  "@typescript-eslint/parser": "^6.7.0",
@@ -75,7 +76,7 @@
75
76
  "rimraf": "^5.0.1",
76
77
  "shelljs": "^0.8.5",
77
78
  "typescript": "^5.2.2",
78
- "vitest": "0.34.4",
79
+ "vitest": "0.34.5",
79
80
  "webdriverio": "^8.16.7"
80
81
  },
81
82
  "optionalDependencies": {
@@ -84,6 +85,7 @@
84
85
  },
85
86
  "dependencies": {
86
87
  "expect": "^29.7.0",
87
- "jest-matcher-utils": "^29.7.0"
88
+ "jest-matcher-utils": "^29.7.0",
89
+ "lodash.isequal": "^4.5.0"
88
90
  }
89
91
  }
@@ -1,330 +1,469 @@
1
- declare namespace ExpectWebdriverIO {
2
- function expect<T = unknown, R extends void | Promise<void> = void | Promise<void>>(actual: T): Matchers<R, T>
3
- function setOptions(options: DefaultOptions): void
4
- function getConfig(): any
5
- const matchers: Record<string, ((actual: any, ...expected: any[]) => Promise<{
6
- pass: boolean;
7
- message(): string;
8
- }>)>
9
-
10
- interface DefaultOptions {
11
- /**
12
- * time in ms to wait for expectation to succeed. Default: 3000
13
- */
14
- wait?: number
15
-
16
- /**
17
- * interval between attempts. Default: 100
18
- */
19
- interval?: number
20
- }
21
-
22
- interface CommandOptions extends DefaultOptions {
23
- /**
24
- * user message to prepend before assertion error
25
- */
26
- message?: string
27
- }
28
-
29
- interface StringOptions extends CommandOptions {
30
- /**
31
- * apply `toLowerCase` to both actual and expected values
32
- */
33
- ignoreCase?: boolean
34
-
35
- /**
36
- * apply `trim` to actual value
37
- */
38
- trim?: boolean
39
-
40
- /**
41
- * expect actual value to contain expected value.
42
- * Otherwise strict equal
43
- */
44
- containing?: boolean
45
-
46
- /**
47
- * might be helpful to force converting property value to string
48
- */
49
- asString?: boolean
50
- }
51
-
52
- interface NumberOptions extends CommandOptions {
53
- /**
54
- * equals
55
- */
56
- eq?: number
57
- /**
58
- * less than or equals
59
- */
60
- lte?: number
61
-
62
- /**
63
- * greater than or equals
64
- */
65
- gte?: number
66
- }
67
-
68
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
69
- interface Matchers<R, T> {
70
- // ===== $ or $$ =====
71
- /**
72
- * `WebdriverIO.Element` -> `isDisplayed`
73
- */
74
- toBeDisplayed(options?: ExpectWebdriverIO.CommandOptions): R
75
-
76
- /**
77
- * `WebdriverIO.Element` -> `isExisting`
78
- */
79
- toExist(options?: ExpectWebdriverIO.CommandOptions): R
80
- /**
81
- * `WebdriverIO.Element` -> `isExisting`
82
- */
83
- toBePresent(options?: ExpectWebdriverIO.CommandOptions): R
84
- /**
85
- * `WebdriverIO.Element` -> `isExisting`
86
- */
87
- toBeExisting(options?: ExpectWebdriverIO.CommandOptions): R
88
-
89
- /**
90
- * `WebdriverIO.Element` -> `getAttribute`
91
- */
92
- toHaveAttribute(attribute: string, value?: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
93
- /**
94
- * `WebdriverIO.Element` -> `getAttribute`
95
- */
96
- toHaveAttr(attribute: string, value?: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
97
-
98
- /**
99
- * `WebdriverIO.Element` -> `getAttribute`
100
- * Element's attribute includes the value.
101
- */
102
- toHaveAttributeContaining(
103
- attribute: string,
104
- contains: string | RegExp,
105
- options?: ExpectWebdriverIO.StringOptions
106
- ): R
107
- /**
108
- * `WebdriverIO.Element` -> `getAttribute`
109
- * Element's attribute includes the value.
110
- */
111
- toHaveAttrContaining(
112
- attribute: string,
113
- contains: string | RegExp,
114
- options?: ExpectWebdriverIO.StringOptions
115
- ): R
116
-
117
- /**
118
- * `WebdriverIO.Element` -> `getAttribute` class
119
- * @deprecated since v1.3.1 - use `toHaveElementClass` instead.
120
- */
121
- toHaveClass(className: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
122
-
123
- /**
124
- * `WebdriverIO.Element` -> `getAttribute` class
125
- */
126
- toHaveElementClass(className: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
127
-
128
- /**
129
- * `WebdriverIO.Element` -> `getAttribute` class
130
- * @deprecated since v1.3.1 - use `toHaveElementClassContaining` instead.
131
- * Element's class includes the className.
132
- */
133
- toHaveClassContaining(className: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
134
-
135
- /**
136
- * `WebdriverIO.Element` -> `getAttribute` class
137
- * Element's class includes the className.
138
- */
139
- toHaveElementClassContaining(className: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
140
-
141
- /**
142
- * `WebdriverIO.Element` -> `getProperty`
143
- */
144
- toHaveElementProperty(property: string | RegExp, value?: any, options?: ExpectWebdriverIO.StringOptions): R
145
-
146
- /**
147
- * `WebdriverIO.Element` -> `getProperty` value
148
- */
149
- toHaveValue(value: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
150
- /**
151
- * `WebdriverIO.Element` -> `getProperty` value
152
- * Element's value includes the value.
153
- */
154
- toHaveValueContaining(value: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
155
-
156
- /**
157
- * `WebdriverIO.Element` -> `isClickable`
158
- */
159
- toBeClickable(options?: ExpectWebdriverIO.StringOptions): R
160
-
161
- /**
162
- * `WebdriverIO.Element` -> `!isEnabled`
163
- */
164
- toBeDisabled(options?: ExpectWebdriverIO.StringOptions): R
165
-
166
- /**
167
- * `WebdriverIO.Element` -> `isDisplayedInViewport`
168
- */
169
- toBeDisplayedInViewport(options?: ExpectWebdriverIO.StringOptions): R
170
-
171
- /**
172
- * `WebdriverIO.Element` -> `isEnabled`
173
- */
174
- toBeEnabled(options?: ExpectWebdriverIO.StringOptions): R
175
-
176
- /**
177
- * `WebdriverIO.Element` -> `isFocused`
178
- */
179
- toBeFocused(options?: ExpectWebdriverIO.StringOptions): R
180
-
181
- /**
182
- * `WebdriverIO.Element` -> `isSelected`
183
- */
184
- toBeSelected(options?: ExpectWebdriverIO.StringOptions): R
185
-
186
- /**
187
- * `WebdriverIO.Element` -> `isSelected`
188
- */
189
- toBeChecked(options?: ExpectWebdriverIO.StringOptions): R
190
-
191
- /**
192
- * `WebdriverIO.Element` -> `$$('./*').length`
193
- * supports less / greater then or equals to be passed in options
194
- */
195
- toHaveChildren(
196
- size?: number | ExpectWebdriverIO.NumberOptions,
197
- options?: ExpectWebdriverIO.NumberOptions
198
- ): R
199
-
200
- /**
201
- * `WebdriverIO.Element` -> `getAttribute` href
202
- */
203
- toHaveHref(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
204
- /**
205
- * `WebdriverIO.Element` -> `getAttribute` href
206
- */
207
- toHaveLink(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
208
-
209
- /**
210
- * `WebdriverIO.Element` -> `getAttribute` href
211
- * Element's href includes the value provided
212
- */
213
- toHaveHrefContaining(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
214
- /**
215
- * `WebdriverIO.Element` -> `getAttribute` href
216
- * Element's href includes the value provided
217
- */
218
- toHaveLinkContaining(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
219
-
220
- /**
221
- * `WebdriverIO.Element` -> `getProperty` value
222
- */
223
- toHaveId(id: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
224
-
225
- /**
226
- * `WebdriverIO.Element` -> `getText`
227
- */
228
- toHaveText(text: string | RegExp | Array<string | RegExp>, options?: ExpectWebdriverIO.StringOptions): R
229
- /**
230
- * `WebdriverIO.Element` -> `getText`
231
- * Element's text includes the text provided
232
- */
233
- toHaveTextContaining(text: string | RegExp | Array<string | RegExp>, options?: ExpectWebdriverIO.StringOptions): R
234
-
235
- /**
236
- * `WebdriverIO.Element` -> `getAttribute("style")`
237
- */
238
- toHaveStyle(style: { [key: string]: string; }, options?: ExpectWebdriverIO.StringOptions): R
239
-
240
- // ===== browser only =====
241
- /**
242
- * `WebdriverIO.Browser` -> `getUrl`
243
- */
244
- toHaveUrl(url: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
245
-
246
- // ===== browser only =====
247
- /**
248
- * `WebdriverIO.Browser` -> `getUrl`
249
- * Browser's url includes the provided text
250
- */
251
- toHaveUrlContaining(url: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
252
-
253
- /**
254
- * `WebdriverIO.Browser` -> `getTitle`
255
- */
256
- toHaveTitle(title: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
257
-
258
- // ===== browser only =====
259
- /**
260
- * `WebdriverIO.Browser` -> `getTitle`
261
- * Browser's title includes the provided text
262
- */
263
- toHaveTitleContaining(title: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
264
-
265
- // ===== $$ only =====
266
- /**
267
- * `WebdriverIO.ElementArray` -> `$$('...').length`
268
- * supports less / greater then or equals to be passed in options
269
- */
270
- toBeElementsArrayOfSize(
271
- size: number | ExpectWebdriverIO.NumberOptions,
272
- options?: ExpectWebdriverIO.NumberOptions
273
- ): R
274
-
275
- // ==== network mock ====
276
-
277
- /**
278
- * Check that `WebdriverIO.Mock` was called
279
- */
280
- toBeRequested(options?: ExpectWebdriverIO.CommandOptions): R
281
-
282
- /**
283
- * Check that `WebdriverIO.Mock` was called N times
284
- */
285
- toBeRequestedTimes(
286
- times: number | ExpectWebdriverIO.NumberOptions,
287
- options?: ExpectWebdriverIO.NumberOptions
288
- ): R
289
-
290
- /**
291
- * Check that `WebdriverIO.Mock` was called with the specific parameters
292
- */
293
- toBeRequestedWith(requestedWith: RequestedWith, options?: ExpectWebdriverIO.CommandOptions): R
294
- }
295
-
296
- type RequestedWith = {
297
- url?: string | ExpectWebdriverIO.PartialMatcher | ((url: string) => boolean)
298
- method?: string | Array<string>
299
- statusCode?: number | Array<number>
300
- requestHeaders?:
301
- | Record<string, string>
302
- | ExpectWebdriverIO.PartialMatcher
303
- | ((headers: Record<string, string>) => boolean)
304
- responseHeaders?:
305
- | Record<string, string>
306
- | ExpectWebdriverIO.PartialMatcher
307
- | ((headers: Record<string, string>) => boolean)
308
- postData?:
309
- | string
310
- | ExpectWebdriverIO.JsonCompatible
311
- | ExpectWebdriverIO.PartialMatcher
312
- | ((r: string | undefined) => boolean)
313
- response?:
314
- | string
315
- | ExpectWebdriverIO.JsonCompatible
316
- | ExpectWebdriverIO.PartialMatcher
317
- | ((r: string) => boolean)
318
- }
319
-
320
- type jsonPrimitive = string | number | boolean | null
321
- type jsonObject = { [x: string]: jsonPrimitive | jsonObject | jsonArray }
322
- type jsonArray = Array<jsonPrimitive | jsonObject | jsonArray>
323
- type JsonCompatible = jsonObject | jsonArray
324
-
325
- interface PartialMatcher {
326
- sample?: any
327
- asymmetricMatch?(...args: any[]): boolean
1
+ type searchValue = string | RegExp
2
+ type replaceValue = string | ((substring: string, ...args: any[]) => string)
3
+ export type Replacer = [searchValue, replaceValue]
4
+
5
+ declare global {
6
+ namespace ExpectWebdriverIO {
7
+ function expect<T = unknown, R extends void | Promise<void> = void | Promise<void>>(
8
+ actual: T
9
+ ): Matchers<R, T>
10
+ function setOptions(options: DefaultOptions): void
11
+ function getConfig(): any
12
+ const matchers: Record<
13
+ string,
14
+ (
15
+ actual: any,
16
+ ...expected: any[]
17
+ ) => Promise<{
18
+ pass: boolean
19
+ message(): string
20
+ }>
21
+ >
22
+
23
+ interface DefaultOptions {
24
+ /**
25
+ * time in ms to wait for expectation to succeed. Default: 3000
26
+ */
27
+ wait?: number
28
+
29
+ /**
30
+ * interval between attempts. Default: 100
31
+ */
32
+ interval?: number
33
+ }
34
+
35
+ interface CommandOptions extends DefaultOptions {
36
+ /**
37
+ * user message to prepend before assertion error
38
+ */
39
+ message?: string
40
+ }
41
+
42
+ interface HTMLOptions extends StringOptions {
43
+ /**
44
+ * return the HTML with the selector tag included
45
+ */
46
+ includeSelectorTag?: boolean
47
+ }
48
+
49
+ interface StringOptions extends CommandOptions {
50
+ /**
51
+ * apply `toLowerCase` to both actual and expected values
52
+ */
53
+ ignoreCase?: boolean
54
+
55
+ /**
56
+ * apply `trim` to actual value
57
+ */
58
+ trim?: boolean
59
+
60
+ /**
61
+ * expect actual value to contain expected value.
62
+ * Otherwise strict equal
63
+ */
64
+ containing?: boolean
65
+
66
+ /**
67
+ * expect actual value to start with the expected value
68
+ * Otherwise strict equal
69
+ */
70
+ atStart?: boolean
71
+
72
+ /**
73
+ * expect actual value to end with the expected value
74
+ * Otherwise strict equal
75
+ */
76
+ atEnd?: boolean
77
+
78
+ /**
79
+ * expect actual value to have the expected value at the given index (index starts at 0 not 1)
80
+ * Otherwise strict equal
81
+ */
82
+ atIndex?: number
83
+
84
+ /**
85
+ * replace the actual value (example: strip newlines from the value) and expect it to match the expected value
86
+ * Otherwise strict equal
87
+ */
88
+ replace?: Replacer | Replacer[]
89
+
90
+ /**
91
+ * might be helpful to force converting property value to string
92
+ */
93
+ asString?: boolean
94
+ }
95
+
96
+ interface NumberOptions extends CommandOptions {
97
+ /**
98
+ * equals
99
+ */
100
+ eq?: number
101
+ /**
102
+ * less than or equals
103
+ */
104
+ lte?: number
105
+
106
+ /**
107
+ * greater than or equals
108
+ */
109
+ gte?: number
110
+ }
111
+
112
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
113
+ interface Matchers<R, T> {
114
+ // ===== $ or $$ =====
115
+ /**
116
+ * `WebdriverIO.Element` -> `isDisplayed`
117
+ */
118
+ toBeDisplayed(options?: ExpectWebdriverIO.CommandOptions): R
119
+
120
+ /**
121
+ * `WebdriverIO.Element` -> `isExisting`
122
+ */
123
+ toExist(options?: ExpectWebdriverIO.CommandOptions): R
124
+ /**
125
+ * `WebdriverIO.Element` -> `isExisting`
126
+ */
127
+ toBePresent(options?: ExpectWebdriverIO.CommandOptions): R
128
+ /**
129
+ * `WebdriverIO.Element` -> `isExisting`
130
+ */
131
+ toBeExisting(options?: ExpectWebdriverIO.CommandOptions): R
132
+
133
+ /**
134
+ * `WebdriverIO.Element` -> `getAttribute`
135
+ */
136
+ toHaveAttribute(
137
+ attribute: string,
138
+ value?: string | RegExp,
139
+ options?: ExpectWebdriverIO.StringOptions
140
+ ): R
141
+ /**
142
+ * `WebdriverIO.Element` -> `getAttribute`
143
+ */
144
+ toHaveAttr(
145
+ attribute: string,
146
+ value?: string | RegExp,
147
+ options?: ExpectWebdriverIO.StringOptions
148
+ ): R
149
+
150
+ /**
151
+ * `WebdriverIO.Element` -> `getAttribute`
152
+ * Element's attribute includes the value.
153
+ */
154
+ toHaveAttributeContaining(
155
+ attribute: string,
156
+ contains: string | RegExp,
157
+ options?: ExpectWebdriverIO.StringOptions
158
+ ): R
159
+ /**
160
+ * `WebdriverIO.Element` -> `getAttribute`
161
+ * Element's attribute includes the value.
162
+ */
163
+ toHaveAttrContaining(
164
+ attribute: string,
165
+ contains: string | RegExp,
166
+ options?: ExpectWebdriverIO.StringOptions
167
+ ): R
168
+
169
+ /**
170
+ * `WebdriverIO.Element` -> `getAttribute` class
171
+ * @deprecated since v1.3.1 - use `toHaveElementClass` instead.
172
+ */
173
+ toHaveClass(className: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
174
+
175
+ /**
176
+ * `WebdriverIO.Element` -> `getAttribute` class
177
+ */
178
+ toHaveElementClass(className: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
179
+
180
+ /**
181
+ * `WebdriverIO.Element` -> `getAttribute` class
182
+ * @deprecated since v1.3.1 - use `toHaveElementClassContaining` instead.
183
+ * Element's class includes the className.
184
+ */
185
+ toHaveClassContaining(className: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
186
+
187
+ /**
188
+ * `WebdriverIO.Element` -> `getAttribute` class
189
+ * Element's class includes the className.
190
+ */
191
+ toHaveElementClassContaining(
192
+ className: string | RegExp,
193
+ options?: ExpectWebdriverIO.StringOptions
194
+ ): R
195
+
196
+ /**
197
+ * `WebdriverIO.Element` -> `getProperty`
198
+ */
199
+ toHaveElementProperty(
200
+ property: string | RegExp,
201
+ value?: any,
202
+ options?: ExpectWebdriverIO.StringOptions
203
+ ): R
204
+
205
+ /**
206
+ * `WebdriverIO.Element` -> `getProperty` value
207
+ */
208
+ toHaveValue(value: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
209
+ /**
210
+ * `WebdriverIO.Element` -> `getProperty` value
211
+ * Element's value includes the value.
212
+ */
213
+ toHaveValueContaining(value: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
214
+
215
+ /**
216
+ * `WebdriverIO.Element` -> `isClickable`
217
+ */
218
+ toBeClickable(options?: ExpectWebdriverIO.StringOptions): R
219
+
220
+ /**
221
+ * `WebdriverIO.Element` -> `!isEnabled`
222
+ */
223
+ toBeDisabled(options?: ExpectWebdriverIO.StringOptions): R
224
+
225
+ /**
226
+ * `WebdriverIO.Element` -> `isDisplayedInViewport`
227
+ */
228
+ toBeDisplayedInViewport(options?: ExpectWebdriverIO.StringOptions): R
229
+
230
+ /**
231
+ * `WebdriverIO.Element` -> `isEnabled`
232
+ */
233
+ toBeEnabled(options?: ExpectWebdriverIO.StringOptions): R
234
+
235
+ /**
236
+ * `WebdriverIO.Element` -> `isFocused`
237
+ */
238
+ toBeFocused(options?: ExpectWebdriverIO.StringOptions): R
239
+
240
+ /**
241
+ * `WebdriverIO.Element` -> `isSelected`
242
+ */
243
+ toBeSelected(options?: ExpectWebdriverIO.StringOptions): R
244
+
245
+ /**
246
+ * `WebdriverIO.Element` -> `isSelected`
247
+ */
248
+ toBeChecked(options?: ExpectWebdriverIO.StringOptions): R
249
+
250
+ /**
251
+ * `WebdriverIO.Element` -> `$$('./*').length`
252
+ * supports less / greater then or equals to be passed in options
253
+ */
254
+ toHaveChildren(
255
+ size?: number | ExpectWebdriverIO.NumberOptions,
256
+ options?: ExpectWebdriverIO.NumberOptions
257
+ ): R
258
+
259
+ /**
260
+ * `WebdriverIO.Element` -> `getAttribute` href
261
+ */
262
+ toHaveHref(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
263
+ /**
264
+ * `WebdriverIO.Element` -> `getAttribute` href
265
+ */
266
+ toHaveLink(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
267
+
268
+ /**
269
+ * `WebdriverIO.Element` -> `getAttribute` href
270
+ * Element's href includes the value provided
271
+ */
272
+ toHaveHrefContaining(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
273
+ /**
274
+ * `WebdriverIO.Element` -> `getAttribute` href
275
+ * Element's href includes the value provided
276
+ */
277
+ toHaveLinkContaining(href: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
278
+
279
+ /**
280
+ * `WebdriverIO.Element` -> `getProperty` value
281
+ */
282
+ toHaveId(id: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
283
+
284
+ /**
285
+ * `WebdriverIO.Element` -> `getText`
286
+ * Element's text equals the text provided
287
+ */
288
+ toHaveText(
289
+ text: string | RegExp | Array<string | RegExp>,
290
+ options?: ExpectWebdriverIO.StringOptions
291
+ ): R
292
+ /**
293
+ * `WebdriverIO.Element` -> `getText`
294
+ * Element's text includes the text provided
295
+ */
296
+ toHaveTextContaining(
297
+ text: string | RegExp | Array<string | RegExp>,
298
+ options?: ExpectWebdriverIO.StringOptions
299
+ ): R
300
+
301
+ /**
302
+ * `WebdriverIO.Element` -> `getHTML`
303
+ * Element's html equals the html provided
304
+ */
305
+ toHaveHTML(
306
+ html: string | RegExp | Array<string | RegExp>,
307
+ options?: ExpectWebdriverIO.HTMLOptions
308
+ ): R
309
+ /**
310
+ * `WebdriverIO.Element` -> `getHTML`
311
+ * Element's html includes the html provided
312
+ */
313
+ toHaveHTMLContaining(
314
+ html: string | RegExp | Array<string | RegExp>,
315
+ options?: ExpectWebdriverIO.HTMLOptions
316
+ ): R
317
+
318
+ /**
319
+ * `WebdriverIO.Element` -> `getComputedLabel`
320
+ * Element's computed label equals the computed label provided
321
+ */
322
+ toHaveComputedLabel(
323
+ computedLabel: string | RegExp | Array<string | RegExp>,
324
+ options?: ExpectWebdriverIO.StringOptions
325
+ ): R
326
+ /**
327
+ * `WebdriverIO.Element` -> `getComputedLabel`
328
+ * Element's computed label includes the computed label provided
329
+ */
330
+ toHaveComputedLabelContaining(
331
+ computedLabel: string | RegExp | Array<string | RegExp>,
332
+ options?: ExpectWebdriverIO.StringOptions
333
+ ): R
334
+
335
+ /**
336
+ * `WebdriverIO.Element` -> `getComputedRole`
337
+ * Element's computed role equals the computed role provided
338
+ */
339
+ toHaveComputedRole(
340
+ computedRole: string | RegExp | Array<string | RegExp>,
341
+ options?: ExpectWebdriverIO.StringOptions
342
+ ): R
343
+ /**
344
+ * `WebdriverIO.Element` -> `getComputedRole`
345
+ * Element's computed role includes the computed role provided
346
+ */
347
+ toHaveComputedRoleContaining(
348
+ computedRole: string | RegExp | Array<string | RegExp>,
349
+ options?: ExpectWebdriverIO.StringOptions
350
+ ): R
351
+
352
+ /**
353
+ * `WebdriverIO.Element` -> `getSize('width')`
354
+ * Element's width equals the width provided
355
+ */
356
+ toHaveWidth(width: number, options?: ExpectWebdriverIO.CommandOptions): R
357
+
358
+ /**
359
+ * `WebdriverIO.Element` -> `getSize('height')`
360
+ * Element's height equals the height provided
361
+ */
362
+ toHaveHeight(height: number, options?: ExpectWebdriverIO.CommandOptions): R
363
+
364
+ /**
365
+ * `WebdriverIO.Element` -> `getSize()`
366
+ * Element's size equals the size provided
367
+ */
368
+ toHaveHeight(
369
+ size: { height: number; width: number },
370
+ options?: ExpectWebdriverIO.CommandOptions
371
+ ): R
372
+
373
+ /**
374
+ * `WebdriverIO.Element` -> `getAttribute("style")`
375
+ */
376
+ toHaveStyle(style: { [key: string]: string }, options?: ExpectWebdriverIO.StringOptions): R
377
+
378
+ // ===== browser only =====
379
+ /**
380
+ * `WebdriverIO.Browser` -> `getUrl`
381
+ */
382
+ toHaveUrl(url: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
383
+
384
+ // ===== browser only =====
385
+ /**
386
+ * `WebdriverIO.Browser` -> `getUrl`
387
+ * Browser's url includes the provided text
388
+ */
389
+ toHaveUrlContaining(url: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
390
+
391
+ /**
392
+ * `WebdriverIO.Browser` -> `getTitle`
393
+ */
394
+ toHaveTitle(title: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
395
+
396
+ // ===== browser only =====
397
+ /**
398
+ * `WebdriverIO.Browser` -> `getTitle`
399
+ * Browser's title includes the provided text
400
+ */
401
+ toHaveTitleContaining(title: string | RegExp, options?: ExpectWebdriverIO.StringOptions): R
402
+
403
+ // ===== $$ only =====
404
+ /**
405
+ * `WebdriverIO.ElementArray` -> `$$('...').length`
406
+ * supports less / greater then or equals to be passed in options
407
+ */
408
+ toBeElementsArrayOfSize(
409
+ size: number | ExpectWebdriverIO.NumberOptions,
410
+ options?: ExpectWebdriverIO.NumberOptions
411
+ ): R
412
+
413
+ // ==== network mock ====
414
+
415
+ /**
416
+ * Check that `WebdriverIO.Mock` was called
417
+ */
418
+ toBeRequested(options?: ExpectWebdriverIO.CommandOptions): R
419
+
420
+ /**
421
+ * Check that `WebdriverIO.Mock` was called N times
422
+ */
423
+ toBeRequestedTimes(
424
+ times: number | ExpectWebdriverIO.NumberOptions,
425
+ options?: ExpectWebdriverIO.NumberOptions
426
+ ): R
427
+
428
+ /**
429
+ * Check that `WebdriverIO.Mock` was called with the specific parameters
430
+ */
431
+ toBeRequestedWith(requestedWith: RequestedWith, options?: ExpectWebdriverIO.CommandOptions): R
432
+ }
433
+
434
+ type RequestedWith = {
435
+ url?: string | ExpectWebdriverIO.PartialMatcher | ((url: string) => boolean)
436
+ method?: string | Array<string>
437
+ statusCode?: number | Array<number>
438
+ requestHeaders?:
439
+ | Record<string, string>
440
+ | ExpectWebdriverIO.PartialMatcher
441
+ | ((headers: Record<string, string>) => boolean)
442
+ responseHeaders?:
443
+ | Record<string, string>
444
+ | ExpectWebdriverIO.PartialMatcher
445
+ | ((headers: Record<string, string>) => boolean)
446
+ postData?:
447
+ | string
448
+ | ExpectWebdriverIO.JsonCompatible
449
+ | ExpectWebdriverIO.PartialMatcher
450
+ | ((r: string | undefined) => boolean)
451
+ response?:
452
+ | string
453
+ | ExpectWebdriverIO.JsonCompatible
454
+ | ExpectWebdriverIO.PartialMatcher
455
+ | ((r: string) => boolean)
456
+ }
457
+
458
+ type jsonPrimitive = string | number | boolean | null
459
+ type jsonObject = { [x: string]: jsonPrimitive | jsonObject | jsonArray }
460
+ type jsonArray = Array<jsonPrimitive | jsonObject | jsonArray>
461
+ type JsonCompatible = jsonObject | jsonArray
462
+
463
+ interface PartialMatcher {
464
+ sample?: any
465
+ asymmetricMatch?(...args: any[]): boolean
466
+ }
328
467
  }
329
468
  }
330
469