Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docs]: Custom matcher example doesn't work with not #34390

Open
lukpsaxo opened this issue Jan 18, 2025 · 0 comments
Open

[Docs]: Custom matcher example doesn't work with not #34390

lukpsaxo opened this issue Jan 18, 2025 · 0 comments

Comments

@lukpsaxo
Copy link
Contributor

Page(s)

https://playwright.dev/docs/next/test-assertions#add-custom-matchers-using-expectextend

Description

The example in the docs above doesn't work with not properly

e.g.

expect(locator).not.toHaveAmount(2);
  1. the expectation retries until it times out and then passes - this makes the assertion take alot longer than it should.
  2. We see "red" failed assertions in the ui view even though it passes.

To fix the documentation example it could be changed to this - but you tell me if this is the correct way to fix it.

import { expect as baseExpect } from '@playwright/test';
import type { Page, Locator } from '@playwright/test';

export { test } from '@playwright/test';

export const expect = baseExpect.extend({
  async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
    const assertionName = 'toHaveAmount';
    let pass: boolean;
    let matcherResult: any;
    try {
      let expectVal = baseExpect(locator);
      if (this.isNot) {
          expectVal = expectVal.not;
      }
      await expectVal.toHaveAttribute('data-amount', String(expected), options);
      pass = true;
    } catch (e: any) {
      matcherResult = e.matcherResult;
      pass = false;
    }

    if (this.isNot) {
        pass = !pass;
    }

    const message = pass
      ? () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
          '\n\n' +
          `Locator: ${locator}\n` +
          `Expected: not ${this.utils.printExpected(expected)}\n` +
          (matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '')
      : () =>  this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
          '\n\n' +
          `Locator: ${locator}\n` +
          `Expected: ${this.utils.printExpected(expected)}\n` +
          (matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '');

    return {
      message,
      pass,
      name: assertionName,
      expected,
      actual: matcherResult?.actual,
    };
  },
});

original request for this documentation: #15951 (comment)
issue raised but I was told off for not following the template: #34327
issue raised but I was told off because there are multiple issues with the example and you want seperate bugs: #34350

As I said originally I think making this custom assertion work properly is complicated - I'd prefer playwright exposed a way to do it rather than have a very complicated example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant