CDP Input Coalescing for Consistent Hover Interaction
Configure bounded per-context batching for plain CDP mouse hover movement while keeping clicks, drag, wheel, keyboard, touch, and pen input unchanged.
Want the structured docs for Getting Started?
This article lives in the editorial library. For step-by-step setup, reference material, and ongoing updates, jump into the docs section.
CDP clients commonly send mouse movement one command at a time. A client sends a point, waits for completion, then sends the next point. That sequence is reliable, but it can make a fast automated hover look different from a stream of native pointer movement. Pages can observe the resulting event timing and the way movement reaches the browser event queue.
BotBrowser provides a context-level option for workloads that need a more consistent hover path: --bot-cdp-coalesce. The option is off by default. When enabled for a BrowserContext, BotBrowser accepts a short run of plain mouse hover moves, keeps them in order, and forwards them as a small serial batch. The browser engine remains responsible for the final page events and any native event coalescing.
Start with the default
Most browser automation does not need a special input setting. Leave the option off when a workload uses clicks, forms, keyboard entry, scrolling, drag and drop, touch gestures, or pen input. The default preserves the normal CDP completion behavior and avoids changing a workflow that already meets its interaction requirements.
Enable the option only for a context that sends frequent plain mouse hover movement through CDP and needs the browser to receive those points with a little overlap. A tooltip review, a menu that opens as the pointer approaches, a hover card, or a pointer-sensitive desktop interface are typical examples. The setting belongs to the context so one workload can use it while another context in the same browser keeps the default.
The option does not make a pointer path random, and it does not create movement points. Your client still chooses the points and their coordinates. BotBrowser only controls how accepted hover moves are forwarded during a short input window. The last point remains the final position seen by the page.
Configure one BrowserContext
Set --bot-cdp-coalesce in the context configuration surface provided by your BotBrowser launcher. Apply the setting before the context creates its first page or worker. Keep the value with the context's browser version, profile selection, and automation package version so a later validation run can reproduce the same input policy.
The bare flag enables the behavior. An explicit --bot-cdp-coalesce=true value also enables it. Use --bot-cdp-coalesce=false when a deployment template may add the flag and a particular context must retain the default. Treat the value as context identity configuration. Do not plan to switch it while a context is already serving pages.
When a process creates several contexts, give each context a deliberate setting. A context with the option enabled does not turn it on for its siblings. A new context must receive its own value. This separation lets teams compare the same journey with and without the behavior without starting unrelated browser processes.
A launch wrapper should make the setting visible in its configuration rather than hiding it in page code. Keep the flag close to the profile and context declaration, and record whether it is on or off in the run metadata. Do not use page scripts to imitate the feature. Page scripts cannot control when a CDP command completes or how the browser input queue receives the event.
What gets coalesced
Only plain mouse hover movement enters the context batch. In practical terms, the pointer has no button pressed, it is not in a relative-motion mode, and the event is an ordinary mouse move. The option covers the movement used to approach a target, inspect a hover state, or travel across a desktop interface.
The following input remains outside the batch:
- Mouse button down and up events.
- Active drag movement and drag transitions.
- Wheel input.
- Keyboard input and text entry.
- Touch input.
- Pen input.
- Relative mouse motion.
Those boundaries protect the meaning of input that carries a discrete action or a different device type. A click should retain its normal button state and completion behavior. A drag should keep its transition order. A wheel event should keep its delta and timing semantics. The coalescing option does not alter those paths.
Modifiers and button state matter. A movement that arrives while a button is held is part of a drag or another active pointer action, not a plain hover. It stays on the normal path. This rule also prevents a hover batch from crossing a boundary between pointing at a control and acting on that control.
How the batch is delivered
The context accepts a short sequence of eligible hover moves and forwards the accepted points in their original order. The batch is bounded, so a stalled page or an unusually long movement stream cannot accumulate an unlimited queue. A batch is also short-lived, which keeps the setting focused on high-frequency movement instead of adding general input buffering.
Each CDP command keeps one completion result. Accepted hover commands can complete when the context has accepted them for forwarding. The page still receives the corresponding movement through the browser input path. Non-hover input continues to use the normal browser acknowledgement path. When another input type needs to cross the same path, pending hover movement is allowed to clear first so the visible order remains meaningful.
The browser engine decides how the delivered points become page events. It may expose a main event and a list of coalesced children when its event scheduling combines nearby movement. BotBrowser does not invent child events, rewrite their timestamps, or replace the final coordinate. The observable result therefore remains tied to browser event handling, while the context option supplies the overlap that serial CDP calls otherwise lack.
Exact event counts can vary with browser scheduling, page work, host load, and the client stream. Do not write a test that expects a fixed number of page events. Test the user-visible result, the order of actions, callback completion, and the final pointer position.
Serial CDP calls and page behavior
Serial calls are common in Puppeteer and Playwright integrations because each call is awaited before the next one starts. This is a useful completion contract for clicks and other discrete actions. For a long hover path, however, waiting after every point prevents several ordinary moves from being present in the browser queue at the same time.
With the context option enabled, the client can keep its serial command style. The context accepts a short group of plain hover moves and forwards that group in order. The caller does not need to generate a second path, add random delays, or inject page-side pointer events. The existing coordinates and the existing control flow remain the source of the interaction.
The change is about delivery, not trajectory quality. A sparse path still looks sparse. A path with a sudden jump still contains that jump. If a page needs a specific target sequence, improve the caller's coordinates and timing separately, then validate the result with the context option that the deployment will use.
The same distinction applies to application logic. A tooltip that opens only after a dwell may still need a dwell. A menu that requires the pointer to cross a particular region still needs that region in the path. Coalescing helps the browser receive a dense hover stream in a browser-like queue; it does not replace the interaction rules of the application.
Keep actions separate from movement
Use a hover step to reach a control, then use the normal click step to activate it. Do not rely on hover coalescing to carry a button transition. For drag and drop, keep the complete drag sequence on the supported drag path and verify the drop result separately.
This separation makes failures easier to read. If a tooltip does not appear, inspect the hover path, target geometry, and page state. If a click does not activate, inspect focus, hit testing, and the click sequence. If a drag does not complete, inspect the drag source, destination, and application acceptance. One setting should not become a catch-all explanation for every pointer issue.
For a page that uses hover to reveal a button, validate both states: the reveal occurs after the pointer arrives, and the button accepts a normal click afterward. Record the context flag with the run. A later operator can then distinguish an input delivery change from a selector or layout change.
Context isolation and lifecycle
The option is scoped to a BrowserContext. Context A can enable it while Context B remains off, even when both run under one browser process. The setting does not leak into another target, page, worker, or newly created context.
Close a context when its work ends, as usual. If a page or target is replaced during a movement stream, the old movement should not continue into the replacement target. Start a fresh journey with the new page state and keep the same context policy only when that is part of the intended workflow.
Navigation is another useful boundary for validation. Do not assume that a hover started on one document should explain pointer behavior on a replacement document. Wait for the new page to be ready, then run the movement required by the new UI. The context option preserves ordering within its input path; it does not preserve application state across navigation.
When a context is recreated, apply the option again. A process-level template may make the desired value easy to repeat, but the behavior remains a per-context choice. This is especially important for systems that reuse a browser process for separate accounts, tenants, or authorized test sessions.
A practical validation run
Use a small page or an approved test route with a tooltip, hover menu, or hover card. The route should expose a visible state change after the pointer reaches the target. The result should be something an operator can confirm from the application.
Run the same journey twice:
- Create a context with the option off.
- Move through the target path with the same client and coordinates.
- Record whether the hover state appeared and whether the final pointer position reached the target.
- Create a separate context with the option on.
- Repeat the same path and record the same visible outcomes.
Keep the browser release, profile, viewport, page state, client package, and coordinate list constant. Change one variable at a time. The exact number of page events is not a stable acceptance criterion because the browser controls event scheduling.
For a production workflow, add a click after the hover state appears, then verify the resulting page state. Add one control that does not depend on hover, such as a form field or a regular button, to confirm that the broader journey still follows its normal input path. Include a drag, wheel, touch, or pen check only when the workload actually uses that input.
Success means the required hover state is reachable, the action order is correct, each command reaches one completion result, and the final coordinate is not lost. It does not mean that every run exposes the same coalesced list or the same page event count.
Example operating policy
An approved desktop review flow can use the following policy:
- Contexts that inspect hover menus enable
--bot-cdp-coalescebefore their first page. - Contexts that test clicks, forms, keyboard navigation, or drag and drop leave it off unless the same run also has a documented hover requirement.
- Shared run code records the setting with the browser and profile versions.
- The flow validates the hover result and then validates the click or drag result as a separate step.
- A context replacement starts with an explicit setting and a fresh page-state check.
This policy keeps the option narrow. It also prevents a test suite from silently changing its input contract when a shared launch template changes. Explicit false values are useful in templates that serve both kinds of context.
Compatibility notes
The option affects CDP-delivered plain mouse hover movement. It does not alter browser identity settings, network routing, cookies, storage, permissions, viewport configuration, or profile data. Those concerns remain in their existing configuration surfaces.
The setting is useful where browser interaction consistency is part of a privacy review, an approved compatibility test, or a repeatable application workflow. It is not a guarantee that every operating system, page, or browser load will produce the same event grouping. Native event scheduling remains variable by its nature.
Mobile and touch journeys should be evaluated with touch input and a mobile viewport. Do not enable a mouse-hover setting as a substitute for a touch test. Pen interfaces should use pen input. Relative-motion applications should use their normal input path.
If a client library reports a completion before a visible hover state appears, wait for the page state you actually need. CDP command completion and application readiness are separate conditions. Use the application's visible signal, a supported page assertion, or a bounded readiness wait that belongs to the workflow.
Troubleshooting
The option has no visible effect. Confirm that the context received the flag before its first page, that the movement is plain mouse hover movement, and that the page actually uses hover state. A click, drag, wheel, touch, pen, or relative-motion sequence is outside the option's scope.
A drag changed behavior after enabling the option. Separate the hover approach from the drag sequence and start the drag through the normal path. The option should not carry active drag movement.
The visible event count changed between runs. That is expected when browser scheduling or page load differs. Compare the reachable hover state, action order, command completions, and final coordinate instead of one exact count.
Two contexts behave differently. Check each context's explicit value, profile and browser version, viewport, page state, and client coordinate list. The setting is isolated per context and does not repair differences in those other inputs.
A page still feels too slow. Coalescing cannot fix a sparse path, a heavy page, a slow selector, or an application dwell requirement. Measure the journey at the page level, then adjust the relevant step without changing unrelated input types.
Keep the setting explicit
Record the observable contract
An input policy is easier to operate when its expected result is written next to the run configuration. Record the context value, browser release, profile reference, viewport, page route, and client library version as ordinary deployment metadata. Keep the record free of page content and credentials. The purpose is to explain why two authorized checks used different input policies, not to collect a hidden interaction trace.
During review, compare outcomes that a user can see: the hover target becomes available, the pointer reaches the intended final position, the next action occurs in order, and the command caller receives its completion. A run that differs only in page event grouping can still satisfy the workflow. When the visible result differs, inspect page readiness and target geometry before changing the coalescing setting. This keeps the setting accountable without turning a normal compatibility check into a claim about every browser or operating system.
--bot-cdp-coalesce gives a deployment a clear choice for one narrow interaction class. The default remains off. Enable it for a context that sends dense plain mouse hover movement and benefits from short serial batching. Keep other input types on their standard paths, validate the visible result, and record the value with the rest of the context configuration.
That arrangement keeps browser interaction predictable for operators and keeps privacy validation focused on observable behavior. The browser engine remains the source of final event semantics, while the context controls whether serial hover delivery may form a short, ordered batch.
Record a regression comparison
Keep one compact run record for every comparison. Include the browser release, profile name or approved profile identifier, viewport, client library version, context setting, page route, coordinate list revision, and the time of the run. Do not store account content or page data that the workflow does not need. The record should let another operator recreate the same journey without guessing which context policy was active.
Compare an enabled context with a separate disabled context under the same starting page state. Note whether the target became visible, whether the pointer reached the intended final coordinate, whether the follow-up action worked, and whether every CDP command completed once. If the page uses a hover menu, record the menu state before the click and the resulting destination after the click. If it uses a tooltip, record its visible appearance and disappearance as part of the journey.
Keep the comparison tied to one browser and profile pair at a time. When a browser release, profile, viewport, client package, or page revision changes, create a new baseline instead of treating the old result as a direct comparison. This keeps a regression report useful when a difference comes from the application or environment rather than input delivery.
Review event counts only as supporting information. Browser scheduling can produce different grouping across otherwise similar runs, so a changed count does not by itself show a regression. Escalate a comparison when the visible hover state becomes unreachable, the action order changes, a command lacks its completion result, or the final coordinate is wrong. Preserve the run record and the visible page result together so the next investigation starts from the same evidence.
Related Articles
Take BotBrowser from research to production
The guides cover the model first, then move into cross-platform validation, isolated contexts, and scale-ready browser deployment.