puppeteer-ruby 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/docs/Puppeteer.html +3 -3
  3. data/docs/Puppeteer/AsyncAwaitBehavior.html +1 -1
  4. data/docs/Puppeteer/Browser.html +2 -2
  5. data/docs/Puppeteer/BrowserContext.html +1 -1
  6. data/docs/Puppeteer/BrowserFetcher.html +1 -1
  7. data/docs/Puppeteer/BrowserRunner.html +1 -1
  8. data/docs/Puppeteer/BrowserRunner/BrowserProcess.html +1 -1
  9. data/docs/Puppeteer/CDPSession.html +1 -1
  10. data/docs/Puppeteer/CDPSession/Error.html +1 -1
  11. data/docs/Puppeteer/ConcurrentRubyUtils.html +1 -1
  12. data/docs/Puppeteer/Connection.html +1 -1
  13. data/docs/Puppeteer/Connection/MessageCallback.html +1 -1
  14. data/docs/Puppeteer/Connection/ProtocolError.html +1 -1
  15. data/docs/Puppeteer/Connection/RequestDebugPrinter.html +1 -1
  16. data/docs/Puppeteer/Connection/ResponseDebugPrinter.html +1 -1
  17. data/docs/Puppeteer/ConsoleMessage.html +1 -1
  18. data/docs/Puppeteer/ConsoleMessage/Location.html +1 -1
  19. data/docs/Puppeteer/DOMWorld.html +1 -1
  20. data/docs/Puppeteer/DOMWorld/DetachedError.html +1 -1
  21. data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +1 -1
  22. data/docs/Puppeteer/DebugPrint.html +1 -1
  23. data/docs/Puppeteer/Device.html +1 -1
  24. data/docs/Puppeteer/Devices.html +1 -1
  25. data/docs/Puppeteer/ElementHandle.html +525 -207
  26. data/docs/Puppeteer/ElementHandle/ElementNotFoundError.html +5 -5
  27. data/docs/Puppeteer/ElementHandle/ElementNotVisibleError.html +5 -5
  28. data/docs/Puppeteer/ElementHandle/Point.html +40 -29
  29. data/docs/Puppeteer/ElementHandle/ScrollIntoViewError.html +1 -1
  30. data/docs/Puppeteer/EmulationManager.html +1 -1
  31. data/docs/Puppeteer/EventCallbackable.html +1 -1
  32. data/docs/Puppeteer/EventCallbackable/EventListeners.html +1 -1
  33. data/docs/Puppeteer/ExecutionContext.html +1 -1
  34. data/docs/Puppeteer/ExecutionContext/EvaluationError.html +1 -1
  35. data/docs/Puppeteer/ExecutionContext/JavaScriptExpression.html +1 -1
  36. data/docs/Puppeteer/ExecutionContext/JavaScriptFunction.html +1 -1
  37. data/docs/Puppeteer/FileChooser.html +1 -1
  38. data/docs/Puppeteer/Frame.html +1 -1
  39. data/docs/Puppeteer/FrameManager.html +1 -1
  40. data/docs/Puppeteer/FrameManager/NavigationError.html +1 -1
  41. data/docs/Puppeteer/IfPresent.html +1 -1
  42. data/docs/Puppeteer/JSHandle.html +1 -1
  43. data/docs/Puppeteer/Keyboard.html +1 -1
  44. data/docs/Puppeteer/Keyboard/KeyDefinition.html +1 -1
  45. data/docs/Puppeteer/Keyboard/KeyDescription.html +1 -1
  46. data/docs/Puppeteer/Launcher.html +1 -1
  47. data/docs/Puppeteer/Launcher/Base.html +1 -1
  48. data/docs/Puppeteer/Launcher/Base/ExecutablePathNotFound.html +1 -1
  49. data/docs/Puppeteer/Launcher/BrowserOptions.html +1 -1
  50. data/docs/Puppeteer/Launcher/Chrome.html +1 -1
  51. data/docs/Puppeteer/Launcher/Chrome/DefaultArgs.html +1 -1
  52. data/docs/Puppeteer/Launcher/ChromeArgOptions.html +1 -1
  53. data/docs/Puppeteer/Launcher/LaunchOptions.html +1 -1
  54. data/docs/Puppeteer/LifecycleWatcher.html +1 -1
  55. data/docs/Puppeteer/LifecycleWatcher/ExpectedLifecycle.html +1 -1
  56. data/docs/Puppeteer/LifecycleWatcher/FrameDetachedError.html +1 -1
  57. data/docs/Puppeteer/LifecycleWatcher/TerminatedError.html +1 -1
  58. data/docs/Puppeteer/Mouse.html +1 -1
  59. data/docs/Puppeteer/Mouse/Button.html +1 -1
  60. data/docs/Puppeteer/NetworkManager.html +1 -1
  61. data/docs/Puppeteer/NetworkManager/Credentials.html +1 -1
  62. data/docs/Puppeteer/Page.html +2 -2
  63. data/docs/Puppeteer/Page/FileChooserTimeoutError.html +1 -1
  64. data/docs/Puppeteer/Page/ScreenshotOptions.html +1 -1
  65. data/docs/Puppeteer/Page/ScriptTag.html +1 -1
  66. data/docs/Puppeteer/Page/StyleTag.html +1 -1
  67. data/docs/Puppeteer/Page/TargetCrashedError.html +1 -1
  68. data/docs/Puppeteer/RemoteObject.html +110 -39
  69. data/docs/Puppeteer/Target.html +138 -116
  70. data/docs/Puppeteer/Target/InitializeFailure.html +1 -1
  71. data/docs/Puppeteer/Target/TargetInfo.html +1 -1
  72. data/docs/Puppeteer/TimeoutError.html +2 -2
  73. data/docs/Puppeteer/TimeoutSettings.html +1 -1
  74. data/docs/Puppeteer/TouchScreen.html +1 -1
  75. data/docs/Puppeteer/Viewport.html +81 -1
  76. data/docs/Puppeteer/WaitTask.html +1 -1
  77. data/docs/Puppeteer/WaitTask/TerminatedError.html +1 -1
  78. data/docs/Puppeteer/WaitTask/TimeoutError.html +1 -1
  79. data/docs/Puppeteer/WebSocket.html +26 -26
  80. data/docs/Puppeteer/WebSocket/DriverImpl.html +1 -1
  81. data/docs/Puppeteer/WebSocketTransport.html +2 -2
  82. data/docs/_index.html +26 -12
  83. data/docs/class_list.html +1 -1
  84. data/docs/file.README.html +1 -1
  85. data/docs/index.html +1 -1
  86. data/docs/method_list.html +675 -571
  87. data/docs/top-level-namespace.html +1 -1
  88. data/lib/puppeteer/browser.rb +1 -1
  89. data/lib/puppeteer/element_handle.rb +66 -108
  90. data/lib/puppeteer/element_handle/bounding_box.rb +12 -0
  91. data/lib/puppeteer/element_handle/box_model.rb +19 -0
  92. data/lib/puppeteer/element_handle/point.rb +26 -0
  93. data/lib/puppeteer/errors.rb +1 -3
  94. data/lib/puppeteer/page.rb +1 -1
  95. data/lib/puppeteer/remote_object.rb +9 -0
  96. data/lib/puppeteer/target.rb +9 -12
  97. data/lib/puppeteer/version.rb +1 -1
  98. data/lib/puppeteer/viewport.rb +18 -0
  99. data/lib/puppeteer/web_socket.rb +3 -1
  100. data/lib/puppeteer/web_socket_transport.rb +1 -1
  101. metadata +5 -2
