puppeteer-ruby 0.0.5 → 0.0.6

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/docs/Puppeteer.html +2 -2
  3. data/docs/Puppeteer/AsyncAwaitBehavior.html +1 -1
  4. data/docs/Puppeteer/Browser.html +1 -1
  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 +86 -57
  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 +610 -68
  20. data/docs/Puppeteer/DOMWorld/DetachedError.html +1 -1
  21. data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +1 -1
  22. data/docs/Puppeteer/DebugPrint.html +2 -2
  23. data/docs/Puppeteer/Device.html +1 -1
  24. data/docs/Puppeteer/Devices.html +1 -1
  25. data/docs/Puppeteer/ElementHandle.html +306 -109
  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 +28 -28
  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 +124 -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 +2 -2
  37. data/docs/Puppeteer/Frame.html +117 -65
  38. data/docs/Puppeteer/FrameManager.html +1 -1
  39. data/docs/Puppeteer/FrameManager/NavigationError.html +1 -1
  40. data/docs/Puppeteer/IfPresent.html +1 -1
  41. data/docs/Puppeteer/JSHandle.html +1 -1
  42. data/docs/Puppeteer/Keyboard.html +1 -1
  43. data/docs/Puppeteer/Keyboard/KeyDefinition.html +1 -1
  44. data/docs/Puppeteer/Keyboard/KeyDescription.html +1 -1
  45. data/docs/Puppeteer/Launcher.html +1 -1
  46. data/docs/Puppeteer/Launcher/Base.html +1 -1
  47. data/docs/Puppeteer/Launcher/Base/ExecutablePathNotFound.html +1 -1
  48. data/docs/Puppeteer/Launcher/BrowserOptions.html +1 -1
  49. data/docs/Puppeteer/Launcher/Chrome.html +1 -1
  50. data/docs/Puppeteer/Launcher/Chrome/DefaultArgs.html +1 -1
  51. data/docs/Puppeteer/Launcher/ChromeArgOptions.html +1 -1
  52. data/docs/Puppeteer/Launcher/LaunchOptions.html +1 -1
  53. data/docs/Puppeteer/LifecycleWatcher.html +1 -1
  54. data/docs/Puppeteer/LifecycleWatcher/ExpectedLifecycle.html +1 -1
  55. data/docs/Puppeteer/LifecycleWatcher/FrameDetachedError.html +1 -1
  56. data/docs/Puppeteer/LifecycleWatcher/TerminatedError.html +1 -1
  57. data/docs/Puppeteer/Mouse.html +1 -1
  58. data/docs/Puppeteer/Mouse/Button.html +1 -1
  59. data/docs/Puppeteer/NetworkManager.html +1 -1
  60. data/docs/Puppeteer/NetworkManager/Credentials.html +1 -1
  61. data/docs/Puppeteer/Page.html +95 -43
  62. data/docs/Puppeteer/Page/ScreenshotOptions.html +1 -1
  63. data/docs/Puppeteer/Page/ScriptTag.html +1 -1
  64. data/docs/Puppeteer/Page/StyleTag.html +1 -1
  65. data/docs/Puppeteer/Page/TargetCrashedError.html +1 -1
  66. data/docs/Puppeteer/RemoteObject.html +1 -1
  67. data/docs/Puppeteer/Target.html +1 -1
  68. data/docs/Puppeteer/Target/InitializeFailure.html +1 -1
  69. data/docs/Puppeteer/Target/TargetInfo.html +1 -1
  70. data/docs/Puppeteer/TimeoutError.html +1 -1
  71. data/docs/Puppeteer/TimeoutSettings.html +1 -1
  72. data/docs/Puppeteer/TouchScreen.html +1 -1
  73. data/docs/Puppeteer/Viewport.html +1 -1
  74. data/docs/Puppeteer/WaitTask.html +434 -8
  75. data/docs/Puppeteer/WaitTask/TerminatedError.html +1 -1
  76. data/docs/Puppeteer/WaitTask/TimeoutError.html +206 -0
  77. data/docs/Puppeteer/WebSocket.html +1 -1
  78. data/docs/Puppeteer/WebSocket/DriverImpl.html +1 -1
  79. data/docs/Puppeteer/WebSocketTransport.html +1 -1
  80. data/docs/Puppeteer/WebSocktTransportError.html +1 -1
  81. data/docs/_index.html +8 -1
  82. data/docs/class_list.html +1 -1
  83. data/docs/file.README.html +1 -1
  84. data/docs/index.html +1 -1
  85. data/docs/method_list.html +615 -519
  86. data/docs/top-level-namespace.html +1 -1
  87. data/lib/puppeteer/cdp_session.rb +33 -11
  88. data/lib/puppeteer/dom_world.rb +97 -90
  89. data/lib/puppeteer/element_handle.rb +36 -54
  90. data/lib/puppeteer/execution_context.rb +23 -17
  91. data/lib/puppeteer/frame.rb +13 -11
  92. data/lib/puppeteer/page.rb +29 -11
  93. data/lib/puppeteer/version.rb +1 -1
  94. data/lib/puppeteer/wait_task.rb +183 -1
  95. metadata +3 -2
