puppeteer-ruby 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +71 -0
  3. data/.github/stale.yml +16 -0
  4. data/.gitignore +19 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +302 -0
  7. data/.travis.yml +7 -0
  8. data/Dockerfile +6 -0
  9. data/Gemfile +6 -0
  10. data/README.md +54 -0
  11. data/Rakefile +1 -0
  12. data/bin/console +11 -0
  13. data/bin/setup +8 -0
  14. data/docker-compose.yml +15 -0
  15. data/docs/Puppeteer.html +2020 -0
  16. data/docs/Puppeteer/AsyncAwaitBehavior.html +105 -0
  17. data/docs/Puppeteer/Browser.html +2148 -0
  18. data/docs/Puppeteer/BrowserContext.html +809 -0
  19. data/docs/Puppeteer/BrowserFetcher.html +214 -0
  20. data/docs/Puppeteer/BrowserRunner.html +914 -0
  21. data/docs/Puppeteer/BrowserRunner/BrowserProcess.html +477 -0
  22. data/docs/Puppeteer/CDPSession.html +813 -0
  23. data/docs/Puppeteer/CDPSession/Error.html +124 -0
  24. data/docs/Puppeteer/ConcurrentRubyUtils.html +430 -0
  25. data/docs/Puppeteer/Connection.html +960 -0
  26. data/docs/Puppeteer/Connection/MessageCallback.html +434 -0
  27. data/docs/Puppeteer/Connection/ProtocolError.html +216 -0
  28. data/docs/Puppeteer/Connection/RequestDebugPrinter.html +217 -0
  29. data/docs/Puppeteer/Connection/ResponseDebugPrinter.html +244 -0
  30. data/docs/Puppeteer/ConsoleMessage.html +565 -0
  31. data/docs/Puppeteer/ConsoleMessage/Location.html +433 -0
  32. data/docs/Puppeteer/DOMWorld.html +2219 -0
  33. data/docs/Puppeteer/DOMWorld/DetachedError.html +124 -0
  34. data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +124 -0
  35. data/docs/Puppeteer/DebugPrint.html +233 -0
  36. data/docs/Puppeteer/Device.html +470 -0
  37. data/docs/Puppeteer/Devices.html +139 -0
  38. data/docs/Puppeteer/ElementHandle.html +2542 -0
  39. data/docs/Puppeteer/ElementHandle/ElementNotFoundError.html +206 -0
  40. data/docs/Puppeteer/ElementHandle/ElementNotVisibleError.html +206 -0
  41. data/docs/Puppeteer/ElementHandle/Point.html +492 -0
  42. data/docs/Puppeteer/ElementHandle/ScrollIntoViewError.html +124 -0
  43. data/docs/Puppeteer/EmulationManager.html +454 -0
  44. data/docs/Puppeteer/EventCallbackable.html +433 -0
  45. data/docs/Puppeteer/EventCallbackable/EventListeners.html +435 -0
  46. data/docs/Puppeteer/ExecutionContext.html +998 -0
  47. data/docs/Puppeteer/ExecutionContext/EvaluationError.html +124 -0
  48. data/docs/Puppeteer/ExecutionContext/JavaScriptExpression.html +357 -0
  49. data/docs/Puppeteer/ExecutionContext/JavaScriptFunction.html +389 -0
  50. data/docs/Puppeteer/FileChooser.html +455 -0
  51. data/docs/Puppeteer/Frame.html +3677 -0
  52. data/docs/Puppeteer/FrameManager.html +2410 -0
  53. data/docs/Puppeteer/FrameManager/NavigationError.html +124 -0
  54. data/docs/Puppeteer/IfPresent.html +222 -0
  55. data/docs/Puppeteer/JSHandle.html +1352 -0
  56. data/docs/Puppeteer/Keyboard.html +1557 -0
  57. data/docs/Puppeteer/Keyboard/KeyDefinition.html +831 -0
  58. data/docs/Puppeteer/Keyboard/KeyDescription.html +603 -0
  59. data/docs/Puppeteer/Launcher.html +237 -0
  60. data/docs/Puppeteer/Launcher/Base.html +385 -0
  61. data/docs/Puppeteer/Launcher/Base/ExecutablePathNotFound.html +124 -0
  62. data/docs/Puppeteer/Launcher/BrowserOptions.html +441 -0
  63. data/docs/Puppeteer/Launcher/Chrome.html +669 -0
  64. data/docs/Puppeteer/Launcher/Chrome/DefaultArgs.html +382 -0
  65. data/docs/Puppeteer/Launcher/ChromeArgOptions.html +531 -0
  66. data/docs/Puppeteer/Launcher/LaunchOptions.html +893 -0
  67. data/docs/Puppeteer/LifecycleWatcher.html +834 -0
  68. data/docs/Puppeteer/LifecycleWatcher/ExpectedLifecycle.html +363 -0
  69. data/docs/Puppeteer/LifecycleWatcher/FrameDetachedError.html +206 -0
  70. data/docs/Puppeteer/LifecycleWatcher/TerminatedError.html +124 -0
  71. data/docs/Puppeteer/Mouse.html +1105 -0
  72. data/docs/Puppeteer/Mouse/Button.html +136 -0
  73. data/docs/Puppeteer/NetworkManager.html +901 -0
  74. data/docs/Puppeteer/NetworkManager/Credentials.html +385 -0
  75. data/docs/Puppeteer/Page.html +5970 -0
  76. data/docs/Puppeteer/Page/FileChooserTimeoutError.html +206 -0
  77. data/docs/Puppeteer/Page/ScreenshotOptions.html +845 -0
  78. data/docs/Puppeteer/Page/ScriptTag.html +555 -0
  79. data/docs/Puppeteer/Page/StyleTag.html +448 -0
  80. data/docs/Puppeteer/Page/TargetCrashedError.html +124 -0
  81. data/docs/Puppeteer/RemoteObject.html +1087 -0
  82. data/docs/Puppeteer/Target.html +1336 -0
  83. data/docs/Puppeteer/Target/InitializeFailure.html +124 -0
  84. data/docs/Puppeteer/Target/TargetInfo.html +729 -0
  85. data/docs/Puppeteer/TimeoutError.html +135 -0
  86. data/docs/Puppeteer/TimeoutSettings.html +496 -0
  87. data/docs/Puppeteer/TouchScreen.html +464 -0
  88. data/docs/Puppeteer/Viewport.html +837 -0
  89. data/docs/Puppeteer/WaitTask.html +637 -0
  90. data/docs/Puppeteer/WaitTask/TerminatedError.html +124 -0
  91. data/docs/Puppeteer/WaitTask/TimeoutError.html +206 -0
  92. data/docs/Puppeteer/WebSocket.html +673 -0
  93. data/docs/Puppeteer/WebSocket/DriverImpl.html +412 -0
  94. data/docs/Puppeteer/WebSocketTransport.html +600 -0
  95. data/docs/Puppeteer/WebSocktTransportError.html +124 -0
  96. data/docs/_index.html +823 -0
  97. data/docs/class_list.html +51 -0
  98. data/docs/css/common.css +1 -0
  99. data/docs/css/full_list.css +58 -0
  100. data/docs/css/style.css +496 -0
  101. data/docs/file.README.html +123 -0
  102. data/docs/file_list.html +56 -0
  103. data/docs/frames.html +17 -0
  104. data/docs/index.html +123 -0
  105. data/docs/js/app.js +314 -0
  106. data/docs/js/full_list.js +216 -0
  107. data/docs/js/jquery.js +4 -0
  108. data/docs/method_list.html +4075 -0
  109. data/docs/top-level-namespace.html +126 -0
  110. data/lib/puppeteer.rb +200 -0
  111. data/lib/puppeteer/async_await_behavior.rb +38 -0
  112. data/lib/puppeteer/browser.rb +259 -0
  113. data/lib/puppeteer/browser_context.rb +90 -0
  114. data/lib/puppeteer/browser_fetcher.rb +6 -0
  115. data/lib/puppeteer/browser_runner.rb +161 -0
  116. data/lib/puppeteer/cdp_session.rb +100 -0
  117. data/lib/puppeteer/concurrent_ruby_utils.rb +37 -0
  118. data/lib/puppeteer/connection.rb +254 -0
  119. data/lib/puppeteer/console_message.rb +24 -0
  120. data/lib/puppeteer/debug_print.rb +20 -0
  121. data/lib/puppeteer/device.rb +12 -0
  122. data/lib/puppeteer/devices.rb +885 -0
  123. data/lib/puppeteer/dom_world.rb +484 -0
  124. data/lib/puppeteer/element_handle.rb +433 -0
  125. data/lib/puppeteer/element_handle/bounding_box.rb +12 -0
  126. data/lib/puppeteer/element_handle/box_model.rb +19 -0
  127. data/lib/puppeteer/element_handle/point.rb +26 -0
  128. data/lib/puppeteer/emulation_manager.rb +46 -0
  129. data/lib/puppeteer/errors.rb +2 -0
  130. data/lib/puppeteer/event_callbackable.rb +88 -0
  131. data/lib/puppeteer/execution_context.rb +254 -0
  132. data/lib/puppeteer/file_chooser.rb +29 -0
  133. data/lib/puppeteer/frame.rb +286 -0
  134. data/lib/puppeteer/frame_manager.rb +378 -0
  135. data/lib/puppeteer/if_present.rb +18 -0
  136. data/lib/puppeteer/js_handle.rb +142 -0
  137. data/lib/puppeteer/keyboard.rb +183 -0
  138. data/lib/puppeteer/keyboard/key_description.rb +19 -0
  139. data/lib/puppeteer/keyboard/us_keyboard_layout.rb +283 -0
  140. data/lib/puppeteer/launcher.rb +25 -0
  141. data/lib/puppeteer/launcher/base.rb +48 -0
  142. data/lib/puppeteer/launcher/browser_options.rb +41 -0
  143. data/lib/puppeteer/launcher/chrome.rb +211 -0
  144. data/lib/puppeteer/launcher/chrome_arg_options.rb +49 -0
  145. data/lib/puppeteer/launcher/launch_options.rb +68 -0
  146. data/lib/puppeteer/lifecycle_watcher.rb +171 -0
  147. data/lib/puppeteer/mouse.rb +123 -0
  148. data/lib/puppeteer/network_manager.rb +122 -0
  149. data/lib/puppeteer/page.rb +1065 -0
  150. data/lib/puppeteer/page/screenshot_options.rb +78 -0
  151. data/lib/puppeteer/remote_object.rb +143 -0
  152. data/lib/puppeteer/target.rb +150 -0
  153. data/lib/puppeteer/timeout_settings.rb +15 -0
  154. data/lib/puppeteer/touch_screen.rb +43 -0
  155. data/lib/puppeteer/version.rb +3 -0
  156. data/lib/puppeteer/viewport.rb +54 -0
  157. data/lib/puppeteer/wait_task.rb +188 -0
  158. data/lib/puppeteer/web_socket.rb +122 -0
  159. data/lib/puppeteer/web_socket_transport.rb +49 -0
  160. data/puppeteer-ruby.gemspec +32 -0
  161. metadata +355 -0
