motus-v1.0.9
·
11 commits
to main
since this release
Stability and reliability improvements for test execution, focusing on resilience under parallel load and graceful recovery from browser crashes.
Improvements
- Context concurrency throttle -
BrowserFixturenow limits concurrent browser contexts to four via a static semaphore, preventing Chrome from becoming unresponsive when too many renderer processes compete for resources during parallel test runs. - Fixture reuse support -
BrowserFixture.InitializeAsyncresets disposed state and the restart semaphore so the fixture can be reused across consecutive runs (e.g. clicking Run All a second time in the visual runner). - Transport send serialization - Both
CdpTransportandBiDiTransportnow serialize WebSocket sends through aSemaphoreSlim, sinceClientWebSocketdoes not support concurrent sends. - Transport receive buffer isolation - The CDP and BiDi receive loops now copy incoming WebSocket messages before deserialization so the next
ReceiveAsynccannot overwrite data still referenced by in-flightJsonElementvalues.
Bug Fixes
- Test setup failures after browser crash -
NewContextAsyncandNewPageAsynccalls in test setup could fail if Chrome was still restarting from a previous crash. Added retry loops (up to three attempts with backoff) in the MSTest and NUnit test bases to ride through the restart window. - Cleanup exceptions masking test failures - Test teardown in both MSTest and NUnit now wraps tracing stop and context close in a try/catch so a crashed browser does not throw during cleanup and mask the original test failure. Teardown routes through the new
BrowserFixture.CloseContextAsyncto properly release the context throttle slot even on failure. - Page creation resource leaks -
BrowserContext.NewPageAsynccould leak Chrome targets and CDP sessions when page initialization timed out or failed partway through. Extracted aCreatePageCoreAsynchelper with a 10-second initialization timeout and a catch block that disposes the page, removes the session, and closes the target on any failure. - MotusTargetClosedException not caught during shutdown -
Browser.CloseAsync,BrowserContextclose/dispose, andJsHandle.DisposeAsynconly caughtCdpDisconnectedException. Broadened the catch filters to also handleMotusTargetClosedException, which Chrome can raise when a target is already gone. - ObjectDisposedException on disposed transport - Sending on a disposed
CdpTransportorBiDiTransportthrew a genericObjectDisposedException. Now throws the domain-specificCdpDisconnectedExceptionorBiDiDisconnectedExceptionso callers that already catch those types handle the disposed case consistently.