@@ -173,11 +173,11 @@ class Puppeteer::Frame
173
173
  @secondary_world.tap(selector)
174
174
  end
175
175
 
176
- # @param {string} selector
177
- # @param {string} text
178
- # @param {{delay: (number|undefined)}=} options
179
- def type(selector, text, delay: nil)
180
- @main_world.type(selector, text, delay: delay)
176
+ # @param selector [String]
177
+ # @param text [String]
178
+ # @param delay [Number]
179
+ def type_text(selector, text, delay: nil)
180
+ @main_world.type_text(selector, text, delay: delay)
181
181
  end
182
182
 
183
183
  # /**
@@ -202,9 +202,10 @@ class Puppeteer::Frame
202
202
  # return Promise.reject(new Error('Unsupported target type: ' + (typeof selectorOrFunctionOrTimeout)));
203
203
  # }
204
204
 
205
- # @param {string} selector
206
- # @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
207
- # @return {!Promise<?Puppeteer.ElementHandle>}
205
+ # @param selector [String]
206
+ # @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
207
+ # @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
208
+ # @param timeout [Integer]
208
209
  def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
209
210
  handle = @secondary_world.wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout)
210
211
  if !handle
@@ -216,9 +217,10 @@ class Puppeteer::Frame
216
217
  result
217
218
  end
218
219
 
219
- # @param {string} xpath
220
- # @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
221
- # @return {!Promise<?Puppeteer.ElementHandle>}
220
+ # @param xpath [String]
221
+ # @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
222
+ # @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
223
+ # @param timeout [Integer]
222
224
  def wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil)
223
225
  handle = @secondary_world.wait_for_xpath(xpath, visible: visible, hidden: hidden, timeout: timeout)
224
226
  if !handle
@@ -973,11 +973,11 @@ class Puppeteer::Page
973
973
  main_frame.tap(selector)
974
974
  end
975
975
 
976
- # @param {string} selector
977
- # @param {string} text
978
- # @param {{delay: (number|undefined)}=} options
979
- def type(selector, text, delay: nil)
980
- main_frame.type(selector, text, delay: delay)
976
+ # @param selector [String]
977
+ # @param text [String]
978
+ # @param delay [Number]
979
+ def type_text(selector, text, delay: nil)
980
+ main_frame.type_text(selector, text, delay: delay)
981
981
  end
982
982
 
983
983
  # /**
@@ -990,20 +990,38 @@ class Puppeteer::Page
990
990
  # return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
991
991
  # }
992
992
 
993
- # @param {string} selector
994
- # @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
995
- # @return {!Promise<?Puppeteer.ElementHandle>}
993
+ # @param selector [String]
994
+ # @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
995
+ # @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
996
+ # @param timeout [Integer]
996
997
  def wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
997
998
  main_frame.wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout)
998
999
  end
999
1000
 