@@ -0,0 +1,78 @@
1
+ require 'mime/types'
2
+
3
+ class Puppeteer::Page
4
+ # /**
5
+ # * @typedef {Object} ScreenshotOptions
6
+ # * @property {string=} type
7
+ # * @property {string=} path
8
+ # * @property {boolean=} fullPage
9
+ # * @property {{x: number, y: number, width: number, height: number}=} clip
10
+ # * @property {number=} quality
11
+ # * @property {boolean=} omitBackground
12
+ # * @property {string=} encoding
13
+ # */
14
+ class ScreenshotOptions
15
+ # @params options [Hash]
16
+ def initialize(options)
17
+ if options[:type]
18
+ unless [:png, :jpeg].include?(options[:type].to_sym)
19
+ raise ArgumentError.new("Unknown options.type value: #{options[:type]}")
20
+ end
21
+ @type = options[:type]
22
+ elsif options[:path]
23
+ mime_types = MIME::Types.type_for(options[:path])
24
+ if mime_types.include?('image/png')
25
+ @type = 'png'
26
+ elsif mime_types.include?('image/jpeg')
27
+ @type = 'jpeg'
28
+ else
29
+ raise ArgumentError.new("Unsupported screenshot mime type resolved: #{mime_types}, path: #{options[:path]}")
30
+ end
31
+ end
32
+ @type ||= 'png'
33
+
34
+ if options[:quality]
35
+ unless @type == 'png'
36
+ raise ArgumentError.new("options.quality is unsupported for the #{@type} screenshots")
37
+ end
38
+ unless options[:quality].is_a?(Numeric)
39
+ raise ArgumentError.new("Expected options.quality to be a number but found #{options[:quality].class}")
40
+ end
41
+ quality = options[:quality].to_i
42
+ unless (0..100).include?(qualizy)
43
+ raise ArgumentError.new("Expected options.quality to be between 0 and 100 (inclusive), got #{quality}")
44
+ end
45
+ @quality = quality
46
+ end
47
+
48
+ if options[:clip] && options[:full_page]
49
+ raise ArgumentError.new('options.clip and options.fullPage are exclusive')
50
+ end
51
+
52
+ # if (options.clip) {
53
+ # assert(typeof options.clip.x === 'number', 'Expected options.clip.x to be a number but found ' + (typeof options.clip.x));
54
+ # assert(typeof options.clip.y === 'number', 'Expected options.clip.y to be a number but found ' + (typeof options.clip.y));
55
+ # assert(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' + (typeof options.clip.width));
56
+ # assert(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' + (typeof options.clip.height));
57
+ # assert(options.clip.width !== 0, 'Expected options.clip.width not to be 0.');
58
+ # assert(options.clip.height !== 0, 'Expected options.clip.height not to be 0.');
59
+ # }
60
+
61
+ @path = options[:path]
62
+ @full_page = options[:full_page]
63
+ @clip = options[:clip]
64
+ @omit_background = options[:omit_background]
65
+ @encoding = options[:encoding]
66
+ end
67
+
68
+ attr_reader :type, :quality, :path, :clip, :encoding
69
+
70
+ def full_page?
71
+ @full_page
72
+ end
73
+
74
+ def omit_background?
75
+ @omit_background
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,143 @@
1
+ # providing #valueFromRemoteObject, #releaseObject
2
+ class Puppeteer::RemoteObject
3
+ include Puppeteer::DebugPrint
4
+ using Puppeteer::AsyncAwaitBehavior
5
+
6
+ # @param payload [Hash]
7
+ def initialize(payload)
8
+ @object_id = payload['objectId']
9
+ @sub_type = payload['subtype']
10
+ @unserializable_value = payload['unserializableValue']
11
+ @value = payload['value']
12
+ end
13
+
14
+ attr_reader :sub_type
15
+
16
+ # @return [Future<Puppeteer::RemoteObject|nil>]
17
+ def evaluate_self(client)
18
+ # ported logic from JSHandle#json_value.
19
+
20
+ # original logic:
21
+ # if (this._remoteObject.objectId) {
22
+ # const response = await this._client.send('Runtime.callFunctionOn', {
23
+ # functionDeclaration: 'function() { return this; }',
24
+ # objectId: this._remoteObject.objectId,
25
+ # returnByValue: true,
26
+ # awaitPromise: true,
27
+ # });
28
+ # return helper.valueFromRemoteObject(response.result);
29
+ # }
30
+
31
+ if @object_id
32
+ params = {
33
+ 'functionDeclaration': 'function() { return this; }',
34
+ 'objectId': @object_id,
35
+ 'returnByValue': true,
36
+ 'awaitPromise': true,
37
+ }
38
+ response = client.send_message('Runtime.callFunctionOn', params)
39
+ Puppeteer::RemoteObject.new(response['result'])
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
45
+ # used in JSHandle#properties
46
+ def properties(client)
47
+ # original logic:
48
+ # const response = await this._client.send('Runtime.getProperties', {
49
+ # objectId: this._remoteObject.objectId,
50
+ # ownProperties: true
51
+ # });
52
+ client.send_message('Runtime.getProperties', objectId: @object_id, ownProperties: true)
53
+ end
54
+
55
+ # used in ElementHandle#content_frame, ElementHandle#upload_file
56
+ def node_info(client)
57
+ client.send_message('DOM.describeNode', objectId: @object_id)
58
+ end
59
+
60
+ # used in ElementHandle#clickable_point
61
+ def content_quads(client)
62
+ client.send_message('DOM.getContentQuads', objectId: @object_id)
63
+ end
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
+
74
+ # helper#valueFromRemoteObject
75
+ def value
76
+ if @unserializable_value
77
+ # if (remoteObject.type === 'bigint' && typeof BigInt !== 'undefined')
78
+ # return BigInt(remoteObject.unserializableValue.replace('n', ''));
79
+ # switch (remoteObject.unserializableValue) {
80
+ # case '-0':
81
+ # return -0;
82
+ # case 'NaN':
83
+ # return NaN;
84
+ # case 'Infinity':
85
+ # return Infinity;
86
+ # case '-Infinity':
87
+ # return -Infinity;
88
+ # default:
89
+ # throw new Error('Unsupported unserializable value: ' + remoteObject.unserializableValue);
90
+ # }
91
+ raise NotImplementedError.new('unserializable_value is not implemented yet')
92
+ else
93
+ @value
94
+ end
95
+ end
96
+
97
+ # @param client [Puppeteer::CDPSession]
98
+ def release(client)
99
+ return unless @object_id
100
+
101
+ begin
102
+ client.send_message('Runtime.releaseObject',
103
+ objectId: @object_id,
104
+ )
105
+ rescue => err
106
+ # Exceptions might happen in case of a page been navigated or closed.
107
+ # Swallow these since they are harmless and we don't leak anything in this case.
108
+ debug_puts(err)
109
+ end
110
+
111
+ nil
112
+ end
113
+
114
+ # @param client [Puppeteer::CDPSession]
115
+ async def async_release(client)
116
+ release(client)
117
+ end
118
+
119
+ def converted_arg
120
+ # ported logic from ExecutionContext#convertArgument
121
+ # https://github.com/puppeteer/puppeteer/blob/master/lib/ExecutionContext.js
122
+ #
123
+ # Original logic:
124
+ # if (objectHandle._remoteObject.unserializableValue)
125
+ # return { unserializableValue: objectHandle._remoteObject.unserializableValue };
126
+ # if (!objectHandle._remoteObject.objectId)
127
+ # return { value: objectHandle._remoteObject.value };
128
+ # return { objectId: objectHandle._remoteObject.objectId };
129
+
130
+ if @unserializable_value
131
+ { unserializableValue: @unserializable_value }
132
+ elsif @object_id
133
+ { objectId: @object_id }
134
+ else
135
+ { value: value }
136
+ end
137
+ end
138
+
139
+ # used in ElementHandle#upload_file
140
+ def set_file_input_files(client, files, backend_node_id)
141
+ client.send_message('DOM.setFileInputFiles', objectId: @object_id, files: files, backendNodeId: backend_node_id)
142
+ end
143
+ end
@@ -0,0 +1,150 @@
1
+ # https://github.com/puppeteer/puppeteer/blob/master/lib/Target.js
2
+ class Puppeteer::Target
3
+ class TargetInfo
4
+ def initialize(options)
5
+ @target_id = options['targetId']
6
+ @type = options['type']
7
+ @title = options['title']
8
+ @url = options['url']
9
+ @attached = options['attached']
10
+ @browser_context_id = options['browserContextId']
11
+ @opener_id = options['openerId']
12
+ end
13
+ attr_reader :target_id, :type, :title, :url, :attached, :browser_context_id, :opener_id
14
+ end
15
+
16
+ # @param {!Protocol.Target.TargetInfo} targetInfo
17
+ # @param {!Puppeteer.BrowserContext} browserContext
18
+ # @param {!function():!Promise<!Puppeteer.CDPSession>} sessionFactory
19
+ # @param {boolean} ignoreHTTPSErrors
20
+ # @param {?Puppeteer.Viewport} defaultViewport
21
+ # @param {!Puppeteer.TaskQueue} screenshotTaskQueue
22
+ def initialize(target_info:, browser_context:, session_factory:, ignore_https_errors:, default_viewport:, screenshot_task_queue:)
23
+ @target_info = target_info
24
+ @browser_context = browser_context
25
+ @target_id = target_info.target_id
26
+ @session_factory = session_factory
27
+ @ignore_https_errors = ignore_https_errors
28
+ @default_viewport = default_viewport
29
+ @screenshot_task_queue = screenshot_task_queue
30
+
31
+
32
+ # /** @type {?Promise<!Puppeteer.Page>} */
33
+ # this._pagePromise = null;
34
+ # /** @type {?Promise<!Worker>} */
35
+ # this._workerPromise = null;
36
+ @initialize_callback_promise = resolvable_future
37
+ @initialized_promise = @initialize_callback_promise.then do |success|
38
+ handle_initialized(success)
39
+ end
40
+ @is_closed_promise = resolvable_future
41
+
42
+ @is_initialized = @target_info.type != 'page' || !@target_info.url.empty?
43
+
44
+ if @is_initialized
45
+ @initialize_callback_promise.fulfill(true)
46
+ end
47
+ end
48
+
49
+ attr_reader :target_id, :initialized_promise, :is_closed_promise
50
+
51
+ def closed_callback
52
+ @is_closed_promise.fulfill(true)
53
+ end
54
+
55
+ class InitializeFailure < StandardError; end
56
+
57
+ def ignore_initialize_callback_promise
58
+ unless @initialize_callback_promise.fulfilled?
59
+ @initialize_callback_promise.fulfill(false)
60
+ end
61
+ end
62
+
63
+ private def handle_initialized(success)
64
+ unless success
65
+ raise InitializeFailure.new('Failed to create target for page')
66
+ end
67
+ opener_page = opener&.page
68
+ if opener_page.nil? || type != 'page'
69
+ return true
70
+ end
71
+ # if (!openerPage.listenerCount(Events.Page.Popup))
72
+ # return true;
73
+ popup_page = page
74
+ opener_page.emit_event('Events.Page.Popup', popup_page)
75
+
76
+ true
77
+ end
78
+
79
+ def initialized?
80
+ @is_initialized
81
+ end
82
+
83
+ def create_cdp_session
84
+ @session_factory.call
85
+ end
86
+
87
+ def page
88
+ if ['page', 'background_page', 'webview'].include?(@target_info.type) && @page.nil?
89
+ client = @session_factory.call
90
+ @page = Puppeteer::Page.create(client, self, @ignore_https_errors, @default_viewport, @screenshot_task_queue)
91
+ end
92
+ @page
93
+ end
94
+
95
+ # /**
96
+ # * @return {!Promise<?Worker>}
97
+ # */
98
+ # async worker() {
99
+ # if (this._targetInfo.type !== 'service_worker' && this._targetInfo.type !== 'shared_worker')
100
+ # return null;
101
+ # if (!this._workerPromise) {
102
+ # // TODO(einbinder): Make workers send their console logs.
103
+ # this._workerPromise = this._sessionFactory()
104
+ # .then(client => new Worker(client, this._targetInfo.url, () => {} /* consoleAPICalled */, () => {} /* exceptionThrown */));
105
+ # }
106
+ # return this._workerPromise;
107
+ # }
108
+
109
+ # @return {string}
110
+ def url
111
+ @target_info.url
112
+ end
113
+
114
+ # @return {"page"|"background_page"|"service_worker"|"shared_worker"|"other"|"browser"}
115
+ def type
116
+ type = @target_info.type
117
+ if ['page', 'background_page', 'service_worker', 'shared_worker', 'browser'].include?(type)
118
+ type
119
+ else
120
+ 'other'
121
+ end
122
+ end
123
+
124
+ # @return {!Puppeteer.Browser}
125
+ def browser
126
+ @browser_context.browser
127
+ end
128
+
129
+ # @return {!Puppeteer.BrowserContext}
130
+ def browser_context
131
+ @browser_context
132
+ end
133
+
134
+ # @return {?Puppeteer.Target}
135
+ def opener
136
+ opener_id = @target_info.opener_id
137
+ return nil if opener_id.nil?
138
+ browser.targets[opener_id]
139
+ end
140
+
141
+ # @param {!Protocol.Target.TargetInfo} targetInfo
142
+ def handle_target_info_changed(target_info)
143
+ @target_info = target_info
144
+
145
+ if !@is_initialized && (@target_info.type != 'page' || !@target_info.url.empty?)
146
+ @is_initialized = true
147
+ @initialize_callback_promise.fulfill(true)
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,15 @@
1
+ class Puppeteer::TimeoutSettings
2
+ DEFAULT_TIMEOUT = 30000
3
+
4
+ attr_writer :default_timeout, :default_navigation_timeout
5
+
6
+ # @return {number}
7
+ def navigation_timeout
8
+ @default_navigation_timeout || @default_timeout || DEFAULT_TIMEOUT
9
+ end
10
+
11
+ # @return {number}
12
+ def timeout
13
+ @default_timeout || DEFAULT_TIMEOUT
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ class Puppeteer::TouchScreen
2
+ using Puppeteer::AsyncAwaitBehavior
3
+
4
+ # @param {Puppeteer.CDPSession} client
5
+ # @param keyboard [Puppeteer::Keyboard]
6
+ def initialize(client, keyboard)
7
+ @client = client
8
+ @keyboard = keyboard
9
+ end
10
+
11
+ # @param x [number]
12
+ # @param y [number]
13
+ def tap(x, y)
14
+ # Touches appear to be lost during the first frame after navigation.
15
+ # This waits a frame before sending the tap.
16
+ # @see https://crbug.com/613219
17
+ @client.send_message('Runtime.evaluate',
18
+ expression: 'new Promise(x => requestAnimationFrame(() => requestAnimationFrame(x)))',
19
+ awaitPromise: true,
20
+ )
21
+
22
+ touch_points = [
23
+ { x: x.round, y: y.round },
24
+ ]
25
+ @client.send_message('Input.dispatchTouchEvent',
26
+ type: 'touchStart',
27
+ touchPoints: touch_points,
28
+ modifiers: @keyboard.modifiers,
29
+ )
30
+ @client.send_message('Input.dispatchTouchEvent',
31
+ type: 'touchEnd',
32
+ touchPoints: [],
33
+ modifiers: @keyboard.modifiers,
34
+ )
35
+ end
36
+
37
+ # @param x [number]
38
+ # @param y [number]
39
+ # @return [Future]
40
+ async def async_tap(x, y)
41
+ tap(x, y)
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ class Puppeteer
2
+ VERSION = '0.0.10'
3
+ end
@@ -0,0 +1,54 @@
1
+ class Puppeteer::Viewport
2
+ # @param width [int]
3
+ # @param height [int]
4
+ # @param device_scale_factor [double]
5
+ # @param is_mobile [boolean]
6
+ # @param has_touch [boolean]
7
+ # @param is_landscape [boolean]
8
+ def initialize(
9
+ width:,
10
+ height:,
11
+ device_scale_factor: 1.0,
12
+ is_mobile: false,
13
+ has_touch: false,
14
+ is_landscape: false)
15
+ @width = width
16
+ @height = height
17
+ @device_scale_factor = device_scale_factor
18
+ @is_mobile = is_mobile
19
+ @has_touch = has_touch
20
+ @is_landscape = is_landscape
21
+ end
22
+
23
+ attr_reader :width, :height, :device_scale_factor
24
+
25
+ def mobile?
26
+ @is_mobile
27
+ end
28
+
29
+ def has_touch?
30
+ @has_touch
31
+ end
32
+
33
+ def landscape?
34
+ @is_landscape
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
54
+ end