Implementation:Teamcapybara Capybara WhitespaceNormalizer
| Knowledge Sources | |
|---|---|
| Domains | Testing, Text Processing |
| Last Updated | 2026-02-12 06:00 GMT |
Overview
Capybara::Node::WhitespaceNormalizer provides text normalization utilities for handling Unicode whitespace, directional marks, and spacing inconsistencies in element text content.
Description
The Capybara::Node::WhitespaceNormalizer module contains two public methods and a comprehensive set of constants that define how Capybara normalizes text extracted from DOM elements. Browser-rendered text often contains a mix of Unicode whitespace characters, zero-width markers, and directional marks that can cause naive string comparisons to fail unexpectedly. This module provides a consistent normalization pipeline to handle these cases.
The module defines several important constants:
- NON_BREAKING_SPACE (
\u00a0) -- Unicode non-breaking space (equivalent to ) - LINE_SEPERATOR (
\u2028) -- Unicode line separator - PARAGRAPH_SEPERATOR (
\u2029) -- Unicode paragraph separator - BREAKING_SPACES -- Character class matching all Unicode whitespace except non-breaking spaces
- SQUEEZED_SPACES -- Characters that should be translated to plain spaces: space, newline, form feed, tab, vertical tab, line separator, and paragraph separator
- LEADING_SPACES -- Regex matching breaking whitespace at the start of text
- TRAILING_SPACES -- Regex matching breaking whitespace at the end of text
- ZERO_WIDTH_SPACE (
\u200b) -- Invisible space character to be removed - LEFT_TO_RIGHT_MARK (
\u200e) -- Directional mark to be removed - RIGHT_TO_LEFT_MARK (
\u200f) -- Directional mark to be removed - REMOVED_CHARACTERS -- Combined string of zero-width space and directional marks for deletion
- EMPTY_LINES -- Regex matching multiple empty or whitespace-only lines
The two public methods apply these constants in different pipelines:
normalize_spacing performs full normalization: it deletes invisible characters (zero-width space, directional marks), translates all squeezable whitespace to plain spaces, squeezes consecutive spaces, strips leading/trailing breaking whitespace, and finally converts non-breaking spaces to regular spaces.
normalize_visible_spacing performs a lighter normalization intended for visible text: it squeezes consecutive spaces, collapses empty lines to single newlines, strips leading/trailing breaking whitespace, and converts non-breaking spaces to regular spaces. This variant preserves meaningful line breaks while still cleaning up visual noise.
Usage
Use this module when comparing or asserting on text content extracted from browser elements. It is used internally by Capybara's text retrieval methods (e.g., Element#text with normalize_ws: true) to ensure that text comparisons in matchers like has_text? behave consistently across different browsers and rendering engines. The module can also be included directly in custom classes that need the same normalization behavior.
Code Reference
Source Location
- Repository: Teamcapybara_Capybara
- File: lib/capybara/node/whitespace_normalizer.rb (81 lines)
Signature
module Capybara
module Node
module WhitespaceNormalizer
NON_BREAKING_SPACE = "\u00a0"
LINE_SEPERATOR = "\u2028"
PARAGRAPH_SEPERATOR = "\u2029"
BREAKING_SPACES = "[[:space:]&&[^\u00a0]]"
SQUEEZED_SPACES = " \n\f\t\v\u2028\u2029"
LEADING_SPACES = /\A[[:space:]&&[^\u00a0]]+/
TRAILING_SPACES = /[[:space:]&&[^\u00a0]]+\z/
ZERO_WIDTH_SPACE = "\u200b"
LEFT_TO_RIGHT_MARK = "\u200e"
RIGHT_TO_LEFT_MARK = "\u200f"
REMOVED_CHARACTERS = "\u200b\u200e\u200f"
EMPTY_LINES = /[\ \n]*\n[\ \n]*/
def normalize_spacing(text)
def normalize_visible_spacing(text)
end
end
end
Import
require 'capybara/node/whitespace_normalizer'
I/O Contract
| Method | Input | Output | Description |
|---|---|---|---|
normalize_spacing(text) |
String containing raw element text | String | Full normalization: deletes zero-width/directional characters, translates whitespace to spaces, squeezes, strips, and converts NBSP to space |
normalize_visible_spacing(text) |
String containing visible element text | String | Light normalization: squeezes spaces, collapses empty lines, strips, and converts NBSP to space |
Normalization Pipeline: normalize_spacing
| Step | Operation | Method |
|---|---|---|
| 1 | Delete zero-width space, LTR mark, RTL mark | .delete(REMOVED_CHARACTERS)
|
| 2 | Translate squeezable whitespace to plain space | .tr(SQUEEZED_SPACES, ' ')
|
| 3 | Squeeze consecutive spaces | .squeeze(' ')
|
| 4 | Remove leading breaking whitespace | .sub(LEADING_SPACES, )
|
| 5 | Remove trailing breaking whitespace | .sub(TRAILING_SPACES, )
|
| 6 | Convert non-breaking spaces to regular spaces | .tr(NON_BREAKING_SPACE, ' ')
|
Normalization Pipeline: normalize_visible_spacing
| Step | Operation | Method |
|---|---|---|
| 1 | Squeeze consecutive spaces | .squeeze(' ')
|
| 2 | Collapse empty lines to single newline | .gsub(EMPTY_LINES, "\n")
|
| 3 | Remove leading breaking whitespace | .sub(LEADING_SPACES, )
|
| 4 | Remove trailing breaking whitespace | .sub(TRAILING_SPACES, )
|
| 5 | Convert non-breaking spaces to regular spaces | .tr(NON_BREAKING_SPACE, ' ')
|
Usage Examples
include Capybara::Node::WhitespaceNormalizer
# Basic whitespace normalization
normalize_spacing(" Hello World ")
# => "Hello World"
# Handles tabs, newlines, and form feeds
normalize_spacing("Hello\t\n\f World")
# => "Hello World"
# Removes zero-width spaces and directional marks
normalize_spacing("Hello\u200bWorld\u200e!")
# => "HelloWorld!"
# Converts non-breaking spaces to regular spaces
normalize_spacing("Hello\u00a0World")
# => "Hello World"
# Handles Unicode line/paragraph separators
normalize_spacing("Line1\u2028Line2\u2029Line3")
# => "Line1 Line2 Line3"
# normalize_visible_spacing preserves meaningful line breaks
normalize_visible_spacing("Hello\nWorld")
# => "Hello\nWorld"
# But collapses multiple empty lines
normalize_visible_spacing("Hello\n\n\nWorld")
# => "Hello\nWorld"
# Squeezes spaces within lines
normalize_visible_spacing("Hello World")
# => "Hello World"
Related Pages
- Teamcapybara_Capybara_Node_Element -- Element class that uses this normalizer for text retrieval
- Teamcapybara_Capybara_Node_Simple -- Simple node that applies whitespace normalization in its
textmethod - Teamcapybara_Capybara_Node_Matchers -- Matchers that rely on normalized text for assertions
- Teamcapybara_Capybara_Queries_TextQuery -- Text query that uses normalization for text matching
- Teamcapybara_Capybara_Node_Document -- Document class whose
textmethod supports thenormalize_wsoption