@@ -116,7 +116,7 @@
116
116
  </div>
117
117
 
118
118
  <div id="footer">
119
- Generated on Tue Jun 9 00:13:39 2020 by
119
+ Generated on Fri Jun 12 12:38:32 2020 by
120
120
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
121
121
  0.9.24 (ruby-2.6.3).
122
122
  </div>
@@ -119,7 +119,7 @@ class Puppeteer::Browser
119
119
  target = @targets[target_id]
120
120
  target.ignore_initialize_callback_promise
121
121
  @targets.delete(target_id)
122
- target.handle_closed
122
+ target.closed_callback
123
123
  if await target.initialized_promise
124
124
  emit_event 'Events.Browser.TargetDestroyed', target
125
125
  target.browser_context.emit_event 'Events.BrowserContext.TargetDestroyed', target
@@ -1,4 +1,6 @@
1
- require 'mime/types'
1
+ require_relative './element_handle/bounding_box'
2
+ require_relative './element_handle/box_model'
3
+ require_relative './element_handle/point'
2
4
 
3
5
  class Puppeteer::ElementHandle < Puppeteer::JSHandle
4
6
  include Puppeteer::IfPresent
@@ -53,29 +55,6 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
53
55
  sleep 0.16
54
56
  end
55
57
 
56
- class Point
57
- def initialize(x:, y:)
58
- @x = x
59
- @y = y
60
- end
61
-
62
- def +(other)
63
- Point.new(
64
- x: @x + other.x,
65
- y: @y + other.y,
66
- )
67
- end
68
-
69
- def /(num)
70
- Point.new(
71
- x: @x / num,
72
- y: @y / num,
73
- )
74
- end
75
-
76
- attr_reader :x, :y
77
- end
78
-
79
58
  class ElementNotVisibleError < StandardError
