diff --git a/playwright/_impl/_assertions.py b/playwright/_impl/_assertions.py index 163b156ed..13e7ac481 100644 --- a/playwright/_impl/_assertions.py +++ b/playwright/_impl/_assertions.py @@ -511,15 +511,14 @@ async def to_be_attached( timeout: float = None, ) -> None: __tracebackhide__ = True + if attached is None: + attached = True + attached_string = "attached" if attached else "detached" await self._expect_impl( - ( - "to.be.attached" - if (attached is None or attached is True) - else "to.be.detached" - ), + ("to.be.attached" if attached else "to.be.detached"), FrameExpectOptions(timeout=timeout), None, - "Locator expected to be attached", + f"Locator expected to be {attached_string}", ) async def to_be_checked( @@ -528,15 +527,14 @@ async def to_be_checked( checked: bool = None, ) -> None: __tracebackhide__ = True + if checked is None: + checked = True + checked_string = "checked" if checked else "unchecked" await self._expect_impl( - ( - "to.be.checked" - if checked is None or checked is True - else "to.be.unchecked" - ), + ("to.be.checked" if checked else "to.be.unchecked"), FrameExpectOptions(timeout=timeout), None, - "Locator expected to be checked", + f"Locator expected to be {checked_string}", ) async def not_to_be_attached( @@ -581,11 +579,12 @@ async def to_be_editable( __tracebackhide__ = True if editable is None: editable = True + editable_string = "editable" if editable else "readonly" await self._expect_impl( "to.be.editable" if editable else "to.be.readonly", FrameExpectOptions(timeout=timeout), None, - "Locator expected to be editable", + f"Locator expected to be {editable_string}", ) async def not_to_be_editable( @@ -623,11 +622,12 @@ async def to_be_enabled( __tracebackhide__ = True if enabled is None: enabled = True + enabled_string = "enabled" if enabled else "disabled" await self._expect_impl( "to.be.enabled" if enabled else "to.be.disabled", FrameExpectOptions(timeout=timeout), None, - "Locator expected to be enabled", + f"Locator expected to be {enabled_string}", ) async def not_to_be_enabled( @@ -665,11 +665,12 @@ async def to_be_visible( __tracebackhide__ = True if visible is None: visible = True + visible_string = "visible" if visible else "hidden" await self._expect_impl( "to.be.visible" if visible else "to.be.hidden", FrameExpectOptions(timeout=timeout), None, - "Locator expected to be visible", + f"Locator expected to be {visible_string}", ) async def not_to_be_visible( diff --git a/tests/async/test_assertions.py b/tests/async/test_assertions.py index d61e625c7..88b9c1b4f 100644 --- a/tests/async/test_assertions.py +++ b/tests/async/test_assertions.py @@ -510,14 +510,14 @@ async def test_assertions_locator_to_be_checked(page: Page, server: Server) -> N await page.set_content("") my_checkbox = page.locator("input") await expect(my_checkbox).not_to_be_checked() - with pytest.raises(AssertionError): + with pytest.raises(AssertionError, match="Locator expected to be checked"): await expect(my_checkbox).to_be_checked(timeout=100) await expect(my_checkbox).to_be_checked(timeout=100, checked=False) with pytest.raises(AssertionError): await expect(my_checkbox).to_be_checked(timeout=100, checked=True) await my_checkbox.check() await expect(my_checkbox).to_be_checked(timeout=100, checked=True) - with pytest.raises(AssertionError): + with pytest.raises(AssertionError, match="Locator expected to be unchecked"): await expect(my_checkbox).to_be_checked(timeout=100, checked=False) await expect(my_checkbox).to_be_checked() @@ -534,19 +534,91 @@ async def test_assertions_locator_to_be_disabled_enabled( await expect(my_checkbox).to_be_disabled(timeout=100) await my_checkbox.evaluate("e => e.disabled = true") await expect(my_checkbox).to_be_disabled() - with pytest.raises(AssertionError): + with pytest.raises(AssertionError, match="Locator expected to be enabled"): await expect(my_checkbox).to_be_enabled(timeout=100) +async def test_assertions_locator_to_be_enabled_with_true(page: Page) -> None: + await page.set_content("") + await expect(page.locator("button")).to_be_enabled(enabled=True) + + +async def test_assertions_locator_to_be_enabled_with_false_throws_good_exception( + page: Page, +) -> None: + await page.set_content("") + with pytest.raises(AssertionError, match="Locator expected to be disabled"): + await expect(page.locator("button")).to_be_enabled(enabled=False) + + +async def test_assertions_locator_to_be_enabled_with_false(page: Page) -> None: + await page.set_content("") + await expect(page.locator("button")).to_be_enabled(enabled=False) + + +async def test_assertions_locator_to_be_enabled_with_not_and_false(page: Page) -> None: + await page.set_content("") + await expect(page.locator("button")).not_to_be_enabled(enabled=False) + + +async def test_assertions_locator_to_be_enabled_eventually(page: Page) -> None: + await page.set_content("") + await page.eval_on_selector( + "button", + """ + button => setTimeout(() => { + button.removeAttribute('disabled'); + }, 700); + """, + ) + await expect(page.locator("button")).to_be_enabled() + + +async def test_assertions_locator_to_be_enabled_eventually_with_not(page: Page) -> None: + await page.set_content("") + await page.eval_on_selector( + "button", + """ + button => setTimeout(() => { + button.setAttribute('disabled', ''); + }, 700); + """, + ) + await expect(page.locator("button")).not_to_be_enabled() + + async def test_assertions_locator_to_be_editable(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("") await expect(page.locator("button")).not_to_be_editable() await expect(page.locator("input")).to_be_editable() - with pytest.raises(AssertionError): + with pytest.raises(AssertionError, match="Locator expected to be editable"): await expect(page.locator("button")).to_be_editable(timeout=100) +async def test_assertions_locator_to_be_editable_with_true(page: Page) -> None: + await page.set_content("") + await expect(page.locator("input")).to_be_editable(editable=True) + + +async def test_assertions_locator_to_be_editable_with_false(page: Page) -> None: + await page.set_content("") + await expect(page.locator("input")).to_be_editable(editable=False) + + +async def test_assertions_locator_to_be_editable_with_false_and_throw_good_exception( + page: Page, +) -> None: + await page.set_content("") + with pytest.raises(AssertionError, match="Locator expected to be readonly"): + await expect(page.locator("input")).to_be_editable(editable=False) + + +async def test_assertions_locator_to_be_editable_with_not_and_false(page: Page) -> None: + await page.set_content("") + await expect(page.locator("input")).not_to_be_editable(editable=False) + + async def test_assertions_locator_to_be_empty(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content( @@ -579,10 +651,59 @@ async def test_assertions_locator_to_be_hidden_visible( await expect(my_checkbox).to_be_hidden(timeout=100) await my_checkbox.evaluate("e => e.style.display = 'none'") await expect(my_checkbox).to_be_hidden() - with pytest.raises(AssertionError): + with pytest.raises(AssertionError, match="Locator expected to be visible"): await expect(my_checkbox).to_be_visible(timeout=100) +async def test_assertions_locator_to_be_visible_with_true(page: Page) -> None: + await page.set_content("") + await expect(page.locator("button")).to_be_visible(visible=True) + + +async def test_assertions_locator_to_be_visible_with_false(page: Page) -> None: + await page.set_content("") + await expect(page.locator("button")).to_be_visible(visible=False) + + +async def test_assertions_locator_to_be_visible_with_false_throws_good_exception( + page: Page, +) -> None: + await page.set_content("") + with pytest.raises(AssertionError, match="Locator expected to be hidden"): + await expect(page.locator("button")).to_be_visible(visible=False) + + +async def test_assertions_locator_to_be_visible_with_not_and_false(page: Page) -> None: + await page.set_content("") + await expect(page.locator("button")).not_to_be_visible(visible=False) + + +async def test_assertions_locator_to_be_visible_eventually(page: Page) -> None: + await page.set_content("
") + await page.eval_on_selector( + "div", + """ + div => setTimeout(() => { + div.innerHTML = 'Hello'; + }, 700); + """, + ) + await expect(page.locator("span")).to_be_visible() + + +async def test_assertions_locator_to_be_visible_eventually_with_not(page: Page) -> None: + await page.set_content("