Class: Puppeteer::RemoteObject

Inherits:
Object
  • Object
show all
Includes:
DebugPrint
Defined in:
lib/puppeteer/remote_object.rb

Overview

providing #valueFromRemoteObject, #releaseObject

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DebugPrint

#debug_print, #debug_puts

Constructor Details

#initialize(payload) ⇒ RemoteObject

Returns a new instance of RemoteObject.

Parameters:

  • payload (Hash)


7
8
9
10
11
12
13
# File 'lib/puppeteer/remote_object.rb', line 7

def initialize(payload)
  @object_id = payload['objectId']
  @type = payload['type']
  @sub_type = payload['subtype']
  @unserializable_value = payload['unserializableValue']
  @value = payload['value']
end

Instance Attribute Details

#sub_typeObject (readonly)

Returns the value of attribute sub_type.



15
16
17
# File 'lib/puppeteer/remote_object.rb', line 15

def sub_type
  @sub_type
end

Instance Method Details

#box_model(client) ⇒ Object

used in ElementHandle#_box_model



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/puppeteer/remote_object.rb', line 82

def box_model(client)
  result = client.send_message('DOM.getBoxModel', objectId: @object_id)

  # Firefox returns width/height = 0, content/padding/border/margin = [nil, nil, nil, nil, nil, nil, nil, nil]
  # while Chrome throws Error(Could not compute box model)
  model = result['model']
  if model['width'] == 0 && model['height'] == 0 &&
    %w(content padding border margin).all? { |key| model[key].all?(&:nil?) }

    debug_puts('Could not compute box model in Firefox.')
    return nil
  end
  result
rescue => err
  debug_puts(err)
  nil
end

#content_quads(client) ⇒ Object

used in ElementHandle#clickable_point



77
78
79
# File 'lib/puppeteer/remote_object.rb', line 77

def content_quads(client)
  client.send_message('DOM.getContentQuads', objectId: @object_id)
end

#converted_argObject



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/puppeteer/remote_object.rb', line 155

def converted_arg
  # ported logic from ExecutionContext#convertArgument
  # https://github.com/puppeteer/puppeteer/blob/master/lib/ExecutionContext.js
  #
  # Original logic:
  # if (objectHandle._remoteObject.unserializableValue)
  #   return { unserializableValue: objectHandle._remoteObject.unserializableValue };
  # if (!objectHandle._remoteObject.objectId)
  #   return { value: objectHandle._remoteObject.value };
  # return { objectId: objectHandle._remoteObject.objectId };

  if @unserializable_value
    { unserializableValue: @unserializable_value }
  elsif @object_id
    { objectId: @object_id }
  else
    { value: value }
  end
end

#evaluate_self(client) ⇒ Future<Puppeteer::RemoteObject|nil>

Returns:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/puppeteer/remote_object.rb', line 18

def evaluate_self(client)
  # ported logic from JSHandle#json_value.

  # original logic:
  #   if (this._remoteObject.objectId) {
  #     const response = await this._client.send('Runtime.callFunctionOn', {
  #       functionDeclaration: 'function() { return this; }',
  #       objectId: this._remoteObject.objectId,
  #       returnByValue: true,
  #       awaitPromise: true,
  #     });
  #     return helper.valueFromRemoteObject(response.result);
  #   }

  if @object_id
    params = {
      'functionDeclaration': 'function() { return this; }',
      'objectId': @object_id,
      'returnByValue': true,
      'awaitPromise': true,
    }
    response = client.send_message('Runtime.callFunctionOn', params)
    Puppeteer::RemoteObject.new(response['result'])
  else
    nil
  end
end

#node_info(client) ⇒ Object

used in ElementHandle#content_frame, ElementHandle#upload_file



72
73
74
# File 'lib/puppeteer/remote_object.rb', line 72

def node_info(client)
  client.send_message('DOM.describeNode', objectId: @object_id)
end

#properties(client) ⇒ Object

used in JSHandle#properties



62
63
64
65
66
67
68
69
# File 'lib/puppeteer/remote_object.rb', line 62

def properties(client)
  # original logic:
  #   const response = await this._client.send('Runtime.getProperties', {
  #     objectId: this._remoteObject.objectId,
  #     ownProperties: true
  #   });
  client.send_message('Runtime.getProperties', objectId: @object_id, ownProperties: true)
end

#query_ax_tree(client, accessible_name: nil, role: nil) ⇒ Object

used in ElementHandle#query_ax_tree



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/puppeteer/remote_object.rb', line 101

def query_ax_tree(client, accessible_name: nil, role: nil)
  result = client.send_message('Accessibility.queryAXTree', {
    objectId: @object_id,
    accessibleName: accessible_name,
    role: role,
  }.compact)

  result['nodes'].reject do |node|
    node['role']['value'] == 'text'
  end
end

#release(client) ⇒ Object

Parameters:



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/puppeteer/remote_object.rb', line 137

def release(client)
  return unless @object_id

  begin
    client.send_message('Runtime.releaseObject',
      objectId: @object_id,
    )
  rescue => err
    # Exceptions might happen in case of a page been navigated or closed.
    # Swallow these since they are harmless and we don't leak anything in this case.
    debug_puts(err)
  end

  nil
end

#set_file_input_files(client, files, backend_node_id) ⇒ Object

used in ElementHandle#upload_file



176
177
178
# File 'lib/puppeteer/remote_object.rb', line 176

def set_file_input_files(client, files, backend_node_id)
  client.send_message('DOM.setFileInputFiles', objectId: @object_id, files: files, backendNodeId: backend_node_id)
end

#type_strString

Returns:

  • (String)


47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/puppeteer/remote_object.rb', line 47

def type_str
  # used in JSHandle#to_s
  # original logic:
  #   if (this._remoteObject.objectId) {
  #     const type =  this._remoteObject.subtype || this._remoteObject.type;
  #     return 'JSHandle@' + type;
  #   }
  if @object_id
    @sub_type || @type
  else
    nil
  end
end

#valueObject

helper#valueFromRemoteObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/puppeteer/remote_object.rb', line 114

def value
  if @unserializable_value
    # if (remoteObject.type === 'bigint' && typeof BigInt !== 'undefined')
    #   return BigInt(remoteObject.unserializableValue.replace('n', ''));
    # switch (remoteObject.unserializableValue) {
    #   case '-0':
    #     return -0;
    #   case 'NaN':
    #     return NaN;
    #   case 'Infinity':
    #     return Infinity;
    #   case '-Infinity':
    #     return -Infinity;
    #   default:
    #     throw new Error('Unsupported unserializable value: ' + remoteObject.unserializableValue);
    # }
    raise NotImplementedError.new('unserializable_value is not implemented yet')
  else
    @value
  end
end