80
59
  def initialize
81
60
  super("Node is either not visible or not an HTMLElement")
@@ -105,15 +84,6 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
105
84
  quads.first.reduce(:+) / 4
106
85
  end
107
86
 
108
- # /**
109
- # * @return {!Promise<void|Protocol.DOM.getBoxModelReturnValue>}
110
- # */
111
- # _getBoxModel() {
112
- # return this._client.send('DOM.getBoxModel', {
113
- # objectId: this._remoteObject.objectId
114
- # }).catch(error => debugError(error));
115
- # }
116
-
117
87
  # @param quad [Array<number>]
118
88
  # @return [Array<Point>]
119
89
  private def from_protocol_quad(quad)
@@ -265,89 +235,77 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
265
235
  press(key, delay: delay)
266
236
  end
267
237
 
268
- # /**
269
- # * @return {!Promise<?{x: number, y: number, width: number, height: number}>}
270
- # */
271
- # async boundingBox() {
272
- # const result = await this._getBoxModel();
273
-
274
- # if (!result)
275
- # return null;
276
-
277
- # const quad = result.model.border;
278
- # const x = Math.min(quad[0], quad[2], quad[4], quad[6]);
279
- # const y = Math.min(quad[1], quad[3], quad[5], quad[7]);
280
- # const width = Math.max(quad[0], quad[2], quad[4], quad[6]) - x;
281
- # const height = Math.max(quad[1], quad[3], quad[5], quad[7]) - y;
282
-
283
- # return {x, y, width, height};
284
- # }
285
-
286
- # /**
287
- # * @return {!Promise<?BoxModel>}
288
- # */
289
- # async boxModel() {
290
- # const result = await this._getBoxModel();
291
-
292
- # if (!result)
293
- # return null;
294
-
295
- # const {content, padding, border, margin, width, height} = result.model;
296
- # return {
297
- # content: this._fromProtocolQuad(content),
298
- # padding: this._fromProtocolQuad(padding),
299
- # border: this._fromProtocolQuad(border),
300
- # margin: this._fromProtocolQuad(margin),
301
- # width,
302
- # height
303
- # };
304
- # }
305
-
306
- # /**
307
- # *
308
- # * @param {!Object=} options
309
- # * @returns {!Promise<string|!Buffer>}
310
- # */
311
- # async screenshot(options = {}) {
312
- # let needsViewportReset = false;
313
-
314
- # let boundingBox = await this.boundingBox();
315
- # assert(boundingBox, 'Node is either not visible or not an HTMLElement');
316
-
317
- # const viewport = this._page.viewport();
318
-
319
- # if (viewport && (boundingBox.width > viewport.width || boundingBox.height > viewport.height)) {
320
- # const newViewport = {
321
- # width: Math.max(viewport.width, Math.ceil(boundingBox.width)),
322
- # height: Math.max(viewport.height, Math.ceil(boundingBox.height)),
323
- # };
324
- # await this._page.setViewport(Object.assign({}, viewport, newViewport));
238
+ # @return [BoundingBox|nil]
239
+ def bounding_box
240
+ if_present(box_model) do |result_model|
241
+ quads = result_model.border
242
+
243
+ x = quads.map(&:x).min
244
+ y = quads.map(&:y).min
245
+ BoundingBox.new(
246
+ x: x,
247
+ y: y,
248
+ width: quads.map(&:x).max - x,
249
+ height: quads.map(&:y).max - y,
250
+ )
251
+ end
252
+ end
325
253
 
