[Question][Docs] Extending expect with custom DOM-related assertions (and using locators)
See original GitHub issuePlaywright documentation comes with an example on how to use expect.extend
to add a custom matcher:
That example is pretty much identical to the one in jest docs, and as such, not useful:
The reason it is not useful is because I want to write a custom matcher that takes a locator and checks its attributes. However, as far as I understand, to do that fully I’d need to implement retries by myself.
In the end, to achieve roughly what I wanted, I wrote something like this:
expect.extend({
async toHaveAmount(locator, expected) {
const baseAmount = locator.locator('.base-amount')
await expect.soft(baseAmount).toHaveAttribute('data-amount', expected)
const received = await baseAmount.getAttribute('data-amount')
const options = {
comment: 'toHaveAmount (baseAmount check)',
isNot: this.isNot,
promise: this.promise,
}
const pass = expected === received
const message = pass
? () => this.utils.matcherHint('toBe', undefined, undefined, options) +
'\n\n' +
`Expected: ${this.isNot ? 'not' : ''}${this.utils.printExpected(expected)}\n` +
`Received: ${this.utils.printReceived(received)}`
: () => this.utils.matcherHint('toBe', undefined, undefined, options) +
'\n\n' +
`Expected: ${this.utils.printExpected(expected)}\n` +
`Received: ${this.utils.printReceived(received)}`
return { actual: received, message, pass }
},
})
Note that to avoid implementing retries by myself I’m adding a .soft
assertion, but I still have to implement a full-blown matcher in the end so that I can return valid data. Maybe I am missing something and it can be done in a simpler way, but that’s exactly why it’d be great to have a working example of using extend
with playwright locators.
Issue Analytics
- State:
- Created a year ago
- Comments:7 (2 by maintainers)
@pavelfeldman what information do you need? Basically, the point of the ticket is that Playwright docs should explain how to add playwright-related expect extensions (anything that works with the DOM). Any simple example will do.
@pavelfeldman, I think @AlexDaniel’s point is absolutely valid. I expect the docs to contain a real-world example of a custom matcher that works with a
Locator
reference and is retry-able like the Playwright matchers that come out of the box. It seems that the functions used internally by the library to create retry-able matchers aren’t exposed to the outside world as part of the public API.At first I resorted to using
expect.poll
and it seemed like a hacky workaround - I didn’t know about your suggestion in this thread back then. Then I decided to call the Playwright locator matchers inside of my own matcher function:It seems to be working for my use cases so far, but I have the feeling it’s not a solid solution and it might break in unexpected ways going forward.