fix: Playwright BrowserTest resource leaks and thread safety#4930
fix: Playwright BrowserTest resource leaks and thread safety#4930
Conversation
440a867 to
19b78e8
Compare
Code ReviewOverall, this PR makes meaningful improvements to resource management and thread safety in the Playwright integration. The changes are well-structured and address real issues (resource leaks, missing null guards, resilient disposal with exception aggregation). One bug was found in the exception handling logic. Bug: Original exception lost when
|
19b78e8 to
31958e1
Compare
Browser contexts were not closed on test failure paths in BrowserTest, leading to leaked browser resources. Additionally, if any single context or service disposal threw an exception, remaining resources were skipped entirely. This change ensures all contexts and services are always disposed via try/catch loops that collect exceptions, adds null-safety to BrowserService.DisposeAsync, protects the context list with a lock, and falls back to full disposal when WorkerAwareTest.ResetAsync fails.
31958e1 to
bd8dbde
Compare
Summary
BrowserTest.BrowserTearDownonly closed contexts when the test passed; on failure, contexts were cleared from the list but never actually closed, leaking browser resources.AggregateExceptionafter all resources have been processed.BrowserService.DisposeAsync-- added a null check before callingBrowser.CloseAsync()to guard against cases where the browser was never successfully created.BrowserTest._contextslist is now protected by a lock to prevent concurrent modification ifNewContextis called from multiple async continuations.WorkerAwareTest.WorkerTeardownnow handles the case where_currentWorkeris null, and ifResetAsyncthrows during the "test passed" path, it falls back to disposing all services rather than leaking them.RegisterService-- replacedContainsKey+ indexer double-lookup with a singleTryGetValuecall.Closes #4879
Test plan
dotnet build TUnit.Playwright/TUnit.Playwright.csprojpasses on all target frameworks (netstandard2.0, net8.0, net9.0, net10.0)CloseAsync/DisposeAsynccalls are now wrapped in try/catch with proper exception aggregation