326
- # needsViewportReset = true;
327
- # }
254
+ # @return [BoxModel|nil]
255
+ def box_model
256
+ if_present(@remote_object.box_model(@client)) do |result|
257
+ BoxModel.new(result['model'])
258
+ end
259
+ end
328
260
 
329
- # await this._scrollIntoViewIfNeeded();
261
+ def screenshot(options = {})
262
+ needs_viewport_reset = false
330
263
 
331
- # boundingBox = await this.boundingBox();
332
- # assert(boundingBox, 'Node is either not visible or not an HTMLElement');
333
- # assert(boundingBox.width !== 0, 'Node has 0 width.');
334
- # assert(boundingBox.height !== 0, 'Node has 0 height.');
264
+ box = bounding_box
265
+ unless box
266
+ raise ElementNotVisibleError.new
267
+ end
335
268
 
336
- # const { layoutViewport: { pageX, pageY } } = await this._client.send('Page.getLayoutMetrics');
269
+ viewport = @page.viewport
270
+ if viewport && (box.width > viewport.width || box.height > viewport.height)
271
+ new_viewport = viewport.merge(
272
+ width: [viewport.width, box.width.to_i].min,
273
+ height: [viewport.height, box.height.to_i].min,
274
+ )
275
+ @page.viewport = new_viewport
337
276
 
338
- # const clip = Object.assign({}, boundingBox);
339
- # clip.x += pageX;
340
- # clip.y += pageY;
277
+ needs_viewport_reset = true
278
+ end
279
+ scroll_into_view_if_needed
341
280
 
342
- # const imageData = await this._page.screenshot(Object.assign({}, {
343
- # clip
344
- # }, options));
281
+ box = bounding_box
282
+ unless box
283
+ raise ElementNotVisibleError.new
284
+ end
285
+ if box.width == 0
286
+ raise 'Node has 0 width.'
287
+ end
288
+ if box.height == 0
289
+ raise 'Node has 0 height.'
290
+ end
345
291
 
346
- # if (needsViewportReset)
347
- # await this._page.setViewport(viewport);
292
+ layout_metrics = @client.send_message('Page.getLayoutMetrics')
293
+ page_x = layout_metrics["layoutViewport"]["pageX"]
294
+ page_y = layout_metrics["layoutViewport"]["pageY"]
295
+
296
+ clip = {
297
+ x: page_x + box.x,
298
+ y: page_y + box.y,
299
+ width: box.width,
300
+ height: box.height,
301
+ }
348
302
 
349
- # return imageData;
350
- # }
303
+ @page.screenshot({ clip: clip }.merge(options))
304
+ ensure
305
+ if needs_viewport_reset
306
+ @page.viewport = viewport
307
+ end
308
+ end
351
309
 
