Class: Capybara::Simulated::Node
- Inherits:
-
Driver::Node
- Object
- Driver::Node
- Capybara::Simulated::Node
show all
- Includes:
- WhitespaceNormalizer
- Defined in:
- lib/capybara/simulated/node.rb
Constant Summary
WhitespaceNormalizer::BREAKING_SPACES, WhitespaceNormalizer::EMPTY_LINES, WhitespaceNormalizer::LEADING_SPACES, WhitespaceNormalizer::LEFT_TO_RIGHT_MARK, WhitespaceNormalizer::LINE_SEPERATOR, WhitespaceNormalizer::NON_BREAKING_SPACE, WhitespaceNormalizer::PARAGRAPH_SEPERATOR, WhitespaceNormalizer::REMOVED_CHARACTERS, WhitespaceNormalizer::RIGHT_TO_LEFT_MARK, WhitespaceNormalizer::SQUEEZED_SPACES, WhitespaceNormalizer::TRAILING_SPACES, WhitespaceNormalizer::ZERO_WIDTH_SPACE
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#==(other) ⇒ Object
Both handle_id and context_gen are part of identity: after a cross-page reload the new element can land on the same handle id (JS-side counter resets per ctx) but a different generation.
-
#[](name) ⇒ Object
-
#all_text ⇒ Object
Tick the virtual clock unconditionally on the text path.
-
#checked? ⇒ Boolean
-
#click(keys = [], **opts) ⇒ Object
-
#disabled? ⇒ Boolean
-
#double_click(keys = [], **opts) ⇒ Object
-
#drag_to(target_node, **opts) ⇒ Object
-
#drop(*args) ⇒ Object
-
#find_css(query) ⇒ Object
-
#find_xpath(query) ⇒ Object
-
#hover(**_opts) ⇒ Object
-
#initialize(driver, handle) ⇒ Node
constructor
-
#inner_html ⇒ Object
Convenience accessors mirroring real browser nodes — Discourse tests reach for .native.inner_html (e.g. reviewables XSS checks); without this method .native (= self) raised NoMethodError.
-
#obscured? ⇒ Boolean
-
#outer_html ⇒ Object
-
#path ⇒ Object
-
#readonly? ⇒ Boolean
-
#rect ⇒ Object
Capybara's standard rect API.
-
#right_click(keys = [], **opts) ⇒ Object
-
#scroll_to(target = nil, arg = nil, coords = nil) ⇒ Object
Capybara's driver scroll_to contract (from Element#scroll_to): a target element + align symbol, a position symbol (:top/:bottom/:center), or an [x, y] coordinate pair.
-
#select_option ⇒ Object
-
#selected? ⇒ Boolean
-
#send_keys(*keys) ⇒ Object
-
#set(value, **_) ⇒ Object
-
#shadow_root ⇒ Object
-
#style(names = []) ⇒ Object
-
#submit(*_) ⇒ Object
-
#synchronize ⇒ Object
-
#tag_name ⇒ Object
-
#trigger(event) ⇒ Object
-
#unselect_option ⇒ Object
-
#value ⇒ Object
-
#visible? ⇒ Boolean
-
#visible_text ⇒ Object
#normalize_spacing, #normalize_visible_spacing
Constructor Details
#initialize(driver, handle) ⇒ Node
Returns a new instance of Node.
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# File 'lib/capybara/simulated/node.rb', line 12
def initialize(driver, handle)
super(driver, self)
@handle_id = handle
@browser = driver.current_browser
@initial_node = @browser.lookup_node(handle)
@context_gen = @browser.context_gen
@realm_id = @browser.current_realm_id
end
|
Instance Attribute Details
#context_gen ⇒ Object
Returns the value of attribute context_gen.
26
27
28
|
# File 'lib/capybara/simulated/node.rb', line 26
def context_gen
@context_gen
end
|
#handle_id ⇒ Object
Returns the value of attribute handle_id.
26
27
28
|
# File 'lib/capybara/simulated/node.rb', line 26
def handle_id
@handle_id
end
|
#realm_id ⇒ Object
Returns the value of attribute realm_id.
26
27
28
|
# File 'lib/capybara/simulated/node.rb', line 26
def realm_id
@realm_id
end
|
Instance Method Details
#==(other) ⇒ Object
Both handle_id and context_gen are part of identity: after a
cross-page reload the new element can land on the same handle
id (JS-side counter resets per ctx) but a different generation.
Capybara's synchronize uses old_base == @base to decide
whether reload made progress, so id-only equality would mark
a successful reload as a no-op and raise the original error.
233
234
235
236
237
238
|
# File 'lib/capybara/simulated/node.rb', line 233
def ==(other)
other.is_a?(Node) &&
other.handle_id == @handle_id &&
other.context_gen == @context_gen &&
other.realm_id == @realm_id
end
|
#[](name) ⇒ Object
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/capybara/simulated/node.rb', line 77
def [](name)
browser.tick_real_time if browser.timer_wait_elapsed? || browser.async_io_pending?
check_stale
browser.attr(handle_id, name.to_s)
end
|
#all_text ⇒ Object
Tick the virtual clock unconditionally on the text path. Unlike
Node#[] (attribute reads), the text readers are NOT preceded by
a find_css that ticks under the wall throttle: have_text /
assert_text polls .text directly against an already-found,
cached scope node, so the find loop short-circuits without
re-ticking. Gating these behind timer_wait_elapsed? therefore
stalls a pure text-poll loop's virtual clock and scheduled
setTimeouts never fire (smoke_spec virtual-clock contract).
They run ~once per poll-scope (not once per matched result like
the attribute filters the audit targeted), so they are not the
O(N) hot path and are safe to tick every call.
39
40
41
42
43
|
# File 'lib/capybara/simulated/node.rb', line 39
def all_text
browser.tick_real_time
check_stale
normalize_spacing(browser.all_text(handle_id))
end
|
#checked? ⇒ Boolean
211
|
# File 'lib/capybara/simulated/node.rb', line 211
def checked? = !!self['checked']
|
#click(keys = [], **opts) ⇒ Object
104
105
106
107
|
# File 'lib/capybara/simulated/node.rb', line 104
def click(keys = [], **opts)
check_stale
browser.click(handle_id, keys, **opts)
end
|
#disabled? ⇒ Boolean
209
|
# File 'lib/capybara/simulated/node.rb', line 209
def disabled? = browser.disabled?(handle_id)
|
#double_click(keys = [], **opts) ⇒ Object
114
115
116
117
|
# File 'lib/capybara/simulated/node.rb', line 114
def double_click(keys = [], **opts)
check_stale
browser.double_click(handle_id, keys, **opts)
end
|
#drag_to(target_node, **opts) ⇒ Object
169
170
171
172
173
174
175
|
# File 'lib/capybara/simulated/node.rb', line 169
def drag_to(target_node, **opts)
check_stale
target_node.check_stale if target_node.respond_to?(:check_stale)
target_handle = target_node.respond_to?(:handle_id) ? target_node.handle_id : target_node.native
browser.drag_to(handle_id, target_handle, **opts)
self
end
|
#drop(*args) ⇒ Object
163
164
165
166
167
|
# File 'lib/capybara/simulated/node.rb', line 163
def drop(*args)
check_stale
browser.drop(handle_id, args)
true
end
|
#find_css(query) ⇒ Object
200
201
202
|
# File 'lib/capybara/simulated/node.rb', line 200
def find_css(query)
browser.find_css(query, handle_id).map {|id| self.class.new(driver, id) }
end
|
#find_xpath(query) ⇒ Object
196
197
198
|
# File 'lib/capybara/simulated/node.rb', line 196
def find_xpath(query)
browser.find_xpath(query, handle_id).map {|id| self.class.new(driver, id) }
end
|
#hover(**_opts) ⇒ Object
119
120
121
122
123
|
# File 'lib/capybara/simulated/node.rb', line 119
def hover(**_opts)
check_stale
browser.hover(handle_id)
self
end
|
#inner_html ⇒ Object
Convenience accessors mirroring real browser nodes — Discourse
tests reach for .native.inner_html (e.g. reviewables XSS
checks); without this method .native (= self) raised
NoMethodError.
67
68
69
70
|
# File 'lib/capybara/simulated/node.rb', line 67
def inner_html
check_stale
browser.inner_html(handle_id)
end
|
#obscured? ⇒ Boolean
213
214
215
216
|
# File 'lib/capybara/simulated/node.rb', line 213
def obscured?(*)
check_stale
browser.obscured?(handle_id)
end
|
#outer_html ⇒ Object
72
73
74
75
|
# File 'lib/capybara/simulated/node.rb', line 72
def outer_html
check_stale
browser.outer_html(handle_id)
end
|
#path ⇒ Object
222
223
224
225
|
# File 'lib/capybara/simulated/node.rb', line 222
def path
check_stale
browser.node_path(handle_id)
end
|
#readonly? ⇒ Boolean
212
|
# File 'lib/capybara/simulated/node.rb', line 212
def readonly? = !!self['readonly']
|
#rect ⇒ Object
Capybara's standard rect API. No layout engine — but
The element's coarse border-box (viewport-relative), from the layout engine — backs the
spatial selectors (:above/:below/:near) and coordinate drag. Deterministic per layout
generation (memoised; only a DOM/style mutation changes it), so Discourse's
wait_for_animation — which polls element.rect[:x] twice and waits for it to stabilise —
still settles immediately when nothing is animating.
147
148
149
150
|
# File 'lib/capybara/simulated/node.rb', line 147
def rect
check_stale
browser.rect(handle_id)
end
|
#right_click(keys = [], **opts) ⇒ Object
109
110
111
112
|
# File 'lib/capybara/simulated/node.rb', line 109
def right_click(keys = [], **opts)
check_stale
browser.right_click(handle_id, keys, **opts)
end
|
Capybara's driver scroll_to contract (from Element#scroll_to): a target element + align
symbol, a position symbol (:top/:bottom/:center), or an [x, y] coordinate pair.
self is the element it was called on — the document root for a session-level scroll (routed
via find('/html')), else an element. Drives a real scroll offset in the layout engine.
129
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/capybara/simulated/node.rb', line 129
def scroll_to(target = nil, arg = nil, coords = nil)
check_stale
if target
browser.scroll_to(handle_id, target.handle_id, arg)
elsif coords
browser.scroll_to(handle_id, nil, nil, coords[0], coords[1])
elsif arg
browser.scroll_to(handle_id, nil, arg)
end
self
end
|
#select_option ⇒ Object
181
182
183
184
|
# File 'lib/capybara/simulated/node.rb', line 181
def select_option
check_stale
browser.select_option(handle_id)
end
|
#selected? ⇒ Boolean
210
|
# File 'lib/capybara/simulated/node.rb', line 210
def selected? = browser.option_selected?(handle_id)
|
#send_keys(*keys) ⇒ Object
152
153
154
155
156
|
# File 'lib/capybara/simulated/node.rb', line 152
def send_keys(*keys)
check_stale
browser.send_keys(handle_id, keys)
true
end
|
#set(value, **_) ⇒ Object
176
177
178
179
|
# File 'lib/capybara/simulated/node.rb', line 176
def set(value, **_)
check_stale
browser.set_value_with_events(handle_id, value)
end
|
#shadow_root ⇒ Object
204
205
206
207
208
|
# File 'lib/capybara/simulated/node.rb', line 204
def shadow_root
check_stale
h = browser.shadow_root_handle(handle_id)
h && self.class.new(driver, h)
end
|
#style(names = []) ⇒ Object
218
219
220
221
|
# File 'lib/capybara/simulated/node.rb', line 218
def style(names = [])
check_stale
browser.computed_style(handle_id, Array(names))
end
|
#submit(*_) ⇒ Object
191
192
193
194
|
# File 'lib/capybara/simulated/node.rb', line 191
def submit(*_)
check_stale
browser.submit_form(handle_id)
end
|
#synchronize ⇒ Object
217
|
# File 'lib/capybara/simulated/node.rb', line 217
def synchronize(*) = yield
|
#tag_name ⇒ Object
61
|
# File 'lib/capybara/simulated/node.rb', line 61
def tag_name = browser.tag_name(handle_id)
|
#trigger(event) ⇒ Object
158
159
160
161
162
|
# File 'lib/capybara/simulated/node.rb', line 158
def trigger(event)
check_stale
browser.dispatch_event(handle_id, event.to_s)
true
end
|
#unselect_option ⇒ Object
186
187
188
189
|
# File 'lib/capybara/simulated/node.rb', line 186
def unselect_option
check_stale
browser.unselect_option(handle_id)
end
|
#value ⇒ Object
51
52
53
54
|
# File 'lib/capybara/simulated/node.rb', line 51
def value
check_stale
browser.value(handle_id)
end
|
#visible? ⇒ Boolean
56
57
58
59
|
# File 'lib/capybara/simulated/node.rb', line 56
def visible?
check_stale
browser.visible?(handle_id)
end
|
#visible_text ⇒ Object
45
46
47
48
49
|
# File 'lib/capybara/simulated/node.rb', line 45
def visible_text
browser.tick_real_time
check_stale
normalize_visible_spacing(browser.visible_text(handle_id))
end
|