1000
- # @param {string} xpath
1001
- # @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
1002
- # @return {!Promise<?Puppeteer.ElementHandle>}
1001
+ # @param selector [String]
1002
+ # @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
1003
+ # @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
1004
+ # @param timeout [Integer]
1005
+ async def async_wait_for_selector(selector, visible: nil, hidden: nil, timeout: nil)
1006
+ wait_for_selector(selector, visible: visible, hidden: hidden, timeout: timeout)
1007
+ end
1008
+
1009
+ # @param xpath [String]
1010
+ # @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
1011
+ # @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
1012
+ # @param timeout [Integer]
1003
1013
  def wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil)
1004
1014
  main_frame.wait_for_xpath(xpath, visible: visible, hidden: hidden, timeout: timeout)
1005
1015
  end
1006
1016
 
1017
+ # @param xpath [String]
1018
+ # @param visible [Boolean] Wait for element visible (not 'display: none' nor 'visibility: hidden') on true. default to false.
1019
+ # @param hidden [Boolean] Wait for element invisible ('display: none' nor 'visibility: hidden') on true. default to false.
1020
+ # @param timeout [Integer]
1021
+ async def async_wait_for_xpath(xpath, visible: nil, hidden: nil, timeout: nil)
1022
+ wait_for_xpath(xpath, visible: visible, hidden: hidden, timeout: timeout)
1023
+ end
1024
+
1007
1025
  # @param {Function|string} pageFunction
1008
1026
  # @param {!{polling?: string|number, timeout?: number}=} options
1009
1027
  # @param {!Array<*>} args
@@ -1,3 +1,3 @@
1
1
  class Puppeteer
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
@@ -1,6 +1,188 @@
1
1
  class Puppeteer::WaitTask
2
+ using Puppeteer::AsyncAwaitBehavior
3
+
2
4
  class TerminatedError < StandardError; end
3
5
 
4
- def initialize
6
+ class TimeoutError < StandardError
7
+ def initialize(title:, timeout:)
8
+ super("waiting for #{title} failed: timeout #{timeout}ms exceeded")
9
+ end
10
+ end
11
+
12
+ def initialize(dom_world:, predicate_body:, title:, polling:, timeout:, args: [])
13
+ if polling.is_a?(String)
14
+ if polling != 'raf' && polling != 'mutation'
15
+ raise ArgumentError.new("Unknown polling option: #{polling}")
16
+ end
17
+ elsif polling.is_a?(Numeric)
18
+ unless polling.positive?
19
+ raise ArgumentError.new("Cannot poll with non-positive interval: #{polling}")
20
+ end
21
+ else
22
+ raise ArgumentError.new("Unknown polling options: #{polling}")
23
+ end
24
+
25
+ @dom_world = dom_world
26
+ @polling = polling
27
+ @timeout = timeout
28
+ @predicate_body = predicate_body
29
+ @args = args
30
+ @run_count = 0
31
+ @dom_world._wait_tasks.add(self)
32
+ @promise = resolvable_future
33
+
34
+ # Since page navigation requires us to re-install the pageScript, we should track
35
+ # timeout on our end.
36
+ if timeout
37
+ timeout_error = TimeoutError.new(title: title, timeout: timeout)
38
+ Concurrent::Promises.schedule(timeout / 1000.0) { terminate(timeout_error) unless @timeout_cleared }
39
+ end
40
+ async_rerun
41
+ end
42
+
43
+ # @return [Puppeteer::JSHandle]
44
+ def await_promise
45
+ @promise.value!
46
+ end
47
+
48
+ def terminate(error)
49
+ @terminated = true
50
+ @promise.reject(error)
51
+ cleanup
52
+ end
53
+
54
+ def rerun
55
+ run_count = (@run_count += 1)
56
+ begin
57
+ success = @dom_world.execution_context.evaluate_handle(
58
+ WAIT_FOR_PREDICATE_PAGE_FUNCTION,
59
+ @predicate_body,
60
+ @polling,
61
+ @timeout,
62
+ *@args,
63
+ )
64
+ rescue => err
65
+ error = err
66
+ end
67
+
68
+ if @terminated || run_count != @run_count
69
+ if success
70
+ success.dispose
71
+ end
72
+ return
73
+ end
74
+
75
+ # Ignore timeouts in pageScript - we track timeouts ourselves.
76
+ # If the frame's execution context has already changed, `frame.evaluate` will
77
+ # throw an error - ignore this predicate run altogether.
78
+ if !error && (@dom_world.evaluate("s => !s", success) rescue true)
79
+ success.dispose
80
+ return
81
+ end
82
+
83
+ # When the page is navigated, the promise is rejected.
84
+ # We will try again in the new execution context.
85
+ if error && error.message.include?('Execution context was destroyed')
86
+ return
87
+ end
88
+
89
+ # We could have tried to evaluate in a context which was already
90
+ # destroyed.
91
+ if error && error.message.include?('Cannot find context with specified id')
92
+ return
93
+ end
94
+
95
+ if error
96
+ @promise.reject(error)
97
+ else
98
+ @promise.fulfill(success)
99
+ end
100
+
101
+ cleanup
5
102
  end
