Skip to content

Commit 82f527a

Browse files
Merge branch 'main' into fix-enhanceErrorBe-ambigious-isNot-failure-message
2 parents 4bac55e + f150a63 commit 82f527a

27 files changed

+300
-94
lines changed

.github/workflows/update.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
# Don't merge updates to GitHub Actions versions automatically.
2828
# (Some repos may wish to limit by version range (major/minor/patch), or scope (dep vs dev-dep), too.)
2929
if: contains(steps.metadata.outputs.package-ecosystem, 'npm')
30-
uses: lewagon/wait-on-check-action@v1.4.1
30+
uses: lewagon/wait-on-check-action@v1.5.0
3131
with:
3232
ref: ${{ github.event.pull_request.head.sha }}
3333
repo-token: ${{ secrets.GITHUB_TOKEN }}

docs/API.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,29 @@ await expect(elem).toHaveElementClass(/Container/i)
880880

881881
In addition to the `expect-webdriverio` matchers you can use builtin Jest's [expect](https://jestjs.io/docs/expect) assertions or [expect/expectAsync](https://jasmine.github.io/api/edge/global.html#expect) for Jasmine.
882882

883+
## Modifiers
884+
885+
WebdriverIO supports usage of modifiers as `.not` and it will wait until the reverse condition is meet
886+
887+
```ts
888+
// Wait until the element is no longer present
889+
await expect(element).not.toBeDisplayed()
890+
891+
// Wait until the text is no more 'some title'
892+
await expect(browser).not.toHaveTitle('some title')
893+
```
894+
895+
In case immediate assertion is required, use `{ wait: 0 }`
896+
```ts
897+
// Ensure element is not present right now
898+
await expect(element).not.toBeDisplayed({ wait: 0 })
899+
900+
// Ensure the text is not 'some title' right now
901+
await expect(browser).not.toHaveTitle('some title', { wait: 0 })
902+
```
903+
904+
Note: You can pair `.not` with asymmetric matchers, but to enable the wait-until behavior, `.not` must be used directly on the `expect()` call.
905+
883906
## Asymmetric Matchers
884907

885908
WebdriverIO supports usage of asymmetric matchers wherever you compare text values, e.g.:

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "expect-webdriverio",
3-
"version": "5.6.3",
3+
"version": "5.6.4",
44
"author": "Mykola Grybyk <[email protected]>",
55
"description": "WebdriverIO Assertion Library",
66
"license": "MIT",

src/matchers/browser/toHaveClipboardText.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export async function toHaveClipboardText(
1010
expectedValue: string | RegExp | WdioAsymmetricMatcher<string>,
1111
options: ExpectWebdriverIO.StringOptions = DEFAULT_OPTIONS
1212
) {
13+
const isNot = this.isNot
1314
const { expectation = 'clipboard text', verb = 'have' } = this
1415

1516
await options.beforeAssertion?.({
@@ -27,7 +28,7 @@ export async function toHaveClipboardText(
2728
.catch((err) => log.warn(`Couldn't set clipboard permissions: ${err}`))
2829
actual = await browser.execute(() => window.navigator.clipboard.readText())
2930
return compareText(actual, expectedValue, options).result
30-
}, options)
31+
}, isNot, options)
3132

