puppeteer-ruby 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
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