puppeteer-ruby 0.0.5 → 0.0.6

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