Skip to content

Commit d7ec09a

Browse files
authored
fix(assertions): render aria snapshot in its own section on expect failure (#3089)
1 parent 0c81861 commit d7ec09a

3 files changed

Lines changed: 48 additions & 5 deletions

File tree

playwright/_impl/_assertions.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ async def _expect_impl(
103103
result = await self._call_expect(expression, expect_options, title)
104104
if result["matches"] == self._is_not:
105105
received = result.get("received") or {}
106+
aria_snapshot = None
106107
if isinstance(received, dict):
107-
if "value" in received and received["value"] is not None:
108-
actual = parse_value(received["value"])
109-
else:
110-
actual = received.get("ariaSnapshot")
108+
aria_snapshot = received.get("ariaSnapshot")
109+
value = received.get("value")
110+
actual = parse_value(value) if value is not None else None
111111
else:
112112
actual = received
113113
if self._custom_message:
@@ -120,9 +120,12 @@ async def _expect_impl(
120120
)
121121
error_message = result.get("errorMessage")
122122
error_message = f"\n{error_message}" if error_message else ""
123+
aria_snapshot_message = (
124+
f"\nAria snapshot:\n{aria_snapshot}" if aria_snapshot else ""
125+
)
123126
_record_soft_or_raise(
124127
AssertionError(
125-
f"{out_message}\nActual value: {actual}{error_message} {format_call_log(result.get('log'))}"
128+
f"{out_message}\nActual value: {actual}{error_message} {format_call_log(result.get('log'))}{aria_snapshot_message}"
126129
),
127130
self._is_soft,
128131
)

tests/async/test_assertions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,3 +1179,23 @@ async def test_soft_does_not_leak_between_scopes(page: Page, server: Server) ->
11791179
await page.set_content("<div>hello</div>")
11801180
with pytest.raises(RuntimeError, match="pytest-playwright"):
11811181
await expect.soft(page.locator("div")).to_have_text("nope", timeout=500)
1182+
1183+
1184+
async def test_assertions_should_include_aria_snapshot_in_separate_section(
1185+
page: Page,
1186+
) -> None:
1187+
await page.set_content(
1188+
"""
1189+
<div id="hidden" style="display: none"><span>secret</span></div>
1190+
<main><h1>Page Heading</h1></main>
1191+
"""
1192+
)
1193+
with pytest.raises(AssertionError) as excinfo:
1194+
await expect(page.locator("#hidden")).to_be_visible(timeout=500)
1195+
message = str(excinfo.value)
1196+
assert "Aria snapshot:" in message
1197+
# The aria snapshot lives in its own section, not in the "Actual value" line.
1198+
assert "Actual value: hidden" in message
1199+
actual_line = message.split("\n")[1]
1200+
assert 'heading "Page Heading"' not in actual_line
1201+
assert message.index('heading "Page Heading"') > message.index("Aria snapshot:")

tests/sync/test_assertions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,3 +1089,23 @@ def test_soft_inside_scope_collects_failures(page: Page, server: Server) -> None
10891089

10901090
assert len(errors) == 3
10911091
assert all(isinstance(e, AssertionError) for e in errors)
1092+
1093+
1094+
def test_assertions_should_include_aria_snapshot_in_separate_section(
1095+
page: Page,
1096+
) -> None:
1097+
page.set_content(
1098+
"""
1099+
<div id="hidden" style="display: none"><span>secret</span></div>
1100+
<main><h1>Page Heading</h1></main>
1101+
"""
1102+
)
1103+
with pytest.raises(AssertionError) as excinfo:
1104+
expect(page.locator("#hidden")).to_be_visible(timeout=500)
1105+
message = str(excinfo.value)
1106+
assert "Aria snapshot:" in message
1107+
# The aria snapshot lives in its own section, not in the "Actual value" line.
1108+
assert "Actual value: hidden" in message
1109+
actual_line = message.split("\n")[1]
1110+
assert 'heading "Page Heading"' not in actual_line
1111+
assert message.index('heading "Page Heading"') > message.index("Aria snapshot:")

0 commit comments

Comments
 (0)