103
+
104
+ private def cleanup
105
+ @timeout_cleared = true
106
+ @dom_world._wait_tasks.delete(self)
107
+ end
108
+
109
+ private async def async_rerun
110
+ rerun
111
+ end
112
+
113
+ WAIT_FOR_PREDICATE_PAGE_FUNCTION = <<~JAVASCRIPT
114
+ async function _(predicateBody, polling, timeout, ...args) {
115
+ const predicate = new Function('...args', predicateBody);
116
+ let timedOut = false;
117
+ if (timeout)
118
+ setTimeout(() => (timedOut = true), timeout);
119
+ if (polling === 'raf')
120
+ return await pollRaf();
121
+ if (polling === 'mutation')
122
+ return await pollMutation();
123
+ if (typeof polling === 'number')
124
+ return await pollInterval(polling);
125
+ /**
126
+ * @return {!Promise<*>}
127
+ */
128
+ function pollMutation() {
129
+ const success = predicate(...args);
130
+ if (success)
131
+ return Promise.resolve(success);
132
+ let fulfill;
133
+ const result = new Promise((x) => (fulfill = x));
134
+ const observer = new MutationObserver(() => {
135
+ if (timedOut) {
136
+ observer.disconnect();
137
+ fulfill();
138
+ }
139
+ const success = predicate(...args);
140
+ if (success) {
141
+ observer.disconnect();
142
+ fulfill(success);
143
+ }
144
+ });
145
+ observer.observe(document, {
146
+ childList: true,
147
+ subtree: true,
148
+ attributes: true,
149
+ });
150
+ return result;
151
+ }
152
+ function pollRaf() {
153
+ let fulfill;
154
+ const result = new Promise((x) => (fulfill = x));
155
+ onRaf();
156
+ return result;
157
+ function onRaf() {
158
+ if (timedOut) {
159
+ fulfill();
160
+ return;
161
+ }
162
+ const success = predicate(...args);
163
+ if (success)
164
+ fulfill(success);
165
+ else
166
+ requestAnimationFrame(onRaf);
167
+ }
168
+ }
169
+ function pollInterval(pollInterval) {
170
+ let fulfill;
171
+ const result = new Promise((x) => (fulfill = x));
172
+ onTimeout();
173
+ return result;
174
+ function onTimeout() {
175
+ if (timedOut) {
176
+ fulfill();
177
+ return;
178
+ }
179
+ const success = predicate(...args);
180
+ if (success)
181
+ fulfill(success);
182
+ else
183
+ setTimeout(onTimeout, pollInterval);
184
+ }
185
+ }
186
+ }
187
+ JAVASCRIPT
6
188
  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.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-29 00:00:00.000000000 Z
11
+ date: 2020-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -258,6 +258,7 @@ files:
258
258
  - docs/Puppeteer/Viewport.html
259
259
  - docs/Puppeteer/WaitTask.html
260
260
  - docs/Puppeteer/WaitTask/TerminatedError.html
261
+ - docs/Puppeteer/WaitTask/TimeoutError.html
261
262
  - docs/Puppeteer/WebSocket.html
262
263
  - docs/Puppeteer/WebSocket/DriverImpl.html
263
264
  - docs/Puppeteer/WebSocketTransport.html