Skip to content

fix(transport): store expect errorDetails as serializable string - #3344

Merged
Dmitry Gozman (dgozman) merged 3 commits into
microsoft:mainfrom
kblok:kblok-evaluate-issue-3342
Aug 12, 2026
Merged

fix(transport): store expect errorDetails as serializable string#3344
Dmitry Gozman (dgozman) merged 3 commits into
microsoft:mainfrom
kblok:kblok-evaluate-issue-3342

Conversation

@kblok

Copy link
Copy Markdown
Contributor

Summary

  • Fixes a .NET Framework regression where any failing web-first Expect() hung forever and permanently killed the shared driver connection.
  • Connection.Dispatch now stores expect errorDetails as raw JSON text (serializable) instead of JsonElement, and always completes the callback even if exception enrichment fails.
  • Frame.ExpectAsync parses that JSON string when building FrameExpectResult.

Fixes #3342

Root cause

On .NET Framework, Exception.Data rejects non-serializable values. Storing JsonElement threw after the callback was already removed from _callbacks, so TrySetException never ran (orphaned hang) and the transport loop closed the connection.

Test plan

  • Added ConnectionTests.Dispatch_ExpectErrorDetails_MustBeSerializableForExceptionData (portable unit test; fails on main when ErrorDetails is JsonElement)
  • Confirmed red on unfixed main, green after fix (net8.0)
  • Spot-checked LocatorAssertionsTests.ShouldSupportToBeChecked and ShouldSupportToHaveCount
  • CI on Windows/.NET Framework (original hang scenario)

.NET Framework Exception.Data rejects non-serializable JsonElement values.
Storing expect ErrorDetails as raw JSON text prevents orphaned assertion
callbacks and keeps the driver connection alive after failing Expect().

Fixes microsoft#3342

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

@dgozman Dmitry Gozman (dgozman) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hi Darío!

Thank you for the PR. I think the string serialization is the right solution, but I have some comments about the rest.

Thank you!

Comment thread src/Playwright/Transport/Connection.cs Outdated
}
catch
{
// Best-effort enrichment only; completing the callback is mandatory.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's not do this, or we won't be able to catch issues like this one. The earlier we know something went wrong, the better the chances for a fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done!

Comment thread src/Playwright.Tests/ConnectionTests.cs Outdated
/// On .NET Framework, Exception.Data rejects non-serializable values (e.g. JsonElement),
/// which used to orphan the callback and kill the driver connection (issue #3342).
/// </summary>
public class ConnectionTests

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's drop this test, I don't like that we mostly test the test code itself. Ideally, we would get some .net framework coverage, but I'm not it's worth it at this point.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense!

Keep serializable ErrorDetails string storage only.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread src/Playwright/Transport/Connection.cs Outdated

@dgozman Dmitry Gozman (dgozman) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks great, thank you!

@dgozman
Dmitry Gozman (dgozman) merged commit e768dcc into microsoft:main Aug 12, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants