Skip to content

Releases: DataficationSDK/Motus

motus-v1.0.9

14 Apr 22:27

Choose a tag to compare

Stability and reliability improvements for test execution, focusing on resilience under parallel load and graceful recovery from browser crashes.

Improvements

  • Context concurrency throttle - BrowserFixture now 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.InitializeAsync resets 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 CdpTransport and BiDiTransport now serialize WebSocket sends through a SemaphoreSlim, since ClientWebSocket does not support concurrent sends.
  • Transport receive buffer isolation - The CDP and BiDi receive loops now copy incoming WebSocket messages before deserialization so the next ReceiveAsync cannot overwrite data still referenced by in-flight JsonElement values.

Bug Fixes

  • Test setup failures after browser crash - NewContextAsync and NewPageAsync calls 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.CloseContextAsync to properly release the context throttle slot even on failure.
  • Page creation resource leaks - BrowserContext.NewPageAsync could leak Chrome targets and CDP sessions when page initialization timed out or failed partway through. Extracted a CreatePageCoreAsync helper 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, BrowserContext close/dispose, and JsHandle.DisposeAsync only caught CdpDisconnectedException. Broadened the catch filters to also handle MotusTargetClosedException, which Chrome can raise when a target is already gone.
  • ObjectDisposedException on disposed transport - Sending on a disposed CdpTransport or BiDiTransport threw a generic ObjectDisposedException. Now throws the domain-specific CdpDisconnectedException or BiDiDisconnectedException so callers that already catch those types handle the disposed case consistently.

motus-v1.0.8

10 Apr 21:45

Choose a tag to compare

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 Performance domain and PerformanceObserver API. 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(), and ToHaveInpBelowAsync() with auto-retry semantics and .Not negation support.
  • [PerformanceBudget] attribute - Apply to test methods or classes to declare metric thresholds. Budgets resolve from method attribute, class attribute, motus.config.json, or MOTUS_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-budget enables 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 BrowserHeartbeat pings Chrome every 5 seconds with a 10-second timeout to detect frozen browsers. Process.Exited event provides instant crash detection. Both mechanisms are guarded against double-firing and trigger the Disconnected event for downstream recovery.
  • IBrowser.IsHealthy property - Default interface member that checks both connection state and process liveness. For launched browsers, returns false when the process has exited even if the WebSocket has not yet detected the disconnect.
  • BrowserFixture auto-restart - When Chrome crashes or becomes unresponsive, BrowserFixture automatically disposes the dead browser and launches a replacement with retry. A SemaphoreSlim gate coordinates restart so NewContextAsync callers 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 Disconnected event. On crash, the dead browser is disposed, its capacity slot is released, and a replacement is launched if the pool has dropped below MinInstances.

Improvements

  • Performance reporter integration - Reporters implementing IPerformanceReporter receive 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's TestExecutionService into test base classes, enabling [PerformanceBudget] attribute resolution when the framework's TestContext is not injected.

Bug Fixes

  • CI test suite slowdown - Performance assertion tests blocked for 60 seconds per test because RefreshPerformanceMetricsAsync sent CDP commands with CancellationToken.None and no mock response was queued. Fixed by forwarding the assertion retry helper's cancellation token through to the CDP send, and queueing proper Runtime.evaluate responses in all affected tests. Reduced Motus.Tests.dll runtime from 16 minutes back to 2 minutes.
  • BrowserHeartbeat double-dispose - CloseAsync followed by DisposeAsync on a browser threw ObjectDisposedException because the heartbeat's CancellationTokenSource was disposed twice. Fixed with an Interlocked.CompareExchange guard on the heartbeat's DisposeAsync.
  • Tracing race condition - PumpTracingCompleteAsync used a shared _completeTcs field, allowing a cancelled old pump's cancellation handler to poison the next run's TaskCompletionSource. Fixed by passing a local TCS as a parameter.
  • CancellationTokenSource leaks - WaitForRequestAsync and WaitForResponseAsync in NetworkManager created linked CTS instances that were never disposed. Fixed with ContinueWith disposal on the returned task.
  • ScreencastService circular dependency - OnPageClose called StopAsync() 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

05 Apr 22:59

Choose a tag to compare

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 (error or warning) and a WCAG criterion reference.
  • Accessibility assertions - New page-level assertion ToPassAccessibilityAuditAsync() with configurable options to skip rules or include warnings. Locator-level assertions ToHaveAccessibleNameAsync() and ToHaveRoleAsync() for verifying individual elements.
  • Accessibility lifecycle hook - AccessibilityAuditHook runs audits automatically after navigation and optionally after actions. Register via motus.config.json or LaunchOptions.Accessibility. Supports warn mode (log violations) and enforce mode (fail on violations).
  • Accessibility CLI support - motus run --a11y warn|enforce enables 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 record now accepts --width and --height options to set the browser viewport size during recording (default 1024x768). Matches the existing pattern in motus screenshot and motus pdf.

Documentation

  • Getting Started guide - New top-level docs/getting-started.md covering 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.runsettings to 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), BrowserPool and BrowserLease (return callback, dispose idempotency, options defaults), and RecordCommand (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 CaptureFullWorkflowTrace sample 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-minutes to 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 targets net8.0) builds and runs correctly alongside net10.0 projects.

motus-v1.0.6

30 Mar 21:23

Choose a tag to compare

Feature release with major codegen improvements, trace viewer enhancements, cookie banner removal for screenshot/PDF commands, and colored console output.

New Features

  • Codegen --headed mode - Launch a visible browser with motus 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 --connect mode - Attach to an already-running browser with motus codegen --connect ws://localhost:9222 to analyze the active tab without launching a new browser instance. Works with or without URLs.
  • Codegen --scope option - 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 screenshot and motus pdf now support --hide-banners to 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 --delay options for better control over navigation and rendering. motus pdf also gained --width for 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, and aria-label when all strategies fail, verified for uniqueness before emitting
  • Implicit ARIA role inference - The role selector strategy now infers implicit roles from HTML semantics (<button> as button, <a href> as link, <input type="checkbox"> as checkbox, <select> as listbox, text inputs as textbox). This produces more stable selectors like role=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 (ApplicationStarted callback) instead of before, eliminating the need for a manual refresh on startup.

Bug Fixes

  • Null-check in MotusTestBase cleanup - TestContext.CurrentTestOutcome could throw a NullReferenceException during test cleanup if the TestContext was not initialized. Added a null-conditional check.

motus-v1.0.5

30 Mar 01:01

Choose a tag to compare

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.js and 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 a PhysicalFileProvider while 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 verbose parameter is available on RunnerHost.StartAsync for 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 ... to motus ... throughout the README since it is installed as a global tool.

motus-v1.0.1

29 Mar 14:44

Choose a tag to compare

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 IPluginContext available 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 in await using)

Test Framework Integrations

  • Motus.Testing.MSTest with shared browser across the assembly, per-test context isolation, and [Parallelize] support
  • Motus.Testing.xUnit with collection and class fixtures for parallel execution
  • Motus.Testing.NUnit with 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 PomEmitter with automatic form field grouping
  • Supports MSTest, xUnit, and NUnit output frameworks

CLI Tool (dotnet motus)

  • motus run discovers and runs tests with parallel workers, filtering, and multiple reporters (console, JUnit XML, HTML, TRX)
  • motus record launches a headed browser and emits test code from recorded interactions
  • motus install downloads browser binaries (Chromium, Chrome, Edge, Firefox) with optional revision pinning
  • motus trace show opens recorded traces in the visual runner
  • motus screenshot and motus pdf for 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)