352
310
  # `$()` in JavaScript. $ is not allowed to use as a method name in Ruby.
353
311
  # @param selector [String]
@@ -0,0 +1,12 @@
1
+ class Puppeteer::ElementHandle < Puppeteer::JSHandle
2
+ class BoundingBox
3
+ def initialize(x:, y:, width:, height:)
4
+ @x = x
5
+ @y = y
6
+ @width = width
7
+ @height = height
8
+ end
9
+
10
+ attr_reader :x, :y, :width, :height
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ class Puppeteer::ElementHandle < Puppeteer::JSHandle
2
+ class BoxModel
3
+ QUAD_ATTRIBUTE_NAMES = %i(content padding border margin)
4
+ # @param result [Hash]
5
+ def initialize(result_model)
6
+ QUAD_ATTRIBUTE_NAMES.each do |attr_name|
7
+ quad = result_model[attr_name.to_s]
8
+ instance_variable_set(
9
+ :"@#{attr_name}",
10
+ quad.each_slice(2).map { |x, y| Point.new(x: x, y: y) },
11
+ )
12
+ end
13
+ @width = result_model['width']
14
+ @height = result_model['height']
15
+ end
16
+ attr_reader(*QUAD_ATTRIBUTE_NAMES)
17
+ attr_reader :width, :height
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ class Puppeteer::ElementHandle < Puppeteer::JSHandle
2
+ # A class to represent (x, y)-coordinates
3
+ # supporting + and / operators.
4
+ class Point
5
+ def initialize(x:, y:)
6
+ @x = x
7
+ @y = y
8
+ end
9
+
10
+ def +(other)
11
+ Point.new(
12
+ x: @x + other.x,
13
+ y: @y + other.y,
14
+ )
15
+ end
16
+
17
+ def /(num)
18
+ Point.new(
19
+ x: @x / num,
20
+ y: @y / num,
21
+ )
22
+ end
23
+
24
+ attr_reader :x, :y
25
+ end
26
+ end
@@ -1,4 +1,2 @@
1
- # ref: https://github.com/puppeteer/puppeteer/blob/master/lib/Errors.js
1
+ # ref: https://github.com/puppeteer/puppeteer/blob/master/src/Errors.ts
2
2
  class Puppeteer::TimeoutError < StandardError; end
3
-
4
- class Puppeteer::WebSocktTransportError < StandardError; end
@@ -109,7 +109,7 @@ class Puppeteer::Page
109
109
  @client.on_event 'Page.fileChooserOpened' do |event|
110
110
  handle_file_chooser(event)
111
111
  end
112
- @target.on_close do
112
+ @target.is_closed_promise.then do
113
113
  emit_event 'Events.Page.Close'
114
114
  @closed = true
115
115
  end
@@ -62,6 +62,15 @@ class Puppeteer::RemoteObject
62
62
  client.send_message('DOM.getContentQuads', objectId: @object_id)
63
63
  end
64
64
 
65
+ # used in ElementHandle#_box_model
66
+ def box_model(client)
67
+ client.send_message('DOM.getBoxModel', objectId: @object_id)
68
+ rescue => err
69
+ debug_puts(err)
70
+ nil
71
+ end
72
+
73
+
65
74
  # helper#valueFromRemoteObject
66
75
  def value
67
76
  if @unserializable_value
@@ -37,7 +37,7 @@ class Puppeteer::Target
37
37
  @initialized_promise = @initialize_callback_promise.then do |success|
38
38
  handle_initialized(success)
39
39
  end
40
- # this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
40
+ @is_closed_promise = resolvable_future
41
41
 
42
42
  @is_initialized = @target_info.type != 'page' || !@target_info.url.empty?
43
43
 
@@ -46,12 +46,18 @@ class Puppeteer::Target
46
46
  end
47
47
  end
