Class: Dommy::Rack::Session
- Inherits:
-
Object
- Object
- Dommy::Rack::Session
- Defined in:
- lib/dommy/rack/session.rb
Overview
A single browser-like session over a Rack application. Owns the current URL, document, cookie jar, persistent header store, and history; delegates URL/redirect logic to Navigation and form data collection to FormSubmission.
Defined Under Namespace
Classes: Config
Constant Summary collapse
- DEFAULT_ACCEPT =
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Instance Attribute Summary collapse
-
#history ⇒ Object
readonly
Returns the value of attribute history.
-
#last_request ⇒ Object
readonly
Returns the value of attribute last_request.
-
#last_response ⇒ Object
readonly
Returns the value of attribute last_response.
Instance Method Summary collapse
- #all_css(selector) ⇒ Object
- #all_xpath(xpath) ⇒ Object
-
#apply_navigation_response(response, final_url, push_history: true) ⇒ Object
Apply a final navigation response: update last_response, current_url, the document (HTML only), and the history stack.
-
#at_css(selector) ⇒ Object
— DOM query helpers (delegate to the document) —.
- #at_xpath(xpath) ⇒ Object
- #attach_file(locator, path) ⇒ Object
-
#authorization_bearer(token) ⇒ Object
Bearer-token auth: sets a persistent Authorization header.
- #back ⇒ Object
-
#basic_auth(user, password) ⇒ Object
HTTP Basic auth: sets a persistent Authorization header.
- #body ⇒ Object
- #check(locator) ⇒ Object
- #choose(locator) ⇒ Object
- #clear_cookies ⇒ Object
-
#click_button(locator) ⇒ Object
— Form submission —.
-
#click_link(locator) ⇒ Object
— Link navigation —.
- #click_link_element(element) ⇒ Object
- #client_error? ⇒ Boolean
- #config ⇒ Object
-
#cookies ⇒ Object
— Cookie public API —.
- #current_host ⇒ Object
- #current_path ⇒ Object
-
#current_url ⇒ Object
— Current page state —.
-
#default_headers ⇒ Object
A copy of the headers currently sent on every request.
-
#default_host ⇒ Object
— Config readers used by collaborators —.
- #delete(path, params: nil, body: nil, headers: {}) ⇒ Object
- #delete_header(name) ⇒ Object
- #delete_json(path, data, headers: {}) ⇒ Object
- #document ⇒ Object
- #enforce_same_origin? ⇒ Boolean
-
#fetch(url, method: "GET", headers: {}, body: nil, params: nil, redirect: :follow) ⇒ Object
— Fetch API (returns Response; does NOT change document or history) —.
-
#fill_in(locator, with:) ⇒ Object
Form field setting delegates to FieldInteractor (DOM mutation only; a subsequent submit is what turns into a navigation).
- #follow_meta_refresh? ⇒ Boolean
- #follow_redirects? ⇒ Boolean
- #forward ⇒ Object
-
#get(path, headers: {}) ⇒ Object
— Basic request API (navigates, updating page state) —.
- #get_cookie(name) ⇒ Object
- #has_button?(locator) ⇒ Boolean
-
#has_css?(selector, count: nil) ⇒ Boolean
— Matchers —.
- #has_field?(locator) ⇒ Boolean
- #has_link?(locator) ⇒ Boolean
- #has_no_css?(selector, count: nil) ⇒ Boolean
- #has_no_text?(string) ⇒ Boolean
- #has_text?(string) ⇒ Boolean
- #headers ⇒ Object
- #html ⇒ Object
-
#initialize(app, default_host: "http://example.org", follow_redirects: true, max_redirects: 5, respect_method_override: true, method_override_param: "_method", user_agent: "DommyRack", accept: DEFAULT_ACCEPT, enforce_same_origin: true, follow_meta_refresh: true) ⇒ Session
constructor
A new instance of Session.
-
#json(symbolize_names: false) ⇒ Object
Parsed JSON of the most recent response, or nil if no request yet.
- #max_redirects ⇒ Object
- #navigate(method: "GET", url:, params: nil, body: nil, headers: {}) ⇒ Object
- #not_found? ⇒ Boolean
-
#on_request(&block) ⇒ Object
Register a callback invoked with the Rack env just before each request.
-
#on_response(&block) ⇒ Object
Register a callback invoked with the Response after each request.
- #patch(path, params: nil, body: nil, headers: {}) ⇒ Object
- #patch_json(path, data, headers: {}) ⇒ Object
- #post(path, params: nil, body: nil, headers: {}) ⇒ Object
-
#post_json(path, data, headers: {}) ⇒ Object
— JSON request helpers (navigate with a JSON body) —.
- #put(path, params: nil, body: nil, headers: {}) ⇒ Object
- #put_json(path, data, headers: {}) ⇒ Object
-
#raw_request(method, absolute_url, params: nil, body: nil, headers: {}) ⇒ Object
Execute one request against the app.
- #redirected? ⇒ Boolean
-
#redirects ⇒ Object
— Redirect chain of the last navigation —.
- #reload ⇒ Object
- #request(method, path, params: nil, body: nil, headers: {}) ⇒ Object
-
#save_page(path = nil) ⇒ Object
Write the current page HTML to ‘path` (default: a timestamped file in the system temp dir) and return the path.
- #select(value, from:) ⇒ Object
- #server_error? ⇒ Boolean
- #set_cookie(name, value, path: "/", domain: nil, **opts) ⇒ Object
- #set_header(name, value) ⇒ Object
- #status ⇒ Object
- #submit_form(form, submitter: nil) ⇒ Object (also: #submit)
-
#success? ⇒ Boolean
— Status predicates (delegate to the last response) —.
- #text ⇒ Object
- #uncheck(locator) ⇒ Object
- #unselect(value, from:) ⇒ Object
-
#visit(path) ⇒ Object
— Navigation API —.
-
#within(selector, &block) ⇒ Object
Restrict element finds and matchers to within the first element matching ‘selector` for the duration of the block.
-
#within_frame(locator = nil, &block) ⇒ Object
Load the iframe matched by ‘locator` (id, name, or CSS; the sole frame if omitted) and scope finds/matchers to its document for the block.
Constructor Details
#initialize(app, default_host: "http://example.org", follow_redirects: true, max_redirects: 5, respect_method_override: true, method_override_param: "_method", user_agent: "DommyRack", accept: DEFAULT_ACCEPT, enforce_same_origin: true, follow_meta_refresh: true) ⇒ Session
Returns a new instance of Session.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/dommy/rack/session.rb', line 24 def initialize(app, default_host: "http://example.org", follow_redirects: true, max_redirects: 5, respect_method_override: true, method_override_param: "_method", user_agent: "DommyRack", accept: DEFAULT_ACCEPT, enforce_same_origin: true, follow_meta_refresh: true) @app = app @config = Config.new( default_host: default_host, follow_redirects: follow_redirects, max_redirects: max_redirects, respect_method_override: respect_method_override, method_override_param: method_override_param, user_agent: user_agent, accept: accept, enforce_same_origin: enforce_same_origin, follow_meta_refresh: ).freeze @cookie_jar = CookieJar.new @headers = HeaderStore.new @navigation = Navigation.new(self, @config) @history = History.new @current_url = nil @current_window = nil @last_request = nil @last_response = nil @scope_stack = [] @request_listeners = [] @response_listeners = [] end |
Instance Attribute Details
#history ⇒ Object (readonly)
Returns the value of attribute history.
22 23 24 |
# File 'lib/dommy/rack/session.rb', line 22 def history @history end |
#last_request ⇒ Object (readonly)
Returns the value of attribute last_request.
22 23 24 |
# File 'lib/dommy/rack/session.rb', line 22 def last_request @last_request end |
#last_response ⇒ Object (readonly)
Returns the value of attribute last_response.
22 23 24 |
# File 'lib/dommy/rack/session.rb', line 22 def last_response @last_response end |
Instance Method Details
#all_css(selector) ⇒ Object
247 248 249 |
# File 'lib/dommy/rack/session.rb', line 247 def all_css(selector) scope_root&.query_selector_all(selector) end |
#all_xpath(xpath) ⇒ Object
255 256 257 |
# File 'lib/dommy/rack/session.rb', line 255 def all_xpath(xpath) document ? document.xpath(xpath) : [] end |
#apply_navigation_response(response, final_url, push_history: true) ⇒ Object
Apply a final navigation response: update last_response, current_url, the document (HTML only), and the history stack.
401 402 403 404 405 406 |
# File 'lib/dommy/rack/session.rb', line 401 def (response, final_url, push_history: true) @last_response = response @current_url = final_url @current_window = response.window if response.html? @history.push(final_url) if push_history end |
#at_css(selector) ⇒ Object
— DOM query helpers (delegate to the document) —
243 244 245 |
# File 'lib/dommy/rack/session.rb', line 243 def at_css(selector) scope_root&.query_selector(selector) end |
#at_xpath(xpath) ⇒ Object
251 252 253 |
# File 'lib/dommy/rack/session.rb', line 251 def at_xpath(xpath) document&.at_xpath(xpath) end |
#attach_file(locator, path) ⇒ Object
332 |
# File 'lib/dommy/rack/session.rb', line 332 def attach_file(locator, path) = field_interactor.attach_file(locator, path) |
#authorization_bearer(token) ⇒ Object
Bearer-token auth: sets a persistent Authorization header.
163 164 165 166 |
# File 'lib/dommy/rack/session.rb', line 163 def (token) @headers.bearer(token) self end |
#back ⇒ Object
86 87 88 89 |
# File 'lib/dommy/rack/session.rb', line 86 def back url = @history.back @navigation.revisit(url) if url end |
#basic_auth(user, password) ⇒ Object
HTTP Basic auth: sets a persistent Authorization header.
157 158 159 160 |
# File 'lib/dommy/rack/session.rb', line 157 def basic_auth(user, password) @headers.basic_auth(user, password) self end |
#body ⇒ Object
188 |
# File 'lib/dommy/rack/session.rb', line 188 def body = @last_response&.body |
#check(locator) ⇒ Object
330 |
# File 'lib/dommy/rack/session.rb', line 330 def check(locator) = field_interactor.check(locator) |
#choose(locator) ⇒ Object
329 |
# File 'lib/dommy/rack/session.rb', line 329 def choose(locator) = field_interactor.choose(locator) |
#clear_cookies ⇒ Object
367 |
# File 'lib/dommy/rack/session.rb', line 367 def = @cookie_jar.clear |
#click_button(locator) ⇒ Object
— Form submission —
338 339 340 341 342 343 344 345 |
# File 'lib/dommy/rack/session.rb', line 338 def (locator) = finder.(locator) # Only submit buttons submit a form. type=button / type=reset are # no-ops here since there is no JavaScript to handle their click. return unless () submit_form(finder.form_for(), submitter: ) end |
#click_link(locator) ⇒ Object
— Link navigation —
306 307 308 |
# File 'lib/dommy/rack/session.rb', line 306 def click_link(locator) click_link_element(finder.find_link(locator)) end |
#click_link_element(element) ⇒ Object
310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/dommy/rack/session.rb', line 310 def click_link_element(element) href = element.get_attribute("href") raise ElementNotClickableError, "link has no href" if href.nil? scheme = href.split(":", 2).first.to_s.downcase raise UnsupportedURLError, "#{scheme}: URLs are not supported" if %w[javascript mailto].include?(scheme) return document if href.start_with?("#") # in-page fragment: no request target = resolve_document_url(href) return document if same_page_fragment?(target) # url + fragment to current page: no request navigate(method: "GET", url: target, headers: referer_headers) end |
#client_error? ⇒ Boolean
199 |
# File 'lib/dommy/rack/session.rb', line 199 def client_error? = @last_response&.client_error? || false |
#config ⇒ Object
66 |
# File 'lib/dommy/rack/session.rb', line 66 def config = @config |
#cookies ⇒ Object
— Cookie public API —
359 |
# File 'lib/dommy/rack/session.rb', line 359 def = @cookie_jar.all |
#current_host ⇒ Object
182 183 184 |
# File 'lib/dommy/rack/session.rb', line 182 def current_host @current_url && URI.parse(@current_url).host end |
#current_path ⇒ Object
178 179 180 |
# File 'lib/dommy/rack/session.rb', line 178 def current_path @current_url && URI.parse(@current_url).path end |
#current_url ⇒ Object
— Current page state —
176 |
# File 'lib/dommy/rack/session.rb', line 176 def current_url = @current_url |
#default_headers ⇒ Object
A copy of the headers currently sent on every request. Mutate via #set_header / #delete_header rather than this hash.
144 |
# File 'lib/dommy/rack/session.rb', line 144 def default_headers = @headers.to_h |
#default_host ⇒ Object
— Config readers used by collaborators —
61 |
# File 'lib/dommy/rack/session.rb', line 61 def default_host = @config.default_host |
#delete(path, params: nil, body: nil, headers: {}) ⇒ Object
114 115 116 |
# File 'lib/dommy/rack/session.rb', line 114 def delete(path, params: nil, body: nil, headers: {}) navigate(method: "DELETE", url: path, params: params, body: body, headers: headers) end |
#delete_header(name) ⇒ Object
151 152 153 154 |
# File 'lib/dommy/rack/session.rb', line 151 def delete_header(name) @headers.delete(name) self end |
#delete_json(path, data, headers: {}) ⇒ Object
136 137 138 |
# File 'lib/dommy/rack/session.rb', line 136 def delete_json(path, data, headers: {}) request_json("DELETE", path, data, headers: headers) end |
#document ⇒ Object
189 |
# File 'lib/dommy/rack/session.rb', line 189 def document = @current_window&.document |
#enforce_same_origin? ⇒ Boolean
64 |
# File 'lib/dommy/rack/session.rb', line 64 def enforce_same_origin? = @config.enforce_same_origin |
#fetch(url, method: "GET", headers: {}, body: nil, params: nil, redirect: :follow) ⇒ Object
— Fetch API (returns Response; does NOT change document or history) —
170 171 172 |
# File 'lib/dommy/rack/session.rb', line 170 def fetch(url, method: "GET", headers: {}, body: nil, params: nil, redirect: :follow) @navigation.fetch(url, method: method, params: params, body: body, headers: headers, redirect: redirect) end |
#fill_in(locator, with:) ⇒ Object
Form field setting delegates to FieldInteractor (DOM mutation only; a subsequent submit is what turns into a navigation).
328 |
# File 'lib/dommy/rack/session.rb', line 328 def fill_in(locator, with:) = field_interactor.fill_in(locator, with: with) |
#follow_meta_refresh? ⇒ Boolean
65 |
# File 'lib/dommy/rack/session.rb', line 65 def = @config. |
#follow_redirects? ⇒ Boolean
62 |
# File 'lib/dommy/rack/session.rb', line 62 def follow_redirects? = @config.follow_redirects |
#forward ⇒ Object
91 92 93 94 |
# File 'lib/dommy/rack/session.rb', line 91 def forward url = @history.forward @navigation.revisit(url) if url end |
#get(path, headers: {}) ⇒ Object
— Basic request API (navigates, updating page state) —
98 99 100 |
# File 'lib/dommy/rack/session.rb', line 98 def get(path, headers: {}) navigate(method: "GET", url: path, headers: headers) end |
#get_cookie(name) ⇒ Object
366 |
# File 'lib/dommy/rack/session.rb', line 366 def (name) = @cookie_jar.get(name) |
#has_button?(locator) ⇒ Boolean
301 |
# File 'lib/dommy/rack/session.rb', line 301 def (locator) = element_present? { finder.(locator) } |
#has_css?(selector, count: nil) ⇒ Boolean
— Matchers —
287 288 289 290 |
# File 'lib/dommy/rack/session.rb', line 287 def has_css?(selector, count: nil) nodes = scope_root ? scope_root.query_selector_all(selector) : [] count ? nodes.size == count : !nodes.empty? end |
#has_field?(locator) ⇒ Boolean
302 |
# File 'lib/dommy/rack/session.rb', line 302 def has_field?(locator) = element_present? { finder.find_field(locator) } |
#has_link?(locator) ⇒ Boolean
300 |
# File 'lib/dommy/rack/session.rb', line 300 def has_link?(locator) = element_present? { finder.find_link(locator) } |
#has_no_css?(selector, count: nil) ⇒ Boolean
292 |
# File 'lib/dommy/rack/session.rb', line 292 def has_no_css?(selector, count: nil) = !has_css?(selector, count: count) |
#has_no_text?(string) ⇒ Boolean
298 |
# File 'lib/dommy/rack/session.rb', line 298 def has_no_text?(string) = !has_text?(string) |
#has_text?(string) ⇒ Boolean
294 295 296 |
# File 'lib/dommy/rack/session.rb', line 294 def has_text?(string) scope_text.include?(string.to_s) end |
#headers ⇒ Object
187 |
# File 'lib/dommy/rack/session.rb', line 187 def headers = @last_response&.headers |
#html ⇒ Object
222 223 224 |
# File 'lib/dommy/rack/session.rb', line 222 def html document&.to_html end |
#json(symbolize_names: false) ⇒ Object
Parsed JSON of the most recent response, or nil if no request yet.
192 193 194 |
# File 'lib/dommy/rack/session.rb', line 192 def json(symbolize_names: false) @last_response&.json(symbolize_names: symbolize_names) end |
#max_redirects ⇒ Object
63 |
# File 'lib/dommy/rack/session.rb', line 63 def max_redirects = @config.max_redirects |
#navigate(method: "GET", url:, params: nil, body: nil, headers: {}) ⇒ Object
74 75 76 |
# File 'lib/dommy/rack/session.rb', line 74 def navigate(method: "GET", url:, params: nil, body: nil, headers: {}) @navigation.navigate(method: method, url: url, params: params, body: body, headers: headers) end |
#not_found? ⇒ Boolean
201 |
# File 'lib/dommy/rack/session.rb', line 201 def not_found? = @last_response&.not_found? || false |
#on_request(&block) ⇒ Object
Register a callback invoked with the Rack env just before each request.
211 212 213 214 |
# File 'lib/dommy/rack/session.rb', line 211 def on_request(&block) @request_listeners << block self end |
#on_response(&block) ⇒ Object
Register a callback invoked with the Response after each request.
217 218 219 220 |
# File 'lib/dommy/rack/session.rb', line 217 def on_response(&block) @response_listeners << block self end |
#patch(path, params: nil, body: nil, headers: {}) ⇒ Object
110 111 112 |
# File 'lib/dommy/rack/session.rb', line 110 def patch(path, params: nil, body: nil, headers: {}) navigate(method: "PATCH", url: path, params: params, body: body, headers: headers) end |
#patch_json(path, data, headers: {}) ⇒ Object
132 133 134 |
# File 'lib/dommy/rack/session.rb', line 132 def patch_json(path, data, headers: {}) request_json("PATCH", path, data, headers: headers) end |
#post(path, params: nil, body: nil, headers: {}) ⇒ Object
102 103 104 |
# File 'lib/dommy/rack/session.rb', line 102 def post(path, params: nil, body: nil, headers: {}) navigate(method: "POST", url: path, params: params, body: body, headers: headers) end |
#post_json(path, data, headers: {}) ⇒ Object
— JSON request helpers (navigate with a JSON body) —
124 125 126 |
# File 'lib/dommy/rack/session.rb', line 124 def post_json(path, data, headers: {}) request_json("POST", path, data, headers: headers) end |
#put(path, params: nil, body: nil, headers: {}) ⇒ Object
106 107 108 |
# File 'lib/dommy/rack/session.rb', line 106 def put(path, params: nil, body: nil, headers: {}) navigate(method: "PUT", url: path, params: params, body: body, headers: headers) end |
#put_json(path, data, headers: {}) ⇒ Object
128 129 130 |
# File 'lib/dommy/rack/session.rb', line 128 def put_json(path, data, headers: {}) request_json("PUT", path, data, headers: headers) end |
#raw_request(method, absolute_url, params: nil, body: nil, headers: {}) ⇒ Object
Execute one request against the app. Stores response cookies but does NOT update current_url / document / history.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/dommy/rack/session.rb', line 375 def raw_request(method, absolute_url, params: nil, body: nil, headers: {}) # Remember the latest raw request so #reload can re-issue it. Note this # is the final request of any redirect chain: after a POST that # redirects (PRG), reload re-GETs the landing page rather than re-POSTing. @last_request_args = {method: method, url: absolute_url, params: params, body: body, headers: headers} env = RequestBuilder.new(@config).build( method: method, url: absolute_url, params: params, body: body, headers: @headers.merge(headers), cookie_string: @cookie_jar.(absolute_url) ) @last_request = env @request_listeners.each { |cb| cb.call(env) } status, response_headers, response_body = @app.call(env) response = Response.new(status, response_headers, response_body, url: absolute_url) response..each do |sc| @cookie_jar.store_from_header(sc, absolute_url) end @response_listeners.each { |cb| cb.call(response) } response end |
#redirected? ⇒ Boolean
206 |
# File 'lib/dommy/rack/session.rb', line 206 def redirected? = !redirects.empty? |
#redirects ⇒ Object
— Redirect chain of the last navigation —
205 |
# File 'lib/dommy/rack/session.rb', line 205 def redirects = @last_response&.redirects || [] |
#reload ⇒ Object
78 79 80 81 82 83 84 |
# File 'lib/dommy/rack/session.rb', line 78 def reload raise Error, "no current page to reload" unless @last_request_args response, final_url = @navigation.run(**@last_request_args) (response, final_url) response end |
#request(method, path, params: nil, body: nil, headers: {}) ⇒ Object
118 119 120 |
# File 'lib/dommy/rack/session.rb', line 118 def request(method, path, params: nil, body: nil, headers: {}) navigate(method: method, url: path, params: params, body: body, headers: headers) end |
#save_page(path = nil) ⇒ Object
Write the current page HTML to ‘path` (default: a timestamped file in the system temp dir) and return the path. For debugging.
232 233 234 235 236 237 238 239 |
# File 'lib/dommy/rack/session.rb', line 232 def save_page(path = nil) content = html raise Error, "no current page to save" if content.nil? path ||= ::File.join(Dir.tmpdir, "dommy-rack-#{Time.now.strftime("%Y%m%d%H%M%S")}.html") ::File.write(path, content) path end |
#select(value, from:) ⇒ Object
333 |
# File 'lib/dommy/rack/session.rb', line 333 def select(value, from:) = field_interactor.select(value, from: from) |
#server_error? ⇒ Boolean
200 |
# File 'lib/dommy/rack/session.rb', line 200 def server_error? = @last_response&.server_error? || false |
#set_cookie(name, value, path: "/", domain: nil, **opts) ⇒ Object
361 362 363 364 |
# File 'lib/dommy/rack/session.rb', line 361 def (name, value, path: "/", domain: nil, **opts) resolved_domain = domain || (@current_url && URI.parse(@current_url).host) || URI.parse(@config.default_host).host @cookie_jar.set!(name, value, domain: resolved_domain, path: path, **opts) end |
#set_header(name, value) ⇒ Object
146 147 148 149 |
# File 'lib/dommy/rack/session.rb', line 146 def set_header(name, value) @headers.set(name, value) self end |
#status ⇒ Object
186 |
# File 'lib/dommy/rack/session.rb', line 186 def status = @last_response&.status |
#submit_form(form, submitter: nil) ⇒ Object Also known as: submit
347 348 349 350 351 352 353 |
# File 'lib/dommy/rack/session.rb', line 347 def submit_form(form, submitter: nil) raise InvalidFormError, "element is not inside a form" if form.nil? result = FormSubmission.new(form, submitter, @config).submit! navigate(method: result[:method], url: resolve_document_url(result[:url]), params: result[:params], headers: referer_headers) end |
#success? ⇒ Boolean
— Status predicates (delegate to the last response) —
198 |
# File 'lib/dommy/rack/session.rb', line 198 def success? = @last_response&.success? || false |
#text ⇒ Object
226 227 228 |
# File 'lib/dommy/rack/session.rb', line 226 def text document&.body&.text_content end |
#uncheck(locator) ⇒ Object
331 |
# File 'lib/dommy/rack/session.rb', line 331 def uncheck(locator) = field_interactor.uncheck(locator) |
#unselect(value, from:) ⇒ Object
334 |
# File 'lib/dommy/rack/session.rb', line 334 def unselect(value, from:) = field_interactor.unselect(value, from: from) |
#visit(path) ⇒ Object
— Navigation API —
70 71 72 |
# File 'lib/dommy/rack/session.rb', line 70 def visit(path) @navigation.navigate(method: "GET", url: path) end |
#within(selector, &block) ⇒ Object
Restrict element finds and matchers to within the first element matching ‘selector` for the duration of the block.
263 264 265 266 267 268 |
# File 'lib/dommy/rack/session.rb', line 263 def within(selector, &block) node = scope_root&.query_selector(selector) raise ElementNotFoundError, "no element matching #{selector.inspect}" unless node with_scope(node, &block) end |
#within_frame(locator = nil, &block) ⇒ Object
Load the iframe matched by ‘locator` (id, name, or CSS; the sole frame if omitted) and scope finds/matchers to its document for the block.
272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/dommy/rack/session.rb', line 272 def within_frame(locator = nil, &block) frame = find_frame(locator) raise ElementNotFoundError, "no iframe matching #{locator.inspect}" unless frame src = frame.get_attribute("src") raise Error, "iframe has no src" if src.nil? || src.empty? frame_doc = fetch(resolve_document_url(src), headers: referer_headers).document raise UnsupportedContentTypeError, "iframe did not return an HTML document" unless frame_doc with_scope(frame_doc, &block) end |