Skip to content

Commit 4bac55e

Browse files
committed
fix failure msg with enhanceErrorBe + code refactoring simplification
- Fix double negation in `Expected` with `isNot` when using `enhanceErrorBe` - Fix incorrect Received value with `isNot` when using `enhanceErrorBe` - Code refactoring simplify to better understand the code
1 parent a236cba commit 4bac55e

14 files changed

+306
-204
lines changed

src/util/formatMessage.ts

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ import { equals } from '../jasmineUtils.js'
33
import type { WdioElements } from '../types.js'
44
import { isElementArray } from './elementsUtil.js'
55

6-
const EXPECTED_LABEL = 'Expected'
7-
const RECEIVED_LABEL = 'Received'
8-
const NOT_SUFFIX = ' [not]'
9-
const NOT_EXPECTED_LABEL = EXPECTED_LABEL + NOT_SUFFIX
10-
116
export const getSelector = (el: WebdriverIO.Element | WebdriverIO.ElementArray) => {
127
let result = typeof el.selector === 'string' ? el.selector : '<fn>'
138
if (Array.isArray(el) && (el as WebdriverIO.ElementArray).props.length > 0) {
@@ -39,22 +34,20 @@ export const getSelectors = (el: WebdriverIO.Element | WdioElements) => {
3934
return selectors.reverse().join('.')
4035
}
4136

42-
export const not = (isNot: boolean): string => {
43-
return `${isNot ? 'not ' : ''}`
44-
}
37+
const not = (isNot: boolean): string => `${isNot ? 'not ' : ''}`
4538

4639
export const enhanceError = (
4740
subject: string | WebdriverIO.Element | WdioElements,
4841
expected: unknown,
4942
actual: unknown,
50-
context: { isNot: boolean },
43+
context: { isNot: boolean, useNotInLabel?: boolean },
5144
verb: string,
5245
expectation: string,
53-
arg2 = '', {
46+
expectedValueArgument2 = '', {
5447
message = '',
5548
containing = false
56-
}): string => {
57-
const { isNot = false } = context
49+
} = {}): string => {
50+
const { isNot = false, useNotInLabel = true } = context
5851

5952
subject = typeof subject === 'string' ? subject : getSelectors(subject)
6053

@@ -67,37 +60,43 @@ export const enhanceError = (
6760
verb += ' '
6861
}
6962

70-
let diffString = isNot && equals(actual, expected)
71-
? `${EXPECTED_LABEL}: ${printExpected(expected)}\n${RECEIVED_LABEL}: ${printReceived(actual)}`
72-
: printDiffOrStringify(expected, actual, EXPECTED_LABEL, RECEIVED_LABEL, true)
73-
74-
if (isNot) {
75-
diffString = diffString
76-
.replace(EXPECTED_LABEL, NOT_EXPECTED_LABEL)
77-
.replace(RECEIVED_LABEL, RECEIVED_LABEL + ' '.repeat(NOT_SUFFIX.length))
63+
const label = {
64+
expected: isNot && useNotInLabel ? 'Expected [not]' : 'Expected',
65+
received: isNot && useNotInLabel ? 'Received ' : 'Received'
7866
}
7967

68+
// Using `printDiffOrStringify()` with equals values output `Received: serializes to the same string`, so we need to tweak.
69+
const diffString = equals(actual, expected) ?`\
70+
${label.expected}: ${printExpected(expected)}
71+
${label.received}: ${printReceived(actual)}`
72+
: printDiffOrStringify(expected, actual, label.expected, label.received, true)
73+
8074
if (message) {
8175
message += '\n'
8276
}
8377

84-
if (arg2) {
85-
arg2 = ` ${arg2}`
78+
if (expectedValueArgument2) {
79+
expectedValueArgument2 = ` ${expectedValueArgument2}`
8680
}
8781

88-
const msg = `${message}Expect ${subject} ${not(isNot)}to ${verb}${expectation}${arg2}${contain}\n\n${diffString}`
82+
const msg = `\
83+
${message}Expect ${subject} ${not(isNot)}to ${verb}${expectation}${expectedValueArgument2}${contain}
84+
85+
${diffString}`
86+
8987
return msg
9088
}
9189

9290
export const enhanceErrorBe = (
9391
subject: string | WebdriverIO.Element | WebdriverIO.ElementArray,
94-
pass: boolean,
95-
context: { isNot: boolean },
96-
verb: string,
97-
expectation: string,
92+
context: { isNot: boolean, verb: string, expectation: string },
9893
options: ExpectWebdriverIO.CommandOptions
9994
) => {
100-
return enhanceError(subject, not(context.isNot) + expectation, not(!pass) + expectation, context, verb, expectation, '', options)
95+
const { isNot, verb, expectation } = context
96+
const expected = `${not(isNot)}${expectation}`
97+
const actual = `${not(!isNot)}${expectation}`
98+
99+
return enhanceError(subject, expected, actual, { ...context, useNotInLabel: false }, verb, expectation, '', options)
101100
}
102101

103102
export const numberError = (options: ExpectWebdriverIO.NumberOptions = {}): string | number => {

src/utils.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ async function executeCommandBe(
7272
command: (el: WebdriverIO.Element) => Promise<boolean>,
7373
options: ExpectWebdriverIO.CommandOptions
7474
): ExpectWebdriverIO.AsyncAssertionResult {
75-
const { expectation, verb = 'be' } = this
76-
7775
let el = await received?.getElement()
7876
const pass = await waitUntil(
7977
async () => {
@@ -89,7 +87,8 @@ async function executeCommandBe(
8987
options
9088
)
9189

92-
const message = enhanceErrorBe(el, pass, this, verb, expectation, options)
90+
const { verb = 'be' } = this
91+
const message = enhanceErrorBe(el, { ...this, verb }, options)
9392

9493
return {
9594
pass,

test/__fixtures__/utils.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
export function matcherNameToString(matcherName: string) {
2-
return matcherName.replace(/([A-Z])/g, ' $1').toLowerCase()
3-
}
4-
5-
export function matcherLastWordName(matcherName: string) {
1+
export function matcherNameLastWords(matcherName: string) {
62
return matcherName.replace(/^toHave/, '').replace(/^toBe/, '')
73
.replace(/([A-Z])/g, ' $1').trim().toLowerCase()
84
}
@@ -22,9 +18,3 @@ export function getReceived(msg: string) {
2218
function getReceivedOrExpected(msg: string, type: string) {
2319
return msg.split('\n').find((line, idx) => idx > 1 && line.startsWith(type))
2420
}
25-
26-
export function removeColors(msg: string) {
27-
// eslint-disable-next-line no-control-regex
28-
const s = msg.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')
29-
return s
30-
}

test/matchers.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,43 +111,43 @@ describe('Custom Wdio Matchers Integration Tests', async () => {
111111
await expect(() => expectLib(el).not.toBeDisplayed({ wait: 1 })).rejects.toThrow(`\
112112
Expect $(\`selector\`) not to be displayed
113113
114-
Expected [not]: "not displayed"
115-
Received : "displayed"`
114+
Expected: "not displayed"
115+
Received: "displayed"`
116116
)
117117

118118
await expect(() => expectLib(el).not.toBeExisting({ wait: 1 })).rejects.toThrow(`\
119119
Expect $(\`selector\`) not to be existing
120120
121-
Expected [not]: "not existing"
122-
Received : "existing"`
121+
Expected: "not existing"
122+
Received: "existing"`
123123
)
124124

125125
await expect(() => expectLib(el).not.toBeEnabled({ wait: 1 })).rejects.toThrow(`\
126126
Expect $(\`selector\`) not to be enabled
127127
128-
Expected [not]: "not enabled"
129-
Received : "enabled"`
128+
Expected: "not enabled"
129+
Received: "enabled"`
130130
)
131131

132132
await expect(() => expectLib(el).not.toBeClickable({ wait: 1 })).rejects.toThrow(`\
133133
Expect $(\`selector\`) not to be clickable
134134
135-
Expected [not]: "not clickable"
136-
Received : "clickable"`
135+
Expected: "not clickable"
136+
Received: "clickable"`
137137
)
138138

139139
await expect(() => expectLib(el).not.toBeFocused({ wait: 1 })).rejects.toThrow(`\
140140
Expect $(\`selector\`) not to be focused
141141
142-
Expected [not]: "not focused"
143-
Received : "focused"`
142+
Expected: "not focused"
143+
Received: "focused"`
144144
)
145145

146146
await expect(() => expectLib(el).not.toBeSelected({ wait: 1 })).rejects.toThrow(`\
147147
Expect $(\`selector\`) not to be selected
148148
149-
Expected [not]: "not selected"
150-
Received : "selected"`
149+
Expected: "not selected"
150+
Received: "selected"`
151151
)
152152
})
153153

@@ -423,8 +423,8 @@ Received: 100`)
423423
await expect(() => expectLib(el).not.toBeDisplayed({ wait: 300, interval: 100 })).rejects.toThrow(`\
424424
Expect $(\`selector\`) not to be displayed
425425
426-
Expected [not]: "not displayed"
427-
Received : "displayed"`)
426+
Expected: "not displayed"
427+
Received: "displayed"`)
428428

429429
expect(el.isDisplayed).toHaveBeenCalledTimes(6)
430430
})

test/matchers/beMatchers.test.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { vi, test, describe, expect } from 'vitest'
22
import { $ } from '@wdio/globals'
3-
import { matcherLastWordName } from '../__fixtures__/utils.js'
3+
import { matcherNameLastWords } from '../__fixtures__/utils.js'
44
import * as Matchers from '../../src/matchers.js'
55

66
vi.mock('@wdio/globals')
@@ -78,6 +78,7 @@ describe('be* matchers', () => {
7878
el[elementFnName] = vi.fn().mockResolvedValue(true)
7979

8080
const result = await matcherFn.call({}, el, { wait: 0 }) as ExpectWebdriverIO.AssertionResult
81+
8182
expect(result.pass).toBe(true)
8283
expect(el[elementFnName]).toHaveBeenCalledTimes(1)
8384
})
@@ -89,10 +90,10 @@ describe('be* matchers', () => {
8990

9091
expect(result.pass).toBe(true) // failure, boolean is inverted later because of `.not`
9192
expect(result.message()).toEqual(`\
92-
Expect $(\`sel\`) not to be ${matcherLastWordName(matcherName)}
93+
Expect $(\`sel\`) not to be ${matcherNameLastWords(matcherName)}
9394
94-
Expected [not]: "not ${matcherLastWordName(matcherName)}"
95-
Received : "${matcherLastWordName(matcherName)}"`
95+
Expected: "not ${matcherNameLastWords(matcherName)}"
96+
Received: "${matcherNameLastWords(matcherName)}"`
9697
)
9798
})
9899

@@ -129,10 +130,10 @@ Received : "${matcherLastWordName(matcherName)}"`
129130
const result = await matcherFn.call({}, el, { wait: 1 }) as ExpectWebdriverIO.AssertionResult
130131
expect(result.pass).toBe(false)
131132
expect(result.message()).toBe(`\
132-
Expect $(\`sel\`) to be ${matcherLastWordName(matcherName)}
133+
Expect $(\`sel\`) to be ${matcherNameLastWords(matcherName)}
133134
134-
Expected: "${matcherLastWordName(matcherName)}"
135-
Received: "not ${matcherLastWordName(matcherName)}"`
135+
Expected: "${matcherNameLastWords(matcherName)}"
136+
Received: "not ${matcherNameLastWords(matcherName)}"`
136137
)
137138
})
138139
})

test/matchers/browserMatchers.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { vi, test, describe, expect } from 'vitest'
22
import { browser } from '@wdio/globals'
33

4-
import { getExpectMessage, matcherNameToString, matcherLastWordName } from '../__fixtures__/utils.js'
4+
import { matcherNameLastWords } from '../__fixtures__/utils.js'
55
import * as Matchers from '../../src/matchers.js'
66

77
vi.mock('@wdio/globals')
@@ -67,7 +67,7 @@ describe('browser matchers', () => {
6767

6868
expect(result.pass).toBe(true) // failure, boolean is inverted later because of `.not`
6969
expect(result.message()).toEqual(`\
70-
Expect window not to have ${matcherLastWordName(matcherName)}
70+
Expect window not to have ${matcherNameLastWords(matcherName)}
7171
7272
Expected [not]: " Valid Text "
7373
Received : " Valid Text "`
@@ -89,7 +89,7 @@ Received : " Valid Text "`
8989

9090
expect(result.pass).toBe(true) // failure, boolean is inverted later because of `.not`
9191
expect(result.message()).toEqual(`\
92-
Expect window not to have ${matcherLastWordName(matcherName)}
92+
Expect window not to have ${matcherNameLastWords(matcherName)}
9393
9494
Expected [not]: " Valid Text "
9595
Received : " Valid Text "`
@@ -106,7 +106,13 @@ Received : " Valid Text "`
106106

107107
test('message', async () => {
108108
const result = await matcherFn.call({}, browser) as ExpectWebdriverIO.AssertionResult
109-
expect(getExpectMessage(result.message())).toContain(matcherNameToString(matcherName))
109+
110+
expect(result.pass).toBe(false)
111+
expect(result.message()).toEqual(`\
112+
Expect window to have ${matcherNameLastWords(matcherName)}
113+
114+
Expected: undefined
115+
Received: " Wrong Text "`)
110116
})
111117
})
112118
})

test/matchers/element/toBeDisabled.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ describe('toBeDisabled', () => {
7878
expect(result.message()).toEqual(`\
7979
Expect $(\`sel\`) not to be disabled
8080
81-
Expected [not]: "not disabled"
82-
Received : "disabled"`
81+
Expected: "not disabled"
82+
Received: "disabled"`
8383
)
8484
})
8585

@@ -102,8 +102,8 @@ Received : "disabled"`
102102
expect(result.message()).toEqual(`\
103103
Expect $(\`sel\`) not to be disabled
104104
105-
Expected [not]: "not disabled"
106-
Received : "disabled"`
105+
Expected: "not disabled"
106+
Received: "disabled"`
107107
)
108108
})
109109

test/matchers/element/toBeDisplayed.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ describe('toBeDisplayed', () => {
147147
expect(result.message()).toEqual(`\
148148
Expect $(\`sel\`) not to be displayed
149149
150-
Expected [not]: "not displayed"
151-
Received : "displayed"`
150+
Expected: "not displayed"
151+
Received: "displayed"`
152152
)
153153
})
154154

test/matchers/element/toHaveComputedLabel.test.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { vi, test, describe, expect, beforeEach } from 'vitest'
22
import { $ } from '@wdio/globals'
33

4-
import { getExpectMessage, getReceived, getExpected } from '../../__fixtures__/utils.js'
4+
import { getExpectMessage } from '../../__fixtures__/utils.js'
55
import { toHaveComputedLabel } from '../../../src/matchers/element/toHaveComputedLabel.js'
66

77
vi.mock('@wdio/globals')
@@ -271,18 +271,25 @@ Received : "WebdriverIO"`
271271

272272
test('failure if no match', async () => {
273273
const result = await toHaveComputedLabel.call({}, el, /Webdriver/i)
274+
274275
expect(result.pass).toBe(false)
275-
expect(getExpectMessage(result.message())).toContain('to have computed label')
276-
expect(getExpected(result.message())).toContain('/Webdriver/i')
277-
expect(getReceived(result.message())).toContain('This is example computed label')
276+
expect(result.message()).toEqual(`\
277+
Expect $(\`sel\`) to have computed label
278+
279+
Expected: /Webdriver/i
280+
Received: "This is example computed label"`)
278281
})
279282

280283
test('failure if array does not match with computed label', async () => {
281284
const result = await toHaveComputedLabel.call({}, el, ['div', /Webdriver/i])
285+
282286
expect(result.pass).toBe(false)
283-
expect(getExpectMessage(result.message())).toContain('to have computed label')
284-
expect(getExpected(result.message())).toContain('/Webdriver/i')
285-
expect(getExpected(result.message())).toContain('div')
287+
expect(result.message()).toEqual(`\
288+
Expect $(\`sel\`) to have computed label
289+
290+
Expected: ["div", /Webdriver/i]
291+
Received: "This is example computed label"`
292+
)
286293
})
287294
})
288295
})

test/matchers/element/toHaveHeight.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { vi, test, describe, expect } from 'vitest'
22
import { $ } from '@wdio/globals'
3-
4-
import { getExpectMessage } from '../../__fixtures__/utils.js'
53
import { toHaveHeight } from '../../../src/matchers/element/toHaveHeight.js'
64

75
vi.mock('@wdio/globals')
@@ -48,7 +46,6 @@ describe('toHaveHeight', () => {
4846

4947
const result = await toHaveHeight.call({}, el, 32, {})
5048

51-
expect(result.message()).toEqual('Expect $(`sel`) to have height\n\nExpected: 32\nReceived: serializes to the same string')
5249
expect(result.pass).toBe(true)
5350
expect(el.getSize).toHaveBeenCalledTimes(1)
5451
})
@@ -130,6 +127,10 @@ Received : 32`
130127

131128
const result = await toHaveHeight.call({}, el, 50)
132129

133-
expect(getExpectMessage(result.message())).toContain('to have height')
130+
expect(result.message()).toEqual(`\
131+
Expect $(\`sel\`) to have height
132+
133+
Expected: 50
134+
Received: null`)
134135
})
135136
})

0 commit comments

Comments
 (0)