Class: Ferrum::Frame

Inherits:
Object
  • Object
show all
Includes:
DOM, Runtime
Defined in:
lib/ferrum/frame.rb,
lib/ferrum/frame/dom.rb,
lib/ferrum/frame/runtime.rb

Overview

Represents a frame (the main document or a nested iframe) within a Page. Each frame has its own execution context for JavaScript and its own lifecycle state, tracked via #state. DOM search and JS evaluation methods are provided by the included DOM and Runtime modules.

Defined Under Namespace

Modules: DOM, Runtime

Constant Summary collapse

STATE_VALUES =
%i[
  started_loading
  navigated
  stopped_loading
  canceled
].freeze

Constants included from Runtime

Runtime::INTERMITTENT_ATTEMPTS, Runtime::INTERMITTENT_SLEEP

Constants included from DOM

DOM::LINK_TAG, DOM::SCRIPT_SRC_TAG, DOM::SCRIPT_TEXT_TAG, DOM::STYLE_TAG

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Runtime

#evaluate, #evaluate_async, #evaluate_func, #evaluate_on, #execute

Methods included from DOM

#add_script_tag, #add_style_tag, #at_css, #at_xpath, #body, #css, #current_title, #current_url, #doctype, #frame_element, #xpath

Constructor Details

#initialize(id, page, parent_id = nil) ⇒ Frame

Returns a new instance of Frame.



59
60
61
62
63
64
65
# File 'lib/ferrum/frame.rb', line 59

def initialize(id, page, parent_id = nil)
  @id = id
  @page = page
  @parent_id = parent_id
  @lifecycle_events = []
  @execution_id = Concurrent::MVar.new
end

Instance Attribute Details

#idString

The Frame's unique id.

Returns:

  • (String)


27
28
29
# File 'lib/ferrum/frame.rb', line 27

def id
  @id
end

#lifecycle_eventsArray<Hash{String => (String|Float)}> (readonly)

Frame's lifecycle events (navigation, load, paint, etc.).

Returns:

  • (Array<Hash{String => (String|Float)}>)


57
58
59
# File 'lib/ferrum/frame.rb', line 57

def lifecycle_events
  @lifecycle_events
end

#loader_idString?

Frame loader id.

Returns:

  • (String, nil)


52
53
54
# File 'lib/ferrum/frame.rb', line 52

def loader_id
  @loader_id
end

#nameString?

If frame was given a name it should be here.

Returns:

  • (String, nil)


32
33
34
# File 'lib/ferrum/frame.rb', line 32

def name
  @name
end

#pagePage (readonly)

The page the frame belongs to.

Returns:



37
38
39
# File 'lib/ferrum/frame.rb', line 37

def page
  @page
end

#parent_idString? (readonly)

Parent frame id if this one is nested in another one.

Returns:

  • (String, nil)


42
43
44
# File 'lib/ferrum/frame.rb', line 42

def parent_id
  @parent_id
end

#state:started_loading, ...

One of the states frame's in.

Returns:

  • (:started_loading, :navigated, :stopped_loading, :canceled, nil)


47
48
49
# File 'lib/ferrum/frame.rb', line 47

def state
  @state
end

Instance Method Details

#content=(html) ⇒ Object Also known as: set_content

Sets a content of a given frame.

Examples:

browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
frame = browser.frames[1]
frame.body # <html lang="en"><head><style>body {transition: opacity ease-in 0.2s; }...
frame.content = "<html><head></head><body><p>lol</p></body></html>"
frame.body # => <html><head></head><body><p>lol</p></body></html>

Parameters:

  • html (String)


167
168
169
170
171
172
173
174
175
# File 'lib/ferrum/frame.rb', line 167

def content=(html)
  evaluate_async(%(
    document.open();
    document.write(arguments[0]);
    document.close();
    arguments[1](true);
  ), @page.timeout, html)
  @page.document_node_id
end

