From 306ab34aa3bcdfbb2369e1c698a161565bacc275 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Tue, 6 Sep 2022 11:40:34 -0700 Subject: [PATCH] feat(assertions): support toBeEnabled({ enabled }) (#17058) --- docs/src/api/class-locatorassertions.md | 3 + .../playwright-test/src/matchers/matchers.ts | 5 +- packages/playwright-test/types/test.d.ts | 2 + tests/page/expect-boolean.spec.ts | 82 ++++++++++++------- tests/playwright-test/expect.spec.ts | 7 ++ 5 files changed, 66 insertions(+), 33 deletions(-) diff --git a/docs/src/api/class-locatorassertions.md b/docs/src/api/class-locatorassertions.md index 6204fedbb9..3370eb1a41 100644 --- a/docs/src/api/class-locatorassertions.md +++ b/docs/src/api/class-locatorassertions.md @@ -593,6 +593,9 @@ var locator = Page.Locator("button.submit"); await Expect(locator).toBeEnabledAsync(); ``` +### option: LocatorAssertions.toBeEnabled.enabled +* since: v1.26 +- `enabled` <[boolean]> ### option: LocatorAssertions.toBeEnabled.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeEnabled.timeout = %%-csharp-java-python-assertions-timeout-%% diff --git a/packages/playwright-test/src/matchers/matchers.ts b/packages/playwright-test/src/matchers/matchers.ts index b191930508..1332398220 100644 --- a/packages/playwright-test/src/matchers/matchers.ts +++ b/packages/playwright-test/src/matchers/matchers.ts @@ -78,10 +78,11 @@ export function toBeEmpty( export function toBeEnabled( this: ReturnType, locator: LocatorEx, - options?: { timeout?: number }, + options?: { enabled?: boolean, timeout?: number }, ) { return toBeTruthy.call(this, 'toBeEnabled', locator, 'Locator', async (isNot, timeout, customStackTrace) => { - return await locator._expect(customStackTrace, 'to.be.enabled', { isNot, timeout }); + const enabled = !options || options.enabled === undefined || options.enabled === true; + return await locator._expect(customStackTrace, enabled ? 'to.be.enabled' : 'to.be.disabled', { isNot, timeout }); }, options); } diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index d39e24895b..c154ee6b16 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -3308,6 +3308,8 @@ interface LocatorAssertions { * @param options */ toBeEnabled(options?: { + enabled?: boolean; + /** * Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`. */ diff --git a/tests/page/expect-boolean.spec.ts b/tests/page/expect-boolean.spec.ts index 3f4128ce9a..4db3e0c731 100644 --- a/tests/page/expect-boolean.spec.ts +++ b/tests/page/expect-boolean.spec.ts @@ -84,41 +84,61 @@ test('toBeEditable', async ({ page }) => { await expect(locator).toBeEditable(); }); -test('toBeEnabled', async ({ page }) => { - await page.setContent(''); - const locator = page.locator('button'); - await expect(locator).toBeEnabled(); -}); +test.describe('toBeEnabled', () => { + test('default', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + await expect(locator).toBeEnabled(); + }); -test('toBeEnabled failed', async ({ page }) => { - await page.setContent(''); - const locator = page.locator('button'); - const error = await expect(locator).toBeEnabled({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain(`selector resolved to `); -}); + test('with enabled:true', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + await expect(locator).toBeEnabled({ enabled: true }); + }); -test('toBeEnabled eventually', async ({ page }) => { - await page.setContent(''); - const locator = page.locator('button'); - setTimeout(() => { - locator.evaluate(e => e.removeAttribute('disabled')).catch(() => {}); - }, 500); - await expect(locator).toBeEnabled(); -}); + test('with enabled:false', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + await expect(locator).toBeEnabled({ enabled: false }); + }); -test('not.toBeEnabled eventually', async ({ page }) => { - await page.setContent(''); - const locator = page.locator('button'); - setTimeout(() => { - locator.evaluate(e => e.setAttribute('disabled', '')).catch(() => {}); - }, 500); - await expect(locator).not.toBeEnabled(); -}); + test('failed', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + const error = await expect(locator).toBeEnabled({ timeout: 1000 }).catch(e => e); + expect(error.message).toContain(`selector resolved to `); + }); -test('toBeDisabled', async ({ page }) => { - await page.setContent(''); - const locator = page.locator('button'); - await expect(locator).toBeDisabled(); + test('eventually', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + setTimeout(() => { + locator.evaluate(e => e.removeAttribute('disabled')).catch(() => {}); + }, 500); + await expect(locator).toBeEnabled(); + }); + + test('eventually with not', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + setTimeout(() => { + locator.evaluate(e => e.setAttribute('disabled', '')).catch(() => {}); + }, 500); + await expect(locator).not.toBeEnabled(); + }); + + test('with not and enabled:false', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + await expect(locator).not.toBeEnabled({ enabled: false }); + }); + + test('toBeDisabled', async ({ page }) => { + await page.setContent(''); + const locator = page.locator('button'); + await expect(locator).toBeDisabled(); + }); }); test('toBeEmpty input', async ({ page }) => { diff --git a/tests/playwright-test/expect.spec.ts b/tests/playwright-test/expect.spec.ts index 24dccba74a..f9343e26d1 100644 --- a/tests/playwright-test/expect.spec.ts +++ b/tests/playwright-test/expect.spec.ts @@ -222,6 +222,13 @@ test('should propose only the relevant matchers when custom expect matcher class await test.expect(page).not.toBeEnabled(); await test.expect(page.locator('foo')).toBeEnabled(); + await test.expect(page.locator('foo')).toBeEnabled({ enabled: false }); + await test.expect(page.locator('foo')).not.toBeEnabled({ enabled: true }); + // @ts-expect-error + await test.expect(page.locator('foo')).toBeEnabled({ unknown: false }); + // @ts-expect-error + await test.expect(page.locator('foo')).toBeEnabled({ enabled: 'foo' }); + await test.expect(page.locator('foo')).toBe(true); // @ts-expect-error await test.expect(page.locator('foo')).toHaveURL('https://example.com');