puppeteer-ruby 0.0.11 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +0 -12
  3. data/.github/workflows/docs.yml +45 -0
  4. data/.github/workflows/reviewdog.yml +15 -0
  5. data/README.md +54 -1
  6. data/lib/puppeteer.rb +39 -13
  7. data/lib/puppeteer/browser.rb +22 -25
  8. data/lib/puppeteer/cdp_session.rb +3 -19
  9. data/lib/puppeteer/concurrent_ruby_utils.rb +12 -2
  10. data/lib/puppeteer/connection.rb +3 -15
  11. data/lib/puppeteer/define_async_method.rb +23 -0
  12. data/lib/puppeteer/dom_world.rb +51 -65
  13. data/lib/puppeteer/element_handle.rb +15 -44
  14. data/lib/puppeteer/emulation_manager.rb +2 -6
  15. data/lib/puppeteer/event_callbackable.rb +11 -0
  16. data/lib/puppeteer/execution_context.rb +1 -6
  17. data/lib/puppeteer/frame.rb +34 -39
  18. data/lib/puppeteer/frame_manager.rb +7 -25
  19. data/lib/puppeteer/js_handle.rb +3 -12
  20. data/lib/puppeteer/keyboard.rb +6 -27
  21. data/lib/puppeteer/launcher.rb +6 -6
  22. data/lib/puppeteer/launcher/chrome.rb +10 -8
  23. data/lib/puppeteer/mouse.rb +5 -25
  24. data/lib/puppeteer/network_manager.rb +163 -5
  25. data/lib/puppeteer/page.rb +230 -177
  26. data/lib/puppeteer/page/pdf_options.rb +166 -0
  27. data/lib/puppeteer/remote_object.rb +2 -5
  28. data/lib/puppeteer/request.rb +336 -0
  29. data/lib/puppeteer/response.rb +113 -0
  30. data/lib/puppeteer/target.rb +1 -1
  31. data/lib/puppeteer/touch_screen.rb +2 -7
  32. data/lib/puppeteer/version.rb +1 -1
  33. data/lib/puppeteer/wait_task.rb +2 -4
  34. data/lib/puppeteer/web_socket_transport.rb +8 -8
  35. data/puppeteer-ruby.gemspec +1 -1
  36. data/puppeteer-ruby.png +0 -0
  37. metadata +11 -105
  38. data/Dockerfile +0 -6
  39. data/docker-compose.yml +0 -15
  40. data/docs/Puppeteer.html +0 -2020
  41. data/docs/Puppeteer/AsyncAwaitBehavior.html +0 -105
  42. data/docs/Puppeteer/Browser.html +0 -2258
  43. data/docs/Puppeteer/BrowserContext.html +0 -809
  44. data/docs/Puppeteer/BrowserFetcher.html +0 -214
  45. data/docs/Puppeteer/BrowserRunner.html +0 -914
  46. data/docs/Puppeteer/BrowserRunner/BrowserProcess.html +0 -477
  47. data/docs/Puppeteer/CDPSession.html +0 -813
  48. data/docs/Puppeteer/CDPSession/Error.html +0 -124
  49. data/docs/Puppeteer/ConcurrentRubyUtils.html +0 -430
  50. data/docs/Puppeteer/Connection.html +0 -964
  51. data/docs/Puppeteer/Connection/MessageCallback.html +0 -434
  52. data/docs/Puppeteer/Connection/ProtocolError.html +0 -216
  53. data/docs/Puppeteer/Connection/RequestDebugPrinter.html +0 -217
  54. data/docs/Puppeteer/Connection/ResponseDebugPrinter.html +0 -244
  55. data/docs/Puppeteer/ConsoleMessage.html +0 -565
  56. data/docs/Puppeteer/ConsoleMessage/Location.html +0 -433
  57. data/docs/Puppeteer/DOMWorld.html +0 -2219
  58. data/docs/Puppeteer/DOMWorld/DetachedError.html +0 -124
  59. data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +0 -124
  60. data/docs/Puppeteer/DebugPrint.html +0 -233
  61. data/docs/Puppeteer/Device.html +0 -470
  62. data/docs/Puppeteer/Devices.html +0 -139
  63. data/docs/Puppeteer/ElementHandle.html +0 -2542
  64. data/docs/Puppeteer/ElementHandle/BoundingBox.html +0 -507
  65. data/docs/Puppeteer/ElementHandle/BoxModel.html +0 -404
  66. data/docs/Puppeteer/ElementHandle/ElementNotFoundError.html +0 -206
  67. data/docs/Puppeteer/ElementHandle/ElementNotVisibleError.html +0 -206
  68. data/docs/Puppeteer/ElementHandle/Point.html +0 -492
  69. data/docs/Puppeteer/ElementHandle/ScrollIntoViewError.html +0 -124
  70. data/docs/Puppeteer/EmulationManager.html +0 -454
  71. data/docs/Puppeteer/EventCallbackable.html +0 -433
  72. data/docs/Puppeteer/EventCallbackable/EventListeners.html +0 -435
  73. data/docs/Puppeteer/ExecutionContext.html +0 -998
  74. data/docs/Puppeteer/ExecutionContext/EvaluationError.html +0 -124
  75. data/docs/Puppeteer/ExecutionContext/JavaScriptExpression.html +0 -357
  76. data/docs/Puppeteer/ExecutionContext/JavaScriptFunction.html +0 -389
  77. data/docs/Puppeteer/FileChooser.html +0 -455
  78. data/docs/Puppeteer/Frame.html +0 -3813
  79. data/docs/Puppeteer/FrameManager.html +0 -2410
  80. data/docs/Puppeteer/FrameManager/NavigationError.html +0 -124
  81. data/docs/Puppeteer/IfPresent.html +0 -222
  82. data/docs/Puppeteer/JSHandle.html +0 -1352
  83. data/docs/Puppeteer/Keyboard.html +0 -1557
  84. data/docs/Puppeteer/Keyboard/KeyDefinition.html +0 -831
  85. data/docs/Puppeteer/Keyboard/KeyDescription.html +0 -603
  86. data/docs/Puppeteer/Launcher.html +0 -237
  87. data/docs/Puppeteer/Launcher/Base.html +0 -385
  88. data/docs/Puppeteer/Launcher/Base/ExecutablePathNotFound.html +0 -124
  89. data/docs/Puppeteer/Launcher/BrowserOptions.html +0 -441
  90. data/docs/Puppeteer/Launcher/Chrome.html +0 -669
  91. data/docs/Puppeteer/Launcher/Chrome/DefaultArgs.html +0 -382
  92. data/docs/Puppeteer/Launcher/ChromeArgOptions.html +0 -531
  93. data/docs/Puppeteer/Launcher/LaunchOptions.html +0 -893
  94. data/docs/Puppeteer/LifecycleWatcher.html +0 -834
  95. data/docs/Puppeteer/LifecycleWatcher/ExpectedLifecycle.html +0 -363
  96. data/docs/Puppeteer/LifecycleWatcher/FrameDetachedError.html +0 -206
  97. data/docs/Puppeteer/LifecycleWatcher/TerminatedError.html +0 -124
  98. data/docs/Puppeteer/Mouse.html +0 -1095
  99. data/docs/Puppeteer/Mouse/Button.html +0 -136
  100. data/docs/Puppeteer/NetworkManager.html +0 -901
  101. data/docs/Puppeteer/NetworkManager/Credentials.html +0 -385
  102. data/docs/Puppeteer/Page.html +0 -5970
  103. data/docs/Puppeteer/Page/FileChooserTimeoutError.html +0 -206
  104. data/docs/Puppeteer/Page/ScreenshotOptions.html +0 -845
  105. data/docs/Puppeteer/Page/ScriptTag.html +0 -555
  106. data/docs/Puppeteer/Page/StyleTag.html +0 -448
  107. data/docs/Puppeteer/Page/TargetCrashedError.html +0 -124
  108. data/docs/Puppeteer/RemoteObject.html +0 -1087
  109. data/docs/Puppeteer/Target.html +0 -1336
  110. data/docs/Puppeteer/Target/InitializeFailure.html +0 -124
  111. data/docs/Puppeteer/Target/TargetInfo.html +0 -729
  112. data/docs/Puppeteer/TimeoutError.html +0 -135
  113. data/docs/Puppeteer/TimeoutSettings.html +0 -496
  114. data/docs/Puppeteer/TouchScreen.html +0 -464
  115. data/docs/Puppeteer/Viewport.html +0 -837
  116. data/docs/Puppeteer/WaitTask.html +0 -637
  117. data/docs/Puppeteer/WaitTask/TerminatedError.html +0 -124
  118. data/docs/Puppeteer/WaitTask/TimeoutError.html +0 -206
  119. data/docs/Puppeteer/WebSocket.html +0 -673
  120. data/docs/Puppeteer/WebSocket/DriverImpl.html +0 -412
  121. data/docs/Puppeteer/WebSocket/TransportError.html +0 -124
  122. data/docs/Puppeteer/WebSocketTransport.html +0 -600
  123. data/docs/Puppeteer/WebSocktTransportError.html +0 -124
  124. data/docs/_index.html +0 -816
  125. data/docs/class_list.html +0 -51
  126. data/docs/css/common.css +0 -1
  127. data/docs/css/full_list.css +0 -58
  128. data/docs/css/style.css +0 -496
  129. data/docs/file.README.html +0 -123
  130. data/docs/file_list.html +0 -56
  131. data/docs/frames.html +0 -17
  132. data/docs/index.html +0 -123
  133. data/docs/js/app.js +0 -314
  134. data/docs/js/full_list.js +0 -216
  135. data/docs/js/jquery.js +0 -4
  136. data/docs/method_list.html +0 -4091
  137. data/docs/top-level-namespace.html +0 -126
  138. data/lib/puppeteer/async_await_behavior.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a07fd2c57e3c62d4707af33800a1b8c4470324c1b42e4a30646799d773008919