#execution_idInteger?

Execution context id which is used by JS, each frame has it's own context in which JS evaluates.

Returns:

  • (Integer, nil)


201
202
203
204
205
206
# File 'lib/ferrum/frame.rb', line 201

def execution_id
  value = @execution_id.value
  return if value.instance_of?(Object)

  value
end

#execution_id!Integer

Execution context id which is used by JS, each frame has it's own context in which JS evaluates. Locks for a page timeout and raises an error if an execution id hasn't been set yet, if id is set returns immediately.

Returns:

  • (Integer)

Raises:



188
189
190
191
192
193
# File 'lib/ferrum/frame.rb', line 188

def execution_id!
  value = @execution_id.borrow(@page.timeout, &:itself)
  raise NoExecutionContextError if value.instance_of?(Object)

  value
end

#execution_id=(value) ⇒ Integer?

Sets the execution context id, or clears it if nil is given (e.g. when the context is torn down mid-navigation and hasn't been replaced yet).

Parameters:

  • value (Integer, nil)

Returns:

  • (Integer, nil)


217
218
219
220
221
222
223
# File 'lib/ferrum/frame.rb', line 217

def execution_id=(value)
  if value.nil?
    @execution_id.try_take!
  else
    @execution_id.try_put!(value)
  end
end

#idle?Boolean

Returns whether the frame has finished loading (+:stopped_loading+ state). Frames in :canceled state (execution context torn down mid-navigation) are not considered idle.

Examples:

browser.go_to("https://example.com")
browser.main_frame.idle? # => true

Returns:

  • (Boolean)


134
135
136
# File 'lib/ferrum/frame.rb', line 134

def idle?
  state == :stopped_loading
end

#inspectString

Debug representation of the frame, including its internal state.

Returns:

  • (String)


230
231
232
233
234
235
236
237
238
239
# File 'lib/ferrum/frame.rb', line 230

def inspect
  "#<#{self.class} " \
    "@id=#{@id.inspect} " \
    "@parent_id=#{@parent_id.inspect} " \
    "@name=#{@name.inspect} " \
    "@loader_id=#{@loader_id.inspect} " \
    "@lifecycle_events=#{@lifecycle_events.inspect} " \
    "@state=#{@state.inspect} " \
    "@execution_id=#{@execution_id.inspect}>"
end

#main?Boolean

If current frame is the main frame of the page (top of the tree).

Examples:

browser.go_to("https://www.w3schools.com/tags/tag_frame.asp")
frame = browser.frame_by(id: "C09C4E4404314AAEAE85928EAC109A93")
frame.main? # => false

Returns:

  • (Boolean)


120
121
122
# File 'lib/ferrum/frame.rb', line 120

def main?
  @parent_id.nil?
end

#parentFrame?

Returns the parent frame if this frame is nested in another one.

Examples:

browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
frame = browser.frames.last
frame.url # => "https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309083%2C51.47612752641776%2C0.00030577182769775396%2C51.478569861898606&layer=mapnik"
frame.parent.main? # => false
frame.parent.parent.main? # => false
frame.parent.parent.parent.main? # => true

Returns:



151
152
153
# File 'lib/ferrum/frame.rb', line 151

def parent
  @page.frame_by(id: @parent_id) if @parent_id
end

#titleString

Returns current frame's title.

Examples:

browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
frame = browser.frames[1]
frame.title # => HTML Demo: <iframe>

Returns:

  • (String)


106
107
108
# File 'lib/ferrum/frame.rb', line 106

def title
  evaluate("document.title")
end

#urlString

Returns current frame's location.href.

Examples:

browser.go_to("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe")
frame = browser.frames[1]
frame.url # => https://interactive-examples.mdn.mozilla.net/pages/tabbed/iframe.html

Returns:

  • (String)


92
93
94
# File 'lib/ferrum/frame.rb', line 92

def url
  evaluate("document.location.href")
end