Skip to content
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
31 changes: 16 additions & 15 deletions playwright/_impl/_assertions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Copy link
Member

@Skn0tt Skn0tt Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we reuse attached_string here?

Suggested change
("to.be.attached" if attached else "to.be.detached"),
f"to.be.{attached_string}"

FrameExpectOptions(timeout=timeout),
None,
"Locator expected to be attached",
f"Locator expected to be {attached_string}",
)

async def to_be_checked(
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down
144 changes: 138 additions & 6 deletions tests/async/test_assertions.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,14 +510,14 @@ async def test_assertions_locator_to_be_checked(page: Page, server: Server) -> N
await page.set_content("<input type=checkbox>")
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()

Expand All @@ -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("<button>Text</button>")
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("<button>Text</button>")
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("<button disabled>Text</button>")
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("<button>Text</button>")
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("<button disabled>Text</button>")
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("<button>Text</button>")
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("<input></input><button disabled>Text</button>")
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("<input></input>")
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("<input readonly></input>")
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("<input></input>")
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("<input></input>")
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(
Expand Down Expand Up @@ -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("<button>hello</button>")
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("<button hidden>hello</button>")
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("<button>hello</button>")
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("<button>hello</button>")
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("<div></div>")
await page.eval_on_selector(
"div",
"""
div => setTimeout(() => {
div.innerHTML = '<span>Hello</span>';
}, 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("<div><span>Hello</span></div>")
await page.eval_on_selector(
"span",
"""
span => setTimeout(() => {
span.textContent = '';
}, 700);
""",
)
await expect(page.locator("span")).not_to_be_visible()


async def test_assertions_should_serialize_regexp_correctly(
page: Page, server: Server
) -> None:
Expand Down Expand Up @@ -746,6 +867,15 @@ async def test_should_be_attached_with_attached_false(page: Page) -> None:
await expect(locator).to_be_attached(attached=False)


async def test_should_be_attached_with_attached_false_and_throw_good_error(
page: Page,
) -> None:
await page.set_content("<button>hello</button>")
locator = page.locator("button")
with pytest.raises(AssertionError, match="Locator expected to be detached"):
await expect(locator).to_be_attached(attached=False, timeout=1)


async def test_should_be_attached_with_not_and_attached_false(page: Page) -> None:
await page.set_content("<button>hello</button>")
locator = page.locator("button")
Expand Down Expand Up @@ -773,7 +903,9 @@ async def test_should_be_attached_eventually_with_not(page: Page) -> None:
async def test_should_be_attached_fail(page: Page) -> None:
await page.set_content("<button>Hello</button>")
locator = page.locator("input")
with pytest.raises(AssertionError) as exc_info:
with pytest.raises(
AssertionError, match="Locator expected to be attached"
) as exc_info:
await expect(locator).to_be_attached(timeout=1000)
assert "locator resolved to" not in exc_info.value.args[0]

Expand Down
47 changes: 41 additions & 6 deletions tests/sync/test_assertions.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,14 +490,14 @@ def test_assertions_locator_to_be_checked(page: Page, server: Server) -> None:
page.set_content("<input type=checkbox>")
my_checkbox = page.locator("input")
expect(my_checkbox).not_to_be_checked()
with pytest.raises(AssertionError):
with pytest.raises(AssertionError, match="Locator expected to be checked"):
expect(my_checkbox).to_be_checked(timeout=100)
expect(my_checkbox).to_be_checked(timeout=100, checked=False)
with pytest.raises(AssertionError):
expect(my_checkbox).to_be_checked(timeout=100, checked=True)
my_checkbox.check()
expect(my_checkbox).to_be_checked(timeout=100, checked=True)
with pytest.raises(AssertionError):
with pytest.raises(AssertionError, match="Locator expected to be unchecked"):
expect(my_checkbox).to_be_checked(timeout=100, checked=False)
expect(my_checkbox).to_be_checked()

Expand All @@ -512,7 +512,7 @@ def test_assertions_locator_to_be_disabled_enabled(page: Page, server: Server) -
expect(my_checkbox).to_be_disabled(timeout=100)
my_checkbox.evaluate("e => e.disabled = true")
expect(my_checkbox).to_be_disabled()
with pytest.raises(AssertionError):
with pytest.raises(AssertionError, match="Locator expected to be enabled"):
expect(my_checkbox).to_be_enabled(timeout=100)


Expand All @@ -521,6 +521,14 @@ def test_assertions_locator_to_be_enabled_with_true(page: Page) -> None:
expect(page.locator("button")).to_be_enabled(enabled=True)


def test_assertions_locator_to_be_enabled_with_false_throws_good_exception(
page: Page,
) -> None:
page.set_content("<button>Text</button>")
with pytest.raises(AssertionError, match="Locator expected to be disabled"):
expect(page.locator("button")).to_be_enabled(enabled=False)


def test_assertions_locator_to_be_enabled_with_false(page: Page) -> None:
page.set_content("<button disabled>Text</button>")
expect(page.locator("button")).to_be_enabled(enabled=False)
Expand Down Expand Up @@ -562,7 +570,7 @@ def test_assertions_locator_to_be_editable(page: Page, server: Server) -> None:
page.set_content("<input></input><button disabled>Text</button>")
expect(page.locator("button")).not_to_be_editable()
expect(page.locator("input")).to_be_editable()
with pytest.raises(AssertionError):
with pytest.raises(AssertionError, match="Locator expected to be editable"):
expect(page.locator("button")).to_be_editable(timeout=100)


Expand All @@ -576,6 +584,14 @@ def test_assertions_locator_to_be_editable_with_false(page: Page) -> None:
expect(page.locator("input")).to_be_editable(editable=False)


def test_assertions_locator_to_be_editable_with_false_and_throw_good_exception(
page: Page,
) -> None:
page.set_content("<input></input>")
with pytest.raises(AssertionError, match="Locator expected to be readonly"):
expect(page.locator("input")).to_be_editable(editable=False)


def test_assertions_locator_to_be_editable_with_not_and_false(page: Page) -> None:
page.set_content("<input></input>")
expect(page.locator("input")).not_to_be_editable(editable=False)
Expand Down Expand Up @@ -611,7 +627,7 @@ def test_assertions_locator_to_be_hidden_visible(page: Page, server: Server) ->
expect(my_checkbox).to_be_hidden(timeout=100)
my_checkbox.evaluate("e => e.style.display = 'none'")
expect(my_checkbox).to_be_hidden()
with pytest.raises(AssertionError):
with pytest.raises(AssertionError, match="Locator expected to be visible"):
expect(my_checkbox).to_be_visible(timeout=100)


Expand All @@ -625,6 +641,14 @@ def test_assertions_locator_to_be_visible_with_false(page: Page) -> None:
expect(page.locator("button")).to_be_visible(visible=False)


def test_assertions_locator_to_be_visible_with_false_throws_good_exception(
page: Page,
) -> None:
page.set_content("<button>hello</button>")
with pytest.raises(AssertionError, match="Locator expected to be hidden"):
expect(page.locator("button")).to_be_visible(visible=False)


def test_assertions_locator_to_be_visible_with_not_and_false(page: Page) -> None:
page.set_content("<button>hello</button>")
expect(page.locator("button")).not_to_be_visible(visible=False)
Expand Down Expand Up @@ -813,6 +837,15 @@ def test_should_be_attached_with_attached_false(page: Page) -> None:
expect(locator).to_be_attached(attached=False)


def test_should_be_attached_with_attached_false_and_throw_good_error(
page: Page,
) -> None:
page.set_content("<button>hello</button>")
locator = page.locator("button")
with pytest.raises(AssertionError, match="Locator expected to be detached"):
expect(locator).to_be_attached(attached=False, timeout=1)


def test_should_be_attached_with_not_and_attached_false(page: Page) -> None:
page.set_content("<button>hello</button>")
locator = page.locator("button")
Expand All @@ -838,7 +871,9 @@ def test_should_be_attached_eventually_with_not(page: Page) -> None:
def test_should_be_attached_fail(page: Page) -> None:
page.set_content("<button>Hello</button>")
locator = page.locator("input")
with pytest.raises(AssertionError) as exc_info:
with pytest.raises(
AssertionError, match="Locator expected to be attached"
) as exc_info:
expect(locator).to_be_attached(timeout=1000)
assert "locator resolved to" not in exc_info.value.args[0]

Expand Down
Loading