4
- data.tar.gz: ebef1b4801f825d61227e802009dc0ba265f9a934713aee77378da04e8b00788
3
+ metadata.gz: 38a6ae4190bd04cbacb863d04f9862ebc8a37c6811fbfd690426ba051d5ea5d4
4
+ data.tar.gz: 60b61e143e63ed5e42b0bb6f3d9e5c27262fd2f51064c185e491056a5081707d
5
5
  SHA512:
6
- metadata.gz: d953d0f11e1c764bbd046d8124306231f3f735a7cf39566d15c357694d96f8305319eddd914e6e53232fc860d1b64b7e4389700311e917f1117de310a2c76a99
7
- data.tar.gz: 8f87363c9b82ff27c8747423c74d25f98a19a9b288a77fbb46cd5336a65ad2555d13d58778734a1a4c47589e0c956da4385879e988b29b444a90261f3b6fb94e
6
+ metadata.gz: fc3ab652476ee319fab2d691173a0175d4b03d72346329f2fb855a142c3090693f1fb5cfa52abb4badbfbadc7d4eec5028a295f63fb7ddd3e362321564a96b7c
7
+ data.tar.gz: 6de2484b1b939c3cab1bfa48bb2225c54686f13e7901f3df086d8e5c7b18aa9fc62afb5fd9a785a3fbbf12d2aef50cde1d085f3564ce9afab996f80a39c64936
@@ -18,17 +18,6 @@ jobs:
18
18
  --out test_results/rspec.xml \
