Releases: DataficationSDK/Motus
motus-v1.0.9
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.
motus-v1.0.8
Performance testing, browser health detection, and reliability improvements across the test execution pipeline.
New Features
- Performance metrics collection - Built-in Core Web Vitals collection via CDP
Performancedomain andPerformanceObserverAPI. Collects LCP, FCP, TTFB, CLS, INP, JS heap size, DOM node count, and individual layout shift entries. Metrics are gathered automatically after each navigation when the performance hook is enabled. - Performance budget assertions - New page-level assertions
ToMeetPerformanceBudgetAsync(),ToHaveLcpBelowAsync(),ToHaveFcpBelowAsync(),ToHaveTtfbBelowAsync(),ToHaveClsBelowAsync(), andToHaveInpBelowAsync()with auto-retry semantics and.Notnegation support. [PerformanceBudget]attribute - Apply to test methods or classes to declare metric thresholds. Budgets resolve from method attribute, class attribute,motus.config.json, orMOTUS_PERFORMANCE_*environment variables. Test framework adapters (MSTest, NUnit, xUnit) resolve the attribute and propagate it to the page automatically.- Performance CLI support -
motus run --perf-budgetenables budget enforcement from the command line. All built-in reporters (Console, HTML, JUnit, TRX) surface collected metrics and budget pass/fail status. - Browser health detection - Background
BrowserHeartbeatpings Chrome every 5 seconds with a 10-second timeout to detect frozen browsers.Process.Exitedevent provides instant crash detection. Both mechanisms are guarded against double-firing and trigger theDisconnectedevent for downstream recovery. IBrowser.IsHealthyproperty - Default interface member that checks both connection state and process liveness. For launched browsers, returnsfalsewhen the process has exited even if the WebSocket has not yet detected the disconnect.- BrowserFixture auto-restart - When Chrome crashes or becomes unresponsive,
BrowserFixtureautomatically disposes the dead browser and launches a replacement with retry. ASemaphoreSlimgate coordinates restart soNewContextAsynccallers block briefly rather than racing against a dead browser. Compatible with parallel test execution across all three frameworks. - BrowserPool proactive replenishment - The browser pool subscribes to each browser's
Disconnectedevent. On crash, the dead browser is disposed, its capacity slot is released, and a replacement is launched if the pool has dropped belowMinInstances.
Improvements
- Performance reporter integration - Reporters implementing
IPerformanceReporterreceive metrics alongside budget evaluation results. The visual runner surfaces metrics in timeline marker tooltips and a dedicated Performance section in the step detail panel. - Test method name propagation -
TestMethodNameContext(AsyncLocal) carries the test method name from the visual runner'sTestExecutionServiceinto test base classes, enabling[PerformanceBudget]attribute resolution when the framework'sTestContextis not injected.
Bug Fixes
- CI test suite slowdown - Performance assertion tests blocked for 60 seconds per test because
RefreshPerformanceMetricsAsyncsent CDP commands withCancellationToken.Noneand no mock response was queued. Fixed by forwarding the assertion retry helper's cancellation token through to the CDP send, and queueing properRuntime.evaluateresponses in all affected tests. ReducedMotus.Tests.dllruntime from 16 minutes back to 2 minutes. - BrowserHeartbeat double-dispose -
CloseAsyncfollowed byDisposeAsyncon a browser threwObjectDisposedExceptionbecause the heartbeat'sCancellationTokenSourcewas disposed twice. Fixed with anInterlocked.CompareExchangeguard on the heartbeat'sDisposeAsync. - Tracing race condition -
PumpTracingCompleteAsyncused a shared_completeTcsfield, allowing a cancelled old pump's cancellation handler to poison the next run'sTaskCompletionSource. Fixed by passing a local TCS as a parameter. - CancellationTokenSource leaks -
WaitForRequestAsyncandWaitForResponseAsyncinNetworkManagercreated linked CTS instances that were never disposed. Fixed withContinueWithdisposal on the returned task. - ScreencastService circular dependency -
OnPageClosecalledStopAsync()which awaited operations that depended on the page being open. Simplified to cancel the pump and unsubscribe the event handler directly.
motus-v1.0.7
Feature release with built-in accessibility auditing, comprehensive user documentation, improved code coverage, and CI reliability fixes.
New Features
- Accessibility auditing - Built-in WCAG 2.1 audit engine with 9 rules: missing alt text, empty links, empty buttons, unlabeled form controls, missing document language, heading hierarchy, color contrast, duplicate IDs, and missing landmarks. Each rule reports a severity (
errororwarning) and a WCAG criterion reference. - Accessibility assertions - New page-level assertion
ToPassAccessibilityAuditAsync()with configurable options to skip rules or include warnings. Locator-level assertionsToHaveAccessibleNameAsync()andToHaveRoleAsync()for verifying individual elements. - Accessibility lifecycle hook -
AccessibilityAuditHookruns audits automatically after navigation and optionally after actions. Register viamotus.config.jsonorLaunchOptions.Accessibility. Supportswarnmode (log violations) andenforcemode (fail on violations). - Accessibility CLI support -
motus run --a11y warn|enforceenables auditing from the command line. Violations are surfaced through the reporter pipeline with rule ID, severity, element selector, and WCAG criterion. - Record command viewport options -
motus recordnow accepts--widthand--heightoptions to set the browser viewport size during recording (default 1024x768). Matches the existing pattern inmotus screenshotandmotus pdf.
Documentation
- Getting Started guide - New top-level
docs/getting-started.mdcovering installation, first test examples (MSTest, NUnit, xUnit), running tests, headed mode, slow motion, core concepts (locators, actions, assertions, navigation), and basic configuration. - Architecture docs - Four documents covering project structure and data flow, CDP/BiDi transport and protocol, browser lifecycle management, and selectors and assertions.
- Extensions docs - Three documents covering plugin development, all 7 extensibility interfaces with member tables, and best practices for NativeAOT compatibility and thread safety.
- Guides - Six documents covering configuration, testing frameworks, network interception, accessibility testing, recording and code generation, and Roslyn analyzers.
- Migration guides - Two documents for migrating from Playwright and Selenium with API mapping tables and conceptual differences.
Improvements
- Code coverage exclusions - Added
coverage.runsettingsto exclude source-generated code (CDP protocol domains, JSON serialization contexts) and the Blazor visual runner from coverage measurement. Overall line coverage improved from ~54% to ~80% with accurate representation of hand-written code. - New unit tests - Added tests for
BrowserFinder(Edge, Chromium, auto-detect, InstalledBinariesPath per channel),BrowserPoolandBrowserLease(return callback, dispose idempotency, options defaults), andRecordCommand(viewport option parsing and defaults). - Fill action coalescing - Increased fill debounce threshold and improved coalescing of consecutive fill actions on the same selector during recording, reducing redundant lines in generated test code.
Bug Fixes
- CI integration test hang - Fixed
CaptureFullWorkflowTracesample test failing with "Tracing has already been started" when failure-tracing was active. The test now stops any pre-existing tracing before starting its own session, preventing the process from hanging on disposal. - CI workflow timeouts - Added
timeout-minutesto the Chrome integration test step (10 min) and Motus report generation step (5 min) to prevent hung browser processes from blocking the pipeline indefinitely. - CI .NET SDK version - Added .NET 8.0 SDK to the integration job so
Motus.Samples(which targetsnet8.0) builds and runs correctly alongsidenet10.0projects.
motus-v1.0.6
Feature release with major codegen improvements, trace viewer enhancements, cookie banner removal for screenshot/PDF commands, and colored console output.
New Features
- Codegen
--headedmode - Launch a visible browser withmotus codegen --headed, navigate to any page yourself, then press Enter to analyze. Supports providing URLs upfront (navigates then waits for Enter) or no URLs (opens a blank tab for free navigation). - Codegen
--connectmode - Attach to an already-running browser withmotus codegen --connect ws://localhost:9222to analyze the active tab without launching a new browser instance. Works with or without URLs. - Codegen
--scopeoption - Limit element discovery to a specific container with a CSS selector (e.g.--scope "#login-form",--scope ".modal-dialog"). Only elements inside the scoped container are analyzed and emitted. - Cookie banner removal -
motus screenshotandmotus pdfnow support--hide-bannersto remove cookie consent, privacy, and overlay banners before capture. Targets well-known selectors (OneTrust, CookieBot, Usercentrics, generic patterns) and clears body scroll locks. - Screenshot and PDF options - Both commands gained
--timeout,--wait-until, and--delayoptions for better control over navigation and rendering.motus pdfalso gained--widthfor viewport control. - Colored console reporter - Test results now display with ANSI color codes (green for pass, red for fail, gray for duration). Colors are automatically disabled when output is redirected.
Improvements
- Codegen selector generation - Significantly improved selector hit rate through three changes:
- Element handles are now stored at crawl time (
window.__mtusElements), preventing stale references when the DOM mutates between discovery and resolution - Per-strategy error handling prevents one slow or failing strategy from blocking all remaining elements
- Attribute-based CSS fallback generates selectors from
name,placeholder,href,type, andaria-labelwhen all strategies fail, verified for uniqueness before emitting
- Element handles are now stored at crawl time (
- Implicit ARIA role inference - The role selector strategy now infers implicit roles from HTML semantics (
<button>asbutton,<a href>aslink,<input type="checkbox">ascheckbox,<select>aslistbox, text inputs astextbox). This produces more stable selectors likerole=button[name="Submit"]instead of falling through to text or CSS. - Trace viewer - Rewrote the trace viewer service to extract real timestamps, durations, and human-readable action labels from CDP trace events. Screenshots are aligned to timeline events via binary search. HAR network requests are loaded and matched to events by time window. The viewer now filters to significant events only.
- Trace viewer layout - The sidebar and test explorer are hidden in trace mode since there are no tests to discover. The toolbar shows the trace filename and event count instead of run controls.
- Browser launch timing - The visual runner now opens the browser after the server is fully listening (
ApplicationStartedcallback) instead of before, eliminating the need for a manual refresh on startup.
Bug Fixes
- Null-check in MotusTestBase cleanup -
TestContext.CurrentTestOutcomecould throw aNullReferenceExceptionduring test cleanup if theTestContextwas not initialized. Added a null-conditional check.
motus-v1.0.5
Patch release fixing the visual runner when installed as a global tool, plus CLI and logging improvements.
Bug Fixes
- Fixed static assets 404 in global tool install - The visual runner (
motus run --visual,motus trace show) returned 404 for_framework/blazor.web.jsand other static resources when Motus.Cli was installed as a dotnet global tool. The tool package now bundles wwwroot content (app.css,screencast.js, scoped CSS) alongside the static web assets manifest. At startup, the runner detects whether the manifest's build-time paths are valid; if not (global tool install from CI), it falls back to Production mode and serves the bundled wwwroot via aPhysicalFileProviderwhile letting the ASP.NET Core framework handle_framework/files through its standard pipeline.
Improvements
- Suppressed ASP.NET Core log noise - The visual runner no longer prints info/warn log messages from Kestrel and the request pipeline. Only errors are shown by default. A
verboseparameter is available onRunnerHost.StartAsyncfor diagnostics. - Added shutdown hint - The visual runner now prints
Press Ctrl+C to stop.after the startup URL. - Fixed CLI command references in README - Changed
dotnet motus ...tomotus ...throughout the README since it is installed as a global tool.
motus-v1.0.1
Initial release of Motus, an extensible browser automation and testing framework for .NET. Motus communicates directly with browsers over WebSocket using source-generated protocol bindings, with no Node.js dependency.
Browser Automation Engine
- Direct WebSocket communication with Chromium over CDP and Firefox over WebDriver BiDi
- Source-generated protocol bindings via Roslyn incremental generator for NativeAOT compatibility
- Full Page API: navigation, locators (
GetByRole,GetByText,GetByLabel,GetByTestId, etc.), JavaScript evaluation, screenshots, PDF generation, and file downloads - Network interception and routing with request/response inspection
- Browser contexts with isolated cookies, cache, storage, geolocation, and permissions
- Keyboard, mouse, and touchscreen input simulation
- Tracing, HAR export, and video recording
Plugin System
- All built-in features (selector strategies, wait conditions, lifecycle hooks, reporters) are registered through the same
IPluginContextavailable to third-party authors [MotusPlugin]attribute with source-generated discovery via module initializer- Plugin interfaces:
ISelectorStrategy,IWaitCondition,ILifecycleHook,IReporter
Roslyn Analyzers
- Seven compile-time diagnostics (MOT001-MOT007) catching common automation mistakes: non-awaited async calls, hardcoded delays, fragile selectors, missing disposal, unused locators, deprecated selectors, and navigation without wait
- Automated code fixes for MOT001 (add
await), MOT002 (replace delay with wait), and MOT004 (wrap inawait using)
Test Framework Integrations
Motus.Testing.MSTestwith shared browser across the assembly, per-test context isolation, and[Parallelize]supportMotus.Testing.xUnitwith collection and class fixtures for parallel executionMotus.Testing.NUnitwith per-fixture browser and[Parallelizable(ParallelScope.All)]support- Automatic failure tracing captures a trace ZIP on test failure (MSTest and NUnit; manual in xUnit)
- Browser pool (
IBrowserPool) for concurrent test execution with configurable worker count
Test Recorder
- Record browser interactions in a headed session and emit compilable C# test code
- Selector inference ranks test IDs and accessible roles over fragile CSS paths
- Page Object Model generation via
PomEmitterwith automatic form field grouping - Supports MSTest, xUnit, and NUnit output frameworks
CLI Tool (dotnet motus)
motus rundiscovers and runs tests with parallel workers, filtering, and multiple reporters (console, JUnit XML, HTML, TRX)motus recordlaunches a headed browser and emits test code from recorded interactionsmotus installdownloads browser binaries (Chromium, Chrome, Edge, Firefox) with optional revision pinningmotus trace showopens recorded traces in the visual runnermotus screenshotandmotus pdffor quick page capture- Interactive visual runner with timeline, step debugging, and visual regression UI
Packages
| Package | Description |
|---|---|
Motus |
Core automation engine |
Motus.Abstractions |
Plugin interfaces and browser API types |
Motus.Codegen |
Roslyn source generator for CDP bindings and plugin discovery |
Motus.Analyzers |
Compile-time diagnostics and code fixes |
Motus.Recorder |
Interaction recorder and code emitter |
Motus.Testing |
Shared browser fixture (framework-agnostic) |
Motus.Testing.MSTest |
MSTest integration |
Motus.Testing.xUnit |
xUnit integration |
Motus.Testing.NUnit |
NUnit integration |
Motus.Cli |
Command-line tool (installed via dotnet tool install -g Motus.Cli) |