Skip to content

Commit c058c1d

Browse files
committed
Working cases of toHaveWidth and toHaveHTML with $$()
1 parent dd1107e commit c058c1d

13 files changed

Lines changed: 926 additions & 406 deletions

src/matchers/element/toBeSelected.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export async function toBeSelected(
66
received: WdioElementOrArrayMaybePromise,
77
options: ExpectWebdriverIO.CommandOptions = DEFAULT_OPTIONS
88
) {
9+
this.verb = this.verb || 'be'
910
this.expectation = this.expectation || 'selected'
1011
this.matcherName = this.matcherName || 'toBeSelected'
1112

@@ -26,6 +27,7 @@ export async function toBeSelected(
2627
}
2728

2829
export async function toBeChecked (received: WdioElementOrArrayMaybePromise, options: ExpectWebdriverIO.CommandOptions = DEFAULT_OPTIONS) {
30+
this.verb = 'be'
2931
this.expectation = 'checked'
3032
this.matcherName = 'toBeChecked'
3133

src/matchers/element/toHaveHTML.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { DEFAULT_OPTIONS } from '../../constants.js'
44
import {
55
compareText, compareTextWithArray,
66
enhanceError,
7-
executeCommand,
87
waitUntil,
98
wrapExpectedWithArray
109
} from '../../utils.js'
10+
import { executeCommandWithArray } from '../../util/executeCommand.js'
11+
import { map } from '../../util/elementsUtil.js'
1112

1213
async function condition(el: WebdriverIO.Element, html: string | RegExp | WdioAsymmetricMatcher<string> | Array<string | RegExp>, options: ExpectWebdriverIO.HTMLOptions) {
1314
const actualHTML = await el.getHTML(options)
@@ -31,22 +32,22 @@ export async function toHaveHTML(
3132
options,
3233
})
3334

34-
let el = 'getElement' in received
35-
? await received?.getElement()
36-
: 'getElements' in received
37-
? await received?.getElements()
38-
: received
35+
let elements
3936
let actualHTML
4037

4138
const pass = await waitUntil(async () => {
42-
const result = await executeCommand.call(this, el, condition, options, [expectedValue, options])
43-
el = result.el as WebdriverIO.Element
44-
actualHTML = result.values
39+
const result = await executeCommandWithArray.call(this, received, async (element) => await map(element, async (el) => await condition(el, expectedValue, options)) )
40+
elements = result.elementOrElements
41+
actualHTML = result.valueOrValues
4542

4643
return result.success
47-
}, isNot, options)
44+
}, isNot, {
45+
wait: options.wait,
46+
interval: options.interval
47+
})
4848

49-
const message = enhanceError(el, wrapExpectedWithArray(el, actualHTML, expectedValue), actualHTML, this, verb, expectation, '', options)
49+
const expectedValues = wrapExpectedWithArray(elements, actualHTML, expectedValue)
50+
const message = enhanceError(elements, expectedValues, actualHTML, this, verb, expectation, '', options)
5051

5152
const result: ExpectWebdriverIO.AssertionResult = {
5253
pass,

src/matchers/element/toHaveText.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import type { ChainablePromiseElement, ChainablePromiseArray } from 'webdriverio'
21
import { DEFAULT_OPTIONS } from '../../constants.js'
32
import {
43
compareText, compareTextWithArray,
54
enhanceError,
6-
executeCommand,
75
waitUntil,
86
wrapExpectedWithArray
97
} from '../../utils.js'
8+
import { executeCommandWithArray } from '../../util/executeCommand.js'
9+
import { map } from '../../util/elementsUtil.js'
10+
import type { WdioElementOrArrayMaybePromise } from '../../types.js'
1011

1112
async function condition(el: WebdriverIO.Element | WebdriverIO.ElementArray, text: string | RegExp | Array<string | RegExp> | WdioAsymmetricMatcher<string>, options: ExpectWebdriverIO.StringOptions) {
1213
const actualTextArray: string[] = []
@@ -38,7 +39,7 @@ async function condition(el: WebdriverIO.Element | WebdriverIO.ElementArray, tex
3839
}
3940

4041
export async function toHaveText(
41-
received: ChainablePromiseElement | ChainablePromiseArray,
42+
received: WdioElementOrArrayMaybePromise,
4243
expectedValue: string | RegExp | WdioAsymmetricMatcher<string> | Array<string | RegExp>,
4344
options: ExpectWebdriverIO.StringOptions = DEFAULT_OPTIONS
4445
) {
@@ -51,22 +52,22 @@ export async function toHaveText(
5152
options,
5253
})
5354

54-
let el = 'getElement' in received
55-
? await received?.getElement()
56-
: 'getElements' in received
57-
? await received?.getElements()
58-
: received
55+
let elementOrElements
5956
let actualText
6057

6158
const pass = await waitUntil(async () => {
62-
const result = await executeCommand.call(this, el, condition, options, [expectedValue, options])
63-
el = result.el
64-
actualText = result.values
59+
const result = await executeCommandWithArray.call(this, received,
60+
async (element) => await map(element, async (el) => await condition(el, expectedValue, options)) )
61+
elementOrElements = result.elementOrElements
62+
actualText = result.valueOrValues
6563

6664
return result.success
67-
}, isNot, options)
65+
}, isNot, {
66+
wait: options.wait,
67+
interval: options.interval
68+
})
6869

