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

feat(assertions): support toBeVisible({ visible }) #17207

Merged
merged 1 commit into from
Sep 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/src/api/class-locatorassertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,9 @@ var locator = Page.Locator(".my-element");
await Expect(locator).ToBeVisibleAsync();
```

### option: LocatorAssertions.toBeVisible.visible
* since: v1.26
- `visible` <[boolean]>
### option: LocatorAssertions.toBeVisible.timeout = %%-js-assertions-timeout-%%
* since: v1.18
### option: LocatorAssertions.toBeVisible.timeout = %%-csharp-java-python-assertions-timeout-%%
Expand Down
5 changes: 3 additions & 2 deletions packages/playwright-test/src/matchers/matchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,11 @@ export function toBeHidden(
export function toBeVisible(
this: ReturnType<Expect['getState']>,
locator: LocatorEx,
options?: { timeout?: number },
options?: { visible?: boolean, timeout?: number },
) {
return toBeTruthy.call(this, 'toBeVisible', locator, 'Locator', async (isNot, timeout, customStackTrace) => {
return await locator._expect(customStackTrace, 'to.be.visible', { isNot, timeout });
const visible = !options || options.visible === undefined || options.visible === true;
return await locator._expect(customStackTrace, visible ? 'to.be.visible' : 'to.be.hidden', { isNot, timeout });
}, options);
}

Expand Down
2 changes: 2 additions & 0 deletions packages/playwright-test/types/test.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3369,6 +3369,8 @@ interface LocatorAssertions {
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
*/
timeout?: number;

visible?: boolean;
}): Promise<void>;

/**
Expand Down
192 changes: 107 additions & 85 deletions tests/page/expect-boolean.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,105 +209,127 @@ test('not.toBeDisabled div', async ({ page }) => {
await expect(locator).not.toBeDisabled();
});

test('toBeVisible', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
await expect(locator).toBeVisible();
});
test.describe('toBeVisible', () => {
test('default', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
await expect(locator).toBeVisible();
});

test('not.toBeVisible', async ({ page }) => {
await page.setContent('<button style="display: none"></button>');
const locator = page.locator('button');
await expect(locator).not.toBeVisible();
});
test('with not', async ({ page }) => {
await page.setContent('<button style="display: none">hello</button>');
const locator = page.locator('button');
await expect(locator).not.toBeVisible();
});

test('toBeHidden', async ({ page }) => {
await page.setContent('<button style="display: none"></button>');
const locator = page.locator('button');
await expect(locator).toBeHidden();
});
test('with visible:true', async ({ page }) => {
await page.setContent('<button>hello</button>');
const locator = page.locator('button');
await expect(locator).toBeVisible({ visible: true });
});

test('toBeHidden when nothing matches', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('button');
await expect(locator).toBeHidden();
});
test('with visible:false', async ({ page }) => {
await page.setContent('<button hidden>hello</button>');
const locator = page.locator('button');
await expect(locator).toBeVisible({ visible: false });
});

test('not.toBeHidden', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
await expect(locator).not.toBeHidden();
});
test('with not and visible:false', async ({ page }) => {
await page.setContent('<button>hello</button>');
const locator = page.locator('button');
await expect(locator).not.toBeVisible({ visible: false });
});

test('toBeVisible eventually', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('div', div => div.innerHTML = '<span>Hello</span>').catch(() => {});
}, 0);
await expect(locator).toBeVisible();
});
test('eventually', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('div', div => div.innerHTML = '<span>Hello</span>').catch(() => {});
}, 0);
await expect(locator).toBeVisible();
});

test('not.toBeHidden eventually', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('div', div => div.innerHTML = '<span>Hello</span>').catch(() => {});
}, 0);
await expect(locator).not.toBeHidden();
});
test('eventually with not', async ({ page }) => {
await page.setContent('<div><span>Hello</span></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('span', span => span.textContent = '').catch(() => {});
}, 0);
await expect(locator).not.toBeVisible();
});

test('not.toBeVisible eventually', async ({ page }) => {
await page.setContent('<div><span>Hello</span></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('span', span => span.textContent = '').catch(() => {});
}, 0);
await expect(locator).not.toBeVisible();
});
test('fail', async ({ page }) => {
await page.setContent('<button style="display: none"></button>');
const locator = page.locator('button');
const error = await expect(locator).toBeVisible({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <button></button>`);
});

test('toBeHidden eventually', async ({ page }) => {
await page.setContent('<div><span>Hello</span></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('span', span => span.textContent = '').catch(() => {});
}, 0);
await expect(locator).toBeHidden();
test('fail with not', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
const error = await expect(locator).not.toBeVisible({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <input/>`);
});
});

test('toBeVisible fail', async ({ page }) => {
await page.setContent('<button style="display: none"></button>');
const locator = page.locator('button');
const error = await expect(locator).toBeVisible({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <button></button>`);
});
test.describe('toBeHidden', () => {
test('default', async ({ page }) => {
await page.setContent('<button style="display: none"></button>');
const locator = page.locator('button');
await expect(locator).toBeHidden();
});

test('not.toBeVisible fail', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
const error = await expect(locator).not.toBeVisible({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <input/>`);
});
test('when nothing matches', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('button');
await expect(locator).toBeHidden();
});

test('toBeHidden fail', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
const error = await expect(locator).toBeHidden({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <input/>`);
});
test('with not', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
await expect(locator).not.toBeHidden();
});

test('not.toBeHidden fail', async ({ page }) => {
await page.setContent('<button style="display: none"></button>');
const locator = page.locator('button');
const error = await expect(locator).not.toBeHidden({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <button></button>`);
});
test('eventually with not', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('div', div => div.innerHTML = '<span>Hello</span>').catch(() => {});
}, 0);
await expect(locator).not.toBeHidden();
});

test('not.toBeHidden fail not matching', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('button');
const error = await expect(locator).not.toBeHidden({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`expect.toBeHidden with timeout 1000ms`);
test('eventually', async ({ page }) => {
await page.setContent('<div><span>Hello</span></div>');
const locator = page.locator('span');
setTimeout(() => {
page.$eval('span', span => span.textContent = '').catch(() => {});
}, 0);
await expect(locator).toBeHidden();
});

test('fail', async ({ page }) => {
await page.setContent('<input></input>');
const locator = page.locator('input');
const error = await expect(locator).toBeHidden({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <input/>`);
});

test('fail with not', async ({ page }) => {
await page.setContent('<button style="display: none"></button>');
const locator = page.locator('button');
const error = await expect(locator).not.toBeHidden({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`selector resolved to <button></button>`);
});

test('fail with not when nothing matching', async ({ page }) => {
await page.setContent('<div></div>');
const locator = page.locator('button');
const error = await expect(locator).not.toBeHidden({ timeout: 1000 }).catch(e => e);
expect(error.message).toContain(`expect.toBeHidden with timeout 1000ms`);
});
});

test('toBeFocused', async ({ page }) => {
Expand Down
3 changes: 3 additions & 0 deletions tests/playwright-test/expect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ test('should propose only the relevant matchers when custom expect matcher class

await test.expect(page.locator('foo')).not.toBeEditable();
await test.expect(page.locator('foo')).toBeEditable({ editable: false });

await test.expect(page.locator('foo')).toBeVisible();
await test.expect(page.locator('foo')).not.toBeVisible({ visible: false });
});
`
});
Expand Down