Implementation:Teamcapybara Capybara Edge Node
| Knowledge Sources | |
|---|---|
| Domains | Testing, Driver_Architecture |
| Last Updated | 2026-02-12 00:00 GMT |
Overview
Concrete tool for Edge-specific DOM node interaction with Chrome-Edge variant handling, provided by Capybara::Selenium::EdgeNode.
Description
Capybara::Selenium::EdgeNode inherits from Capybara::Selenium::Node and includes the Html5Drag module. It overrides several methods with Chrome-Edge variant detection, since modern Edge is Chromium-based (version >= 75) and shares many of Chrome's quirks.
The private chrome_edge? method checks whether browser_version is >= 75, indicating a Chromium-based Edge. Most method overrides are gated behind this check and fall back to super for legacy (EdgeHTML-based) Edge.
set_text applies the same React compatibility workaround as ChromeNode -- sending :space then :backspace after clearing to an empty value -- but only when running on Chrome-Edge.
set_file clears the file input value via JavaScript before calling super on Chrome-Edge, working around the WebDriver spec behavior where files are appended to multi-file inputs rather than replaced.
drop delegates to html5_drop on Chrome-Edge, falling back to super for legacy Edge.
click rescues InvalidArgumentError and provides an improved error message when the click fails on a file input element, since EdgeChrome cannot natively click file inputs.
disabled? uses a JavaScript CSS selector (:disabled, select:disabled *) on Chrome-Edge to correctly detect disabled options within disabled select elements.
select_option optimizes to a single JavaScript check for :disabled, select:disabled *, :checked on Chrome-Edge, clicking only when the option is neither disabled nor already selected.
visible? leverages the native is_element_displayed WebDriver endpoint on Chrome-Edge when available, falling back to the standard implementation if the command is unknown or native_displayed is disabled.
send_keys chunks input by emoji presence, routing emoji characters through CDP Input.insertText and non-emoji text through the standard path, identical to ChromeNode.
Usage
Automatically instantiated by the Edge driver specialization via build_node. No direct user construction required.
Code Reference
Source Location
- Repository: capybara
- File: lib/capybara/selenium/nodes/edge_node.rb
- Lines: 110
Signature
class Capybara::Selenium::EdgeNode < Capybara::Selenium::Node
include Html5Drag
def set_text(value, clear: nil, **_unused)
# @param value [String] Text value to set
# @param clear [Symbol, nil] Clear strategy (:backspace, :none, nil)
# Only applies React workaround on Chrome-Edge (version >= 75)
end
def set_file(value)
# @param value [String, Array<String>] File path(s) to attach
# Clears multi-file inputs on Chrome-Edge before calling super
end
def drop(*args)
# @param args [Array] File paths or type/data pairs for HTML5 drop
# Delegates to html5_drop on Chrome-Edge, super on legacy Edge
end
def click(*, **)
# Provides improved error message for file input clicks on EdgeChrome
end
def disabled?
# @return [Boolean] Uses JS selector on Chrome-Edge; super on legacy Edge
end
def select_option
# Optimized single-check click on Chrome-Edge
end
def visible?
# @return [Boolean] Uses native displayed endpoint on Chrome-Edge
end
def send_keys(*args)
# @param args [Array<String, Symbol>] Keys to send; emoji via CDP
end
end
Import
require 'capybara/selenium/nodes/edge_node'
# Loaded automatically by the Edge driver specialization
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| value (set_text) | String | Yes | Text value to set on the element |
| clear (set_text) | Symbol/nil | No | Clear strategy: :backspace, :none, or nil (default) |
| value (set_file) | String/Array<String> | Yes | One or more file paths to attach |
| args (drop) | Array | Yes | File paths (String) or type/data pairs (Hash) for HTML5 drop |
| args (send_keys) | Array<String, Symbol> | Yes | Key inputs; emoji characters routed through CDP Input.insertText |
Outputs
| Name | Type | Description |
|---|---|---|
| disabled? | Boolean | Whether the element is disabled (including options in disabled selects) |
| visible? | Boolean | Whether the element is displayed, using native endpoint on Chrome-Edge |
Usage Examples
Chrome-Edge Variant Detection
# The chrome_edge? check gates Chrome-specific behavior
# Edge version >= 75 is Chromium-based and uses Chrome-like workarounds
# Legacy EdgeHTML (< 75) falls back to standard Selenium::Node behavior
Text Input with React Workaround
# On Chrome-Edge, empty value triggers space+backspace for React compatibility
edge_node.set_text('')
# On legacy Edge, delegates directly to super
edge_node.set_text('hello', clear: :backspace)
File Upload
file_input = page.find('input[type="file"]')
# On Chrome-Edge, clears existing files before setting new ones
file_input.set('/path/to/file.pdf')
File Input Click Error Handling
# EdgeChrome raises InvalidArgumentError when clicking file inputs
# The error is re-raised with a descriptive message:
# "EdgeChrome can't click on file inputs."
file_input = page.find('input[type="file"]')
file_input.click # => Selenium::WebDriver::Error::InvalidArgumentError
Drag and Drop
source = page.find('#drag-source')
target = page.find('#drop-target')
# On Chrome-Edge: uses HTML5 drag emulation via Html5Drag module
# On legacy Edge: falls back to standard Selenium drag
source.drag_to(target)