69-
const message = enhanceError(el, wrapExpectedWithArray(el, actualText, expectedValue), actualText, this, verb, expectation, '', options)
70+
const message = enhanceError(elementOrElements, wrapExpectedWithArray(elementOrElements, actualText, expectedValue), actualText, this, verb, expectation, '', options)
7071
const result: ExpectWebdriverIO.AssertionResult = {
7172
pass,
7273
message: (): string => message

src/matchers/element/toHaveWidth.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { DEFAULT_OPTIONS } from '../../constants.js'
2-
import type { WdioElementMaybePromise } from '../../types.js'
2+
import type { WdioElementOrArrayMaybePromise } from '../../types.js'
3+
import { map, wrapExpectedWithArray } from '../../util/elementsUtil.js'
4+
import { executeCommandWithArray } from '../../util/executeCommand.js'
35
import {
46
compareNumbers,
57
enhanceError,
6-
executeCommand,
78
numberError,
89
waitUntil,
910
} from '../../utils.js'
1011

11-
async function condition(el: WebdriverIO.Element, width: number, options: ExpectWebdriverIO.NumberOptions) {
12+
async function condition(el: WebdriverIO.Element, options: ExpectWebdriverIO.NumberOptions) {
1213
const actualWidth = await el.getSize('width')
1314

1415
return {
@@ -18,49 +19,51 @@ async function condition(el: WebdriverIO.Element, width: number, options: Expect
1819
}
1920

2021
export async function toHaveWidth(
21-
received: WdioElementMaybePromise,
22+
received: WdioElementOrArrayMaybePromise,
2223
expectedValue: number | ExpectWebdriverIO.NumberOptions,
2324
options: ExpectWebdriverIO.CommandOptions = DEFAULT_OPTIONS
2425
) {
2526
const isNot = this.isNot
2627
const { expectation = 'width', verb = 'have' } = this
28+
this.matcherName = 'toHaveWidth'
2729

2830
await options.beforeAssertion?.({
29-
matcherName: 'toHaveWidth',
31+
matcherName: this.matcherName,
3032
expectedValue,
3133
options,
3234
})
3335

34-
// type check
36+
// validate expectedValue
3537
let numberOptions: ExpectWebdriverIO.NumberOptions
3638
if (typeof expectedValue === 'number') {
3739
numberOptions = { eq: expectedValue } as ExpectWebdriverIO.NumberOptions
3840
} else if (!expectedValue || (typeof expectedValue.eq !== 'number' && typeof expectedValue.gte !== 'number' && typeof expectedValue.lte !== 'number')) {
39-
throw new Error('Invalid params passed to toHaveHeight.')
41+
throw new Error(`Invalid params passed to ${this.matcherName}.`)
4042
} else {
4143
numberOptions = expectedValue
4244
}
4345

44-
let el = await received?.getElement()
46+
let elements
4547
let actualWidth
4648

4749
const pass = await waitUntil(
4850
async () => {
49-
const result = await executeCommand.call(this, el, condition, numberOptions, [expectedValue, numberOptions])
51+
const result = await executeCommandWithArray.call(this, received, (elements) => map(elements, (el) => condition(el, numberOptions)))
5052

51-
el = result.el as WebdriverIO.Element
52-
actualWidth = result.values
53+
elements = result.elementOrElements
54+
actualWidth = result.valueOrValues
5355

5456
return result.success
5557
},
5658
isNot,
57-
{ ...numberOptions, ...options }
59+
{ wait: options.wait, interval: options.interval }
5860
)
5961

60-
const error = numberError(numberOptions)
62+
const expextedFailureMessage = numberError(numberOptions)
63+
const expectedValues = wrapExpectedWithArray(elements, actualWidth, expextedFailureMessage)
6164
const message = enhanceError(
62-
el,
63-
error,
65+
elements,
66+
expectedValues,
6467
actualWidth,
6568
this,
6669
verb,
@@ -75,7 +78,7 @@ export async function toHaveWidth(
7578
}
7679

7780
await options.afterAssertion?.({
78-
matcherName: 'toHaveWidth',
81+
matcherName: this.matcherName,
7982
expectedValue,
8083
options,
8184
result

src/util/elementsUtil.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { WdioElementOrArrayMaybePromise } from '../types'
1+
import type { WdioElementOrArrayMaybePromise, WdioElements } from '../types'
22

33
/**
44
* if el is an array of elements and actual value is an array
@@ -7,9 +7,9 @@ import type { WdioElementOrArrayMaybePromise } from '../types'
77
* @param actual actual result or results array
88
* @param expected expected result
99
*/
10-
export const wrapExpectedWithArray = (el: WebdriverIO.Element | WebdriverIO.ElementArray, actual: unknown, expected: unknown) => {
11-
if (Array.isArray(el) && el.length > 1 && Array.isArray(actual)) {
12-
expected = [expected]
10+
export const wrapExpectedWithArray = (el: WebdriverIO.Element | WdioElements | undefined, actual: unknown, expected: unknown) => {
11+
if (Array.isArray(el) && Array.isArray(actual) && !Array.isArray(expected)) {
12+
expected = Array(actual.length).fill(expected)
1313
}
1414
return expected
1515
}

src/util/executeCommand.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,18 @@ export async function executeCommand(
3232
* @param options - Optional configuration options
3333
* @param params - Additional parameters
3434
*/
35-
export async function executeCommandWithArray(
35+
export async function executeCommandWithArray<T>(
3636
nonAwaitedElements: WdioElementOrArrayMaybePromise,
37-
condition: (awaitedElements: WdioElements) => Promise<{
38-
results: boolean[];
39-
values?: unknown;
40-
}>,
41-
): Promise<{ elementOrElements: WdioElements | WebdriverIO.Element | undefined; success: boolean; values?: unknown; }> {
37+
condition: (awaitedElements: WdioElements) => Promise<
38+
{ result: boolean; value?: T }[]
39+
>,
40+
): Promise<{ elementOrElements: WdioElements | WebdriverIO.Element | undefined; success: boolean; valueOrValues: T | undefined | Array<T | undefined> }> {
4241
const { elements: awaitedElements, isSingleElement } = await awaitElements(nonAwaitedElements)
43-
const results = awaitedElements ? await condition(awaitedElements) : { results: [], values: undefined }
42+
const results = awaitedElements ? await condition(awaitedElements) : [{ result: false, value: undefined }]
43+
4444
return {
4545
elementOrElements: isSingleElement && awaitedElements?.length === 1 ? awaitedElements[0] : awaitedElements,
46-
success: results.results.every(Boolean),
47-
values: results.values,
46+
success: results.every((res) => res.result === true),
47+
valueOrValues: isSingleElement && results.length === 1 ? results[0].value : results.map(({ value }) => value),
4848
}
4949
}

src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ async function executeCommandBe(
4242
const result = await executeCommandWithArray.call(
4343
this,
4444
nonAwaitedElements,
45-
async (awaitedElements: WdioElements) => ({ results: await map(awaitedElements, async (element) => await command(element)) }),
45+
async (awaitedElements: WdioElements) => (await map(awaitedElements, async (element) => ({ result: await command(element) }))),
4646
)
4747
awaitedElements = result.elementOrElements
4848
return result.success

0 commit comments

Comments
 (0)