19
19
  --format progress
20
20
 
21
- rubocop:
22
- docker:
23
- - image: circleci/ruby:2.6.3-stretch-node
24
- executor: ruby/default
25
- steps:
26
- - checkout
27
- - ruby/bundle-install
28
- - run:
29
- name: rubocop
30
- command: bundle exec rubocop
31
-
32
21
  deploy:
33
22
  docker:
34
23
  - image: circleci/ruby:2.6.3-stretch-node
@@ -60,7 +49,6 @@ workflows:
60
49
  ci:
61
50
  jobs:
62
51
  - rspec
63
- - rubocop
64
52
  rubygems-deploy:
65
53
  jobs:
66
54
  - deploy:
@@ -0,0 +1,45 @@
1
+ name: update docs
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+
7
+ jobs:
8
+ update-docs:
9
+ name: update docs
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.6
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ gem uninstall bundler
24
+ gem install bundler -v 1.17
25
+ bundle install
26
+
27
+ - name: Deploy Configuration
28
+ run: |
29
+ mkdir ~/.ssh
30
+ ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
31
+ echo "${{ secrets.DOCS_DEPLOY_SSH_RSA }}" | base64 -d > ~/.ssh/id_rsa
32
+ chmod 400 ~/.ssh/id_rsa
33
+
34
+ - name: Build and Push
35
+ run: |
36
+ git clone git@github.com:YusukeIwaki/puppeteer-ruby-docs.git docs
37
+ rm -rf docs/*
38
+ bundle exec yardoc -o docs
39
+ cp puppeteer-ruby.png docs/
40
+ cd docs/
41
+ git add -A
42
+ git config user.name github
43
+ git config user.email github@example.com
44
+ git commit -m ${{ github.sha }}
45
+ git push origin master
@@ -0,0 +1,15 @@
1
+ name: reviewdog
2
+ on: [pull_request]
3
+ jobs:
4
+ rubocop:
5
+ name: runner / rubocop
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - name: Check out code
9
+ uses: actions/checkout@v2
10
+ - name: rubocop
11
+ uses: reviewdog/action-rubocop@v1
12
+ with:
13
+ github_token: ${{ secrets.github_token }}
14
+ reporter: github-pr-review
15
+ rubocop_version: 0.86.0
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A Ruby port of [puppeteer](https://pptr.dev/).
4
4
 
5
+ ![logo](puppeteer-ruby.png)
6
+
5
7
  REMARK: This Gem is NOT production-ready!!
6
8
 
7
9
  ## Getting Started
@@ -45,9 +47,60 @@ end
45
47
 
46
48
  More usage examples can be found [here](https://github.com/YusukeIwaki/puppeteer-ruby-example)
47
49
 
50
+ ## Collaboration with Selenium or Capybara
51
+
52
+ It is really remarkable that we can use puppeteer functions in existing Selenium or Capybara codes, with a few configuration in advance.
53
+
54
+ ```ruby
55
+ require 'spec_helper'
56
+
57
+ RSpec.describe 'hotel.testplanisphere.dev', type: :feature do
58
+ before {
59
+ visit 'https://hotel.testplanisphere.dev/'
60
+
61
+ # acquire Puppeteer::Browser instance, by connecting Chrome with DevTools Protocol.
62
+ @browser = Puppeteer.connect(
63
+ browser_url: 'http://localhost:9222',
64
+ default_viewport: Puppeteer::Viewport.new(width: 1280, height: 800))
65
+ }
66
+
67
+ after {
68
+ # release Puppeteer::Browser reesource.
69
+ @browser.disconnect
70
+ }
71
+
72
+ it 'can be handled with puppeteer and assert with Capybara' do
73
+ # automation with puppeteer
74
+ puppeteer_page = @browser.pages.first
75
+ puppeteer_page.wait_for_selector('li.nav-item')
76
+
77
+ reservation_link = puppeteer_page.SS('li.nav-item')[1]
78
+
79
+ await_all(
80
+ puppeteer_page.async_wait_for_navigation,
81
+ reservation_link.async_click,
82
+ )
83
+
84
+ # expectation with Capybara DSL
85
+ expect(page).to have_text('宿泊プラン一覧')
86
+ end
87
+
88
+ it 'can be handled with Capybara and assert with puppeteer' do
89
+ # automation with Capybara
90
+ page.all('li.nav-item')[1].click
91
+
92
+ # expectation with puppeteer
93
+ puppeteer_page = @browser.pages.first
94
+ body_text = puppeteer_page.Seval('body', '(el) => el.textContent')
95
+ expect(body_text).to include('宿泊プラン一覧')
96
+ end
97
+ ```
98
+
99
+ The detailed step of configuration can be found [here](https://github.com/YusukeIwaki/puppeteer-ruby-example/tree/master/_with_capybara-rspec).
100
+
48
101
  ## API
49
102
 
50
- https://yusukeiwaki.github.io/puppeteer-ruby/
103
+ https://yusukeiwaki.github.io/puppeteer-ruby-docs/
51
104
 
52
105
  ## Contributing
53
106
 
@@ -8,8 +8,8 @@ require 'puppeteer/errors'
8
8
  require 'puppeteer/viewport'
9
9
 
10
10
  # Modules
11
- require 'puppeteer/async_await_behavior'
12
11
  require 'puppeteer/concurrent_ruby_utils'
12
+ require 'puppeteer/define_async_method'
13
13
  require 'puppeteer/debug_print'
14
14
  require 'puppeteer/event_callbackable'
15
15
  require 'puppeteer/if_present'
@@ -36,6 +36,8 @@ require 'puppeteer/mouse'
36
36
  require 'puppeteer/network_manager'
37
37
  require 'puppeteer/page'
38
38
  require 'puppeteer/remote_object'
39
+ require 'puppeteer/request'
40
+ require 'puppeteer/response'
39
41
  require 'puppeteer/target'
40
42
  require 'puppeteer/timeout_settings'
41
43
  require 'puppeteer/touch_screen'
@@ -63,17 +65,33 @@ class Puppeteer
63
65
  end
64
66
  end
65
67
 
66
- # @param {string} projectRoot
67
- # @param {string} preferredRevision
68
- # @param {boolean} isPuppeteerCore
68
+ # @param project_root [String]
69
+ # @param prefereed_revision [String]
70
+ # @param is_puppeteer_core [String]
69
71
  def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
70
72
  @project_root = project_root
71
73
  @preferred_revision = preferred_revision
72
74
  @is_puppeteer_core = is_puppeteer_core
73
75
  end
74
76
 
75
- # @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions & {product?: string, extraPrefsFirefox?: !object})=} options
76
- # @return {!Promise<!Puppeteer.Browser>}
77
+ # @param product [String]
78
+ # @param executable_path [String]
79
+ # @param ignore_default_args [Array<String>|nil]
80
+ # @param handle_SIGINT [Boolean]
81
+ # @param handle_SIGTERM [Boolean]
82
+ # @param handle_SIGHUP [Boolean]
83
+ # @param timeout [Integer]
84
+ # @param dumpio [Boolean]
85
+ # @param env [Hash]
86
+ # @param pipe [Boolean]
87
+ # @param args [Array<String>]
88
+ # @param user_data_dir [String]
89
+ # @param devtools [Boolean]
90
+ # @param headless [Boolean]
91
+ # @param ignore_https_errors [Boolean]
92
+ # @param default_viewport [Puppeteer::Viewport|nil]
93
+ # @param slow_mo [Integer]
94
+ # @return [Puppeteer::Browser]
77
95
  def launch(
78
96
  product: nil,
79
97
  executable_path: nil,
@@ -125,8 +143,13 @@ class Puppeteer
125
143
  end
126
144
  end
127
145
 
128
- # @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserURL?: string, transport?: !Puppeteer.ConnectionTransport})} options
129
- # @return {!Promise<!Puppeteer.Browser>}
146
+ # @param browser_ws_endpoint [String]
147
+ # @param browser_url [String]
148
+ # @param transport [Puppeteer::WebSocketTransport]
149
+ # @param ignore_https_errors [Boolean]
150
+ # @param default_viewport [Puppeteer::Viewport|nil]
151
+ # @param slow_mo [Integer]
152
+ # @return [Puppeteer::Browser]
130
153
  def connect(
131
154
  browser_ws_endpoint: nil,
132
155
  browser_url: nil,
@@ -151,7 +174,7 @@ class Puppeteer
151
174
  end
152
175
  end
153
176
 
154
- # @return {string}
177
+ # @return [String]
155
178
  def executable_path
156
179
  launcher.executable_path
157
180
  end
@@ -165,12 +188,12 @@ class Puppeteer
165
188
  )
166
189
  end
167
190
 
168
- # @return {string}
191
+ # @return [String]
169
192
  def product
170
193
  launcher.product
171
194
  end
172
195
 
173
- # @return {Puppeteer::Devices}
196
+ # @return [Puppeteer::Devices]
174
197
  def devices
175
198
  Puppeteer::Devices
176
199
  end
@@ -180,8 +203,11 @@ class Puppeteer
180
203
  # # ???
181
204
  # end
182
205
 
183
- # @param {!Launcher.ChromeArgOptions=} options
184
- # @return {!Array<string>}
206
+ # @param args [Array<String>]
207
+ # @param user_data_dir [String]
208
+ # @param devtools [Boolean]
209
+ # @param headless [Boolean]
210
+ # @return [Array<String>]
185
211
  def default_args(args: nil, user_data_dir: nil, devtools: nil, headless: nil)
186
212
  options = {
187
213
  args: args,
@@ -5,7 +5,7 @@ class Puppeteer::Browser
5
5
  include Puppeteer::DebugPrint
6
6
  include Puppeteer::EventCallbackable
7
7
  include Puppeteer::IfPresent
8
- using Puppeteer::AsyncAwaitBehavior
8
+ using Puppeteer::DefineAsyncMethod
9
9
 
10
10
  # @param {!Puppeteer.Connection} connection
11
11
  # @param {!Array<string>} contextIds
@@ -97,6 +97,12 @@ class Puppeteer::Browser
97
97
  @contexts.remove(context_id)
98
98
  end
99
99
 
100
+ class TargetAlreadyExistError < StandardError
101
+ def initialize
102
+ super('Target should not exist before targetCreated')
103
+ end
104
+ end
105
+
100
106
  # @param {!Protocol.Target.targetCreatedPayload} event
101
107
  def handle_target_created(event)
102
108
  target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
@@ -108,6 +114,9 @@ class Puppeteer::Browser
108
114
  @default_context
109
115
  end
110
116
 
117
+ if @targets[target_info.target_id]
118
+ raise TargetAlreadyExistError.new
119
+ end
111
120
  target = Puppeteer::Target.new(
112
121
  target_info: target_info,
113
122
  browser_context: context,
@@ -122,13 +131,8 @@ class Puppeteer::Browser
122
131
  emit_event 'Events.Browser.TargetCreated', target
123
132
  context.emit_event 'Events.BrowserContext.TargetCreated', target
124
133
  end
125
-
126
- if_present(pending_target_info_changed_event.delete(target_info.target_id)) do |pending_event|
127
- handle_target_info_changed(pending_event)
128
- end
129
134
  end
130
135
 
131
-
132
136
  # @param {{targetId: string}} event
133
137
  def handle_target_destroyed(event)
134
138
  target_id = event['targetId']
@@ -142,24 +146,16 @@ class Puppeteer::Browser
142
146
  end
143
147
  end
144
148
 
149
+ class TargetNotExistError < StandardError
150
+ def initialize
151
+ super('target should exist before targetInfoChanged')
152
+ end
153
+ end
154
+
145
155
  # @param {!Protocol.Target.targetInfoChangedPayload} event
146
156
  def handle_target_info_changed(event)
147
157
  target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
148
- target = @targets[target_info.target_id]
149
- if !target
150
- # targetCreated is sometimes notified after targetInfoChanged.
151
- # We don't raise error. Instead, keep the event as a pending change,
152
- # and handle it on handle_target_created.
153
- #
154
- # D, [2020-04-22T00:22:26.630328 #79646] DEBUG -- : RECV << {"method"=>"Target.targetInfoChanged", "params"=>{"targetInfo"=>{"targetId"=>"8068CED48357B9557EEC85AA62165A8E", "type"=>"iframe", "title"=>"", "url"=>"", "attached"=>true, "browserContextId"=>"7895BFB24BF22CE40584808713D96E8D"}}}
155
- # E, [2020-04-22T00:22:26.630448 #79646] ERROR -- : target should exist before targetInfoChanged (StandardError)
156
- # D, [2020-04-22T00:22:26.630648 #79646] DEBUG -- : RECV << {"method"=>"Target.targetCreated", "params"=>{"targetInfo"=>{"targetId"=>"8068CED48357B9557EEC85AA62165A8E", "type"=>"iframe", "title"=>"", "url"=>"", "attached"=>false, "browserContextId"=>"7895BFB24BF22CE40584808713D96E8D"}}}
157
- pending_target_info_changed_event[target_info.target_id] = event
158
- return
159
- # original implementation is:
160
- #
161
- # raise StandardError.new('target should exist before targetInfoChanged')
162
- end
158
+ target = @targets[target_info.target_id] or raise TargetNotExistError.new
163
159
  previous_url = target.url
164
160
  was_initialized = target.initialized?
165
161
  target.handle_target_info_changed(target_info)
@@ -169,10 +165,6 @@ class Puppeteer::Browser
169
165
  end
170
166
  end
171
167
 
172
- private def pending_target_info_changed_event
173
- @pending_target_info_changed_event ||= {}
174
- end
175
-
176
168
  # @return [String]
177
169
  def websocket_endpoint
178
170
  @connection.url
@@ -207,6 +199,11 @@ class Puppeteer::Browser
207
199
  targets.first { |target| target.type == 'browser' }
208
200
  end
209
201
 
202
+ # used only in Target#opener
203
+ private def find_target_by_id(target_id)
204
+ @targets[target_id]
205
+ end
206
+
210
207
  # @param {function(!Target):boolean} predicate
211
208
  # @param {{timeout?: number}=} options
212
209
  # @return {!Promise<!Target>}
@@ -1,7 +1,7 @@
1
1
  class Puppeteer::CDPSession
2
2
  include Puppeteer::DebugPrint
3
3
  include Puppeteer::EventCallbackable
4
- using Puppeteer::AsyncAwaitBehavior
4
+ using Puppeteer::DefineAsyncMethod
5
5
 
6
6
  class Error < StandardError; end
7
7
 
@@ -13,7 +13,6 @@ class Puppeteer::CDPSession
13
13
  @connection = connection
14
14
  @target_type = target_type
15
15
  @session_id = session_id
16
- @pending_messages = {}
17
16
  end
18
17
 
19
18
  attr_reader :connection
@@ -35,12 +34,7 @@ class Puppeteer::CDPSession
35
34
  id = @connection.raw_send(message: { sessionId: @session_id, method: method, params: params })
36
35
  promise = resolvable_future
37
36
  callback = Puppeteer::Connection::MessageCallback.new(method: method, promise: promise)
38
- if pending_message = @pending_messages.delete(id)
39
- debug_puts "Pending message (id: #{id}) is handled"
40
- callback_with_message(callback, pending_message)
41
- else
42
- @callbacks[id] = callback
43
- end
37
+ @callbacks[id] = callback
44
38
  promise
45
39
  end
46
40
 
@@ -50,17 +44,7 @@ class Puppeteer::CDPSession
50
44
  if callback = @callbacks.delete(message['id'])
51
45
  callback_with_message(callback, message)
52
46
  else
53
- debug_puts "unknown id: #{id}. Store it into pending message"
54
-
55
- # RECV is often notified before SEND.
56
- # Wait about 10 frames before throwing an error.
57
- message_id = message['id']
58
- @pending_messages[message_id] = message
59
- Concurrent::Promises.schedule(0.16, message_id) do |id|
60
- if @pending_messages.delete(id)
61
- raise Error.new("unknown id: #{id}")
62
- end
63
- end
47
+ raise Error.new("unknown id: #{id}")
64
48
  end
65
49
  else
66
50
  emit_event message['method'], message['params']
@@ -1,5 +1,8 @@
1
1
  # utility methods for Concurrent::Promises.
2
2
  module Puppeteer::ConcurrentRubyUtils
3
+ # wait for all promises.
4
+ # REMARK: This method doesn't assure the order of calling.
5
+ # for example, await_all(async1, async2) calls calls2 -> calls1 often.
3
6
  def await_all(*args)
4
7
  if args.length == 1 && args[0].is_a?(Enumerable)
5
8
  Concurrent::Promises.zip(*(args[0])).value!
@@ -8,6 +11,9 @@ module Puppeteer::ConcurrentRubyUtils
8
11
  end
9
12
  end
10
13
 
14
+ # wait for first promises.
15
+ # REMARK: This method doesn't assure the order of calling.
16
+ # for example, await_all(async1, async2) calls calls2 -> calls1 often.
11
17
  def await_any(*args)
12
18
  if args.length == 1 && args[0].is_a?(Enumerable)
13
19
  Concurrent::Promises.any(*(args[0])).value!
@@ -29,8 +35,12 @@ module Puppeteer::ConcurrentRubyUtils
29
35
  Concurrent::Promises.future(&block)
30
36
  end
31
37
 
32
- def resolvable_future
33
- Concurrent::Promises.resolvable_future
38
+ def resolvable_future(&block)
39
+ future = Concurrent::Promises.resolvable_future
40
+ if block
41
+ block.call(future)
42
+ end
43
+ future
34
44
  end
35
45
  end
36
46