From 0ade5aa9adac16112d82c5ca522ab9abcad6d166 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Wed, 25 Oct 2023 19:22:13 -0700 Subject: [PATCH] fix: ignoreCase in toHaveAttribute (#27809) Fixes #27795 --- docs/src/api/class-locatorassertions.md | 6 ++++++ packages/playwright/src/matchers/matchers.ts | 4 ++-- packages/playwright/types/test.d.ts | 8 ++++++++ tests/page/expect-misc.spec.ts | 7 +++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/src/api/class-locatorassertions.md b/docs/src/api/class-locatorassertions.md index 077e418eb5..1569c69c2e 100644 --- a/docs/src/api/class-locatorassertions.md +++ b/docs/src/api/class-locatorassertions.md @@ -1151,6 +1151,12 @@ Expected attribute value. ### option: LocatorAssertions.toHaveAttribute.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 +### option: LocatorAssertions.toHaveAttribute.ignoreCase = %%-js-assertions-timeout-%% +* since: v1.40 +- `ignoreCase` <[boolean]> + +Whether to perform case-insensitive match. [`option: ignoreCase`] option takes precedence over the corresponding regular expression flag if specified. + ## async method: LocatorAssertions.toHaveAttribute#2 * since: v1.39 * langs: js diff --git a/packages/playwright/src/matchers/matchers.ts b/packages/playwright/src/matchers/matchers.ts index 5f4013c62f..cd8e54a37d 100644 --- a/packages/playwright/src/matchers/matchers.ts +++ b/packages/playwright/src/matchers/matchers.ts @@ -178,7 +178,7 @@ export function toHaveAttribute( locator: LocatorEx, name: string, expected: string | RegExp | undefined | { timeout?: number }, - options?: { timeout?: number }, + options?: { timeout?: number, ignoreCase?: boolean }, ) { if (!options) { // Update params for the case toHaveAttribute(name, options); @@ -193,7 +193,7 @@ export function toHaveAttribute( }, options); } return toMatchText.call(this, 'toHaveAttribute', locator, 'Locator', async (isNot, timeout) => { - const expectedText = toExpectedTextValues([expected as (string | RegExp)]); + const expectedText = toExpectedTextValues([expected as (string | RegExp)], { ignoreCase: options?.ignoreCase }); return await locator._expect('to.have.attribute.value', { expressionArg: name, expectedText, isNot, timeout }); }, expected as (string | RegExp), options); } diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 1c5ab5e791..e605859592 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -5708,6 +5708,14 @@ interface LocatorAssertions { * @param options */ toHaveAttribute(name: string, value: string|RegExp, options?: { + /** + * Time to retry the assertion for in milliseconds. Defaults to `timeout` in `TestConfig.expect`. + * + * Whether to perform case-insensitive match. `ignoreCase` option takes precedence over the corresponding regular + * expression flag if specified. + */ + ignoreCase?: boolean; + /** * Time to retry the assertion for in milliseconds. Defaults to `timeout` in `TestConfig.expect`. */ diff --git a/tests/page/expect-misc.spec.ts b/tests/page/expect-misc.spec.ts index 2e229aed01..91f4178735 100644 --- a/tests/page/expect-misc.spec.ts +++ b/tests/page/expect-misc.spec.ts @@ -299,6 +299,13 @@ test.describe('toHaveAttribute', () => { await expect(locator).toHaveAttribute('checked', { timeout: 5000 }); await expect(locator).not.toHaveAttribute('open', { timeout: 5000 }); }); + + test('support ignoreCase', async ({ page }) => { + await page.setContent('
Text content
'); + const locator = page.locator('#NoDe'); + await expect(locator).toHaveAttribute('id', 'node', { ignoreCase: true }); + await expect(locator).not.toHaveAttribute('id', 'node'); + }); }); test.describe('toHaveCSS', () => {