Implementation:Teamcapybara Capybara GetAttribute Atom
| Knowledge Sources | |
|---|---|
| Domains | Testing, Driver_Architecture |
| Last Updated | 2026-02-12 00:00 GMT |
Overview
JavaScript atom providing cross-browser attribute retrieval via get(element, attribute), used by Selenium driver internals to normalize attribute access across different DOM element types and properties.
Description
The file defines an IIFE (Immediately Invoked Function Expression) that returns a get(element, attribute) function. This atom handles the many inconsistencies in how browsers expose HTML attributes versus DOM properties, providing a unified interface for Capybara's Selenium driver.
The retrieval logic follows a priority cascade:
- Style attributes -- Returns element.style.cssText if the style object is not a string.
- Selected/checked state -- For selectable elements (<option>, <input type="checkbox">, <input type="radio">), returns "true" or null based on the element's checked/selected property.
- Link and image URLs -- For <a href> and <img src>, retrieves the attribute value first, then resolves to the full URL via the DOM property if the attribute exists.
- Spellcheck -- Special handling that coerces the attribute to "true" or "false" strings, falling back to the property value coerced to string.
- Boolean properties -- For the 49 known boolean HTML attributes (defined in BOOLEAN_PROPERTIES), returns "true" if the attribute is present or the property is truthy, null otherwise.
- General fallback -- Tries the DOM property first (using PROPERTY_ALIASES for remapping, e.g., "class" to "className"), falls back to getAttributeNode if the property is null, an object, or a function.
All return values are converted to strings via .toString(), with null returned for absent attributes.
Usage
Injected and executed in the browser context by Capybara's Selenium driver via execute_script to retrieve element attributes reliably.
Code Reference
Source Location
- Repository: capybara
- File: lib/capybara/selenium/atoms/src/getAttribute.js (161 lines)
Signature
// IIFE returning the get function
(function(){
// Constants
var BOOLEAN_PROPERTIES = [ /* 49 boolean attribute names */ ];
var PROPERTY_ALIASES = { "class": "className", "readonly": "readOnly" };
// Internal helpers
function isSelectable(element) { /* checks OPTION, INPUT[checkbox/radio] */ }
function isSelected(element) { /* reads selected or checked property */ }
function getAttributeValue(element, name) { /* reads via getAttributeNode */ }
// Public API
return function get(element, attribute) {
// @param {Element} element - DOM element to query
// @param {string} attribute - Attribute name to retrieve
// @return {string|null} Attribute value as string, or null if absent
};
})()
Import
// Not imported directly; loaded and executed via Selenium's execute_script
// The atom is typically read from file and injected into the browser context
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| element | Element | Yes | DOM element to retrieve the attribute from |
| attribute | String | Yes | Name of the attribute to retrieve (case-insensitive) |
Outputs
| Name | Type | Description |
|---|---|---|
| value | String/null | Attribute value as a string, or null if the attribute is absent |
Internal Details
BOOLEAN_PROPERTIES Constant
49 HTML boolean attribute names that receive special true/null handling:
var BOOLEAN_PROPERTIES = [
"allowfullscreen", "allowpaymentrequest", "allowusermedia", "async",
"autofocus", "autoplay", "checked", "compact", "complete", "controls",
"declare", "default", "defaultchecked", "defaultselected", "defer",
"disabled", "ended", "formnovalidate", "hidden", "indeterminate",
"iscontenteditable", "ismap", "itemscope", "loop", "multiple", "muted",
"nohref", "nomodule", "noresize", "noshade", "novalidate", "nowrap",
"open", "paused", "playsinline", "pubdate", "readonly", "required",
"reversed", "scoped", "seamless", "seeking", "selected", "truespeed",
"typemustmatch", "willvalidate"
];
PROPERTY_ALIASES Constant
Maps HTML attribute names to their corresponding DOM property names:
var PROPERTY_ALIASES = {
"class": "className",
"readonly": "readOnly"
};
Attribute Resolution Priority
| Priority | Condition | Return Value |
|---|---|---|
| 1 | attribute == "style" | element.style.cssText |
| 2 | selectable element + "selected"/"checked" | "true" or null |
| 3 | <img src> or <a href> | Full URL via DOM property (if attribute exists) |
| 4 | attribute == "spellcheck" | Coerced string "true" / "false" or property + "" |
| 5 | Boolean property | "true" if present/truthy, null otherwise |
| 6 | General fallback | DOM property (via alias), or getAttributeNode value |