3233
const message = enhanceError('browser', expectedValue, actual, this, verb, expectation, '', options)
3334
const result: ExpectWebdriverIO.AssertionResult = {

src/matchers/browser/toHaveTitle.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export async function toHaveTitle(
66
expectedValue: string | RegExp | WdioAsymmetricMatcher<string>,
77
options: ExpectWebdriverIO.StringOptions = DEFAULT_OPTIONS
88
) {
9+
const isNot = this.isNot
910
const { expectation = 'title', verb = 'have' } = this
1011

1112
await options.beforeAssertion?.({
@@ -19,7 +20,7 @@ export async function toHaveTitle(
1920
actual = await browser.getTitle()
2021

2122
return compareText(actual, expectedValue, options).result
22-
}, options)
23+
}, isNot, options)
2324

2425
const message = enhanceError('window', expectedValue, actual, this, verb, expectation, '', options)
2526
const result: ExpectWebdriverIO.AssertionResult = {

src/matchers/browser/toHaveUrl.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export async function toHaveUrl(
66
expectedValue: string | RegExp | WdioAsymmetricMatcher<string>,
77
options: ExpectWebdriverIO.StringOptions = DEFAULT_OPTIONS
88
) {
9+
const isNot = this.isNot
910
const { expectation = 'url', verb = 'have' } = this
1011

1112
await options.beforeAssertion?.({
@@ -19,7 +20,7 @@ export async function toHaveUrl(
1920
actual = await browser.getUrl()
2021

2122
return compareText(actual, expectedValue, options).result
22-
}, options)
23+
}, isNot, options)
2324

2425
const message = enhanceError('window', expectedValue, actual, this, verb, expectation, '', options)
2526
const result: ExpectWebdriverIO.AssertionResult = {

src/matchers/element/toHaveAttribute.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ async function conditionAttrAndValue(el: WebdriverIO.Element, attribute: string,
2727
}
2828

2929
export async function toHaveAttributeAndValue(received: WdioElementMaybePromise, attribute: string, value: string | RegExp | WdioAsymmetricMatcher<string>, options: ExpectWebdriverIO.StringOptions = DEFAULT_OPTIONS) {
30+
const isNot = this.isNot
3031
const { expectation = 'attribute', verb = 'have' } = this
3132

3233
let el = await received?.getElement()
@@ -37,7 +38,7 @@ export async function toHaveAttributeAndValue(received: WdioElementMaybePromise,
3738
attr = result.values
3839

3940
return result.success
40-
}, options)
41+
}, isNot, options)
4142

4243
const expected = wrapExpectedWithArray(el, attr, value)
4344
const message = enhanceError(el, expected, attr, this, verb, expectation, attribute, options)
@@ -48,8 +49,9 @@ export async function toHaveAttributeAndValue(received: WdioElementMaybePromise,
4849
} as ExpectWebdriverIO.AssertionResult
4950
}
5051

51-
async function toHaveAttributeFn(received: WdioElementMaybePromise, attribute: string, options: ExpectWebdriverIO.StringOptions) {
52-
const { expectation = 'attribute', verb = 'have', isNot } = this
52+
async function toHaveAttributeFn(received: WdioElementMaybePromise, attribute: string) {
53+
const isNot = this.isNot
54+
const { expectation = 'attribute', verb = 'have' } = this
5355

5456
let el = await received?.getElement()
5557

@@ -58,9 +60,9 @@ async function toHaveAttributeFn(received: WdioElementMaybePromise, attribute: s
5860
el = result.el as WebdriverIO.Element
5961

6062
return result.success
61-
}, options)
63+
}, isNot, {})
6264

63-
const message = enhanceError(el, !isNot, pass, this, verb, expectation, attribute, options)
65+
const message = enhanceError(el, !isNot, pass, this, verb, expectation, attribute, {})
6466

6567
return {
6668
pass,
@@ -84,7 +86,7 @@ export async function toHaveAttribute(
8486
// Name and value is passed in e.g. el.toHaveAttribute('attr', 'value', (opts))
8587
? await toHaveAttributeAndValue.call(this, received, attribute, value, options)
8688
// Only name is passed in e.g. el.toHaveAttribute('attr')
87-
: await toHaveAttributeFn.call(this, received, attribute, options)
89+
: await toHaveAttributeFn.call(this, received, attribute)
8890

8991
await options.afterAssertion?.({
9092
matcherName: 'toHaveAttribute',

src/matchers/element/toHaveChildren.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export async function toHaveChildren(
3535
expectedValue?: number | ExpectWebdriverIO.NumberOptions,
3636
options: ExpectWebdriverIO.StringOptions = DEFAULT_OPTIONS
3737
) {
38+
const isNot = this.isNot
3839
const { expectation = 'children', verb = 'have' } = this
3940

4041
await options.beforeAssertion?.({
@@ -55,7 +56,7 @@ export async function toHaveChildren(
5556
children = result.values
5657

5758
return result.success
58-
}, { ...numberOptions, ...options })
59+
}, isNot, { ...numberOptions, ...options })
5960

6061
const error = numberError(numberOptions)
6162
const expectedArray = wrapExpectedWithArray(el, children, error)

src/matchers/element/toHaveClass.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export async function toHaveElementClass(
4242
expectedValue: string | RegExp | Array<string | RegExp> | WdioAsymmetricMatcher<string>,
4343
options: ExpectWebdriverIO.StringOptions = DEFAULT_OPTIONS
4444
) {
45+
const isNot = this.isNot
4546
const { expectation = 'class', verb = 'have' } = this
4647

4748
await options.beforeAssertion?.({
@@ -61,7 +62,7 @@ export async function toHaveElementClass(
6162
attr = result.values
6263

6364
return result.success
64-
}, options)
65+
}, isNot, options)
6566

6667
const message = enhanceError(el, wrapExpectedWithArray(el, attr, expectedValue), attr, this, verb, expectation, '', options)
6768
const result: ExpectWebdriverIO.AssertionResult = {

0 commit comments

Comments
 (0)