48
48
 
49
- attr_reader :target_id, :initialized_promise
49
+ attr_reader :target_id, :initialized_promise, :is_closed_promise
50
+
51
+ def closed_callback
52
+ @is_closed_promise.fulfill(true)
53
+ end
50
54
 
51
55
  class InitializeFailure < StandardError; end
52
56
 
53
57
  def ignore_initialize_callback_promise
54
- @initialize_callback_promise.fulfill(false)
58
+ unless @initialize_callback_promise.fulfilled?
59
+ @initialize_callback_promise.fulfill(false)
60
+ end
55
61
  end
56
62
 
57
63
  private def handle_initialized(success)
@@ -70,15 +76,6 @@ class Puppeteer::Target
70
76
  true
71
77
  end
72
78
 
73
- def handle_closed
74
- @closed = true
75
- @on_close&.call
76
- end
77
-
78
- def on_close(&block)
79
- @on_close = block
80
- end
81
-
82
79
  def initialized?
83
80
  @is_initialized
84
81
  end
@@ -1,3 +1,3 @@
1
1
  class Puppeteer
2
- VERSION = '0.0.9'
2
+ VERSION = '0.0.10'
3
3
  end
@@ -33,4 +33,22 @@ class Puppeteer::Viewport
33
33
  def landscape?
34
34
  @is_landscape
35
35
  end
36
+
37
+ def merge(
38
+ width: nil,
39
+ height: nil,
40
+ device_scale_factor: nil,
41
+ is_mobile: nil,
42
+ has_touch: nil,
43
+ is_landscape: nil)
44
+
45
+ Puppeteer::Viewport.new(
46
+ width: width || @width,
47
+ height: height || @height,
48
+ device_scale_factor: device_scale_factor || @device_scale_factor,
49
+ is_mobile: is_mobile.nil? ? @is_mobile : is_mobile,
50
+ has_touch: has_touch.nil? ? @has_touch : has_touch,
51
+ is_landscape: is_landscape.nil? ? @is_landscape : is_landscape,
52
+ )
53
+ end
36
54
  end
@@ -43,6 +43,8 @@ class Puppeteer::WebSocket
43
43
  end
44
44
  end
45
45
 
46
+ class TransportError < StandardError; end
47
+
46
48
  private def setup
47
49
  @ready_state = STATE_CONNECTING
48
50
  @driver.on(:open) do
@@ -55,7 +57,7 @@ class Puppeteer::WebSocket
55
57
  end
56
58
  @driver.on(:error) do |event|
57
59
  if !handle_on_error(error_message: event.message)
58
- raise Puppeteer::WebSocktTransportError.new(event.message)
60
+ raise TransportError.new(event.message)
59
61
  end
60
62
  end
61
63
  @driver.on(:message) do |event|
@@ -11,7 +11,7 @@ class Puppeteer::WebSocketTransport
11
11
  promise.fulfill(Puppeteer::WebSocketTransport.new(ws))
12
12
  end
13
13
  ws.on_error do |error_message|
14
- promise.reject(Puppeteer::WebSocktTransportError.new(error_message))
14
+ promise.reject(Puppeteer::WebSocket::TransportError.new(error_message))
15
15
  end
16
16
  promise.value!
17
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppeteer-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-08 00:00:00.000000000 Z
11
+ date: 2020-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -294,6 +294,9 @@ files:
294
294
  - lib/puppeteer/devices.rb
295
295
  - lib/puppeteer/dom_world.rb
296
296
  - lib/puppeteer/element_handle.rb
297
+ - lib/puppeteer/element_handle/bounding_box.rb
298
+ - lib/puppeteer/element_handle/box_model.rb
299
+ - lib/puppeteer/element_handle/point.rb
297
300
  - lib/puppeteer/emulation_manager.rb
298
301
  - lib/puppeteer/errors.rb
299
302
  - lib/puppeteer/event_callbackable.rb