puppeteer-ruby 0.0.9 → 0.0.14

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 (137) 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 +37 -13
  7. data/lib/puppeteer/browser.rb +40 -27
  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 +16 -16
  11. data/lib/puppeteer/define_async_method.rb +23 -0
  12. data/lib/puppeteer/dom_world.rb +17 -33
  13. data/lib/puppeteer/element_handle.rb +80 -151
  14. data/lib/puppeteer/element_handle/bounding_box.rb +12 -0
  15. data/lib/puppeteer/element_handle/box_model.rb +19 -0
  16. data/lib/puppeteer/element_handle/point.rb +26 -0
  17. data/lib/puppeteer/emulation_manager.rb +2 -6
  18. data/lib/puppeteer/errors.rb +1 -3
  19. data/lib/puppeteer/event_callbackable.rb +11 -0
  20. data/lib/puppeteer/execution_context.rb +1 -6
  21. data/lib/puppeteer/frame.rb +34 -1
  22. data/lib/puppeteer/frame_manager.rb +7 -25
  23. data/lib/puppeteer/js_handle.rb +3 -12
  24. data/lib/puppeteer/keyboard.rb +6 -27
  25. data/lib/puppeteer/launcher.rb +6 -6
  26. data/lib/puppeteer/launcher/chrome.rb +10 -8
  27. data/lib/puppeteer/mouse.rb +8 -33
  28. data/lib/puppeteer/page.rb +82 -67
  29. data/lib/puppeteer/remote_object.rb +11 -5
  30. data/lib/puppeteer/target.rb +10 -13
  31. data/lib/puppeteer/touch_screen.rb +2 -7
  32. data/lib/puppeteer/version.rb +1 -1
  33. data/lib/puppeteer/viewport.rb +18 -0
  34. data/lib/puppeteer/wait_task.rb +2 -4
  35. data/lib/puppeteer/web_socket.rb +3 -1
  36. data/lib/puppeteer/web_socket_transport.rb +8 -8
  37. data/puppeteer-ruby.gemspec +1 -1
  38. data/puppeteer-ruby.png +0 -0
  39. metadata +11 -102
  40. data/Dockerfile +0 -6
  41. data/docker-compose.yml +0 -15
  42. data/docs/Puppeteer.html +0 -2020
  43. data/docs/Puppeteer/AsyncAwaitBehavior.html +0 -105
  44. data/docs/Puppeteer/Browser.html +0 -2148
  45. data/docs/Puppeteer/BrowserContext.html +0 -809
  46. data/docs/Puppeteer/BrowserFetcher.html +0 -214
  47. data/docs/Puppeteer/BrowserRunner.html +0 -914
  48. data/docs/Puppeteer/BrowserRunner/BrowserProcess.html +0 -477
  49. data/docs/Puppeteer/CDPSession.html +0 -813
  50. data/docs/Puppeteer/CDPSession/Error.html +0 -124
  51. data/docs/Puppeteer/ConcurrentRubyUtils.html +0 -430
  52. data/docs/Puppeteer/Connection.html +0 -960
  53. data/docs/Puppeteer/Connection/MessageCallback.html +0 -434
  54. data/docs/Puppeteer/Connection/ProtocolError.html +0 -216
  55. data/docs/Puppeteer/Connection/RequestDebugPrinter.html +0 -217
  56. data/docs/Puppeteer/Connection/ResponseDebugPrinter.html +0 -244
  57. data/docs/Puppeteer/ConsoleMessage.html +0 -565
  58. data/docs/Puppeteer/ConsoleMessage/Location.html +0 -433
  59. data/docs/Puppeteer/DOMWorld.html +0 -2219
  60. data/docs/Puppeteer/DOMWorld/DetachedError.html +0 -124
  61. data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +0 -124
  62. data/docs/Puppeteer/DebugPrint.html +0 -233
  63. data/docs/Puppeteer/Device.html +0 -470
  64. data/docs/Puppeteer/Devices.html +0 -139
  65. data/docs/Puppeteer/ElementHandle.html +0 -2224
  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 -481
  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 -3677
  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 -1105
  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 -1016
  109. data/docs/Puppeteer/Target.html +0 -1314
  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 -757
  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/WebSocketTransport.html +0 -600
  122. data/docs/Puppeteer/WebSocktTransportError.html +0 -124
  123. data/docs/_index.html +0 -809
  124. data/docs/class_list.html +0 -51
  125. data/docs/css/common.css +0 -1
  126. data/docs/css/full_list.css +0 -58
  127. data/docs/css/style.css +0 -496
  128. data/docs/file.README.html +0 -123
  129. data/docs/file_list.html +0 -56
  130. data/docs/frames.html +0 -17
  131. data/docs/index.html +0 -123
  132. data/docs/js/app.js +0 -314
  133. data/docs/js/full_list.js +0 -216
  134. data/docs/js/jquery.js +0 -4
  135. data/docs/method_list.html +0 -3971
  136. data/docs/top-level-namespace.html +0 -126
  137. data/lib/puppeteer/async_await_behavior.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bd4cd6afe37a5975230cc6f9563671881e2fac9cdfed904afcff459cbfdb061
4
- data.tar.gz: abbd2505425e7e9b5b3b878daba8fbbf94c616e7e988ca0722bf96307be0d88b
3
+ metadata.gz: 0a500508a5a1d88ed4694c5614c7c70bdae06d4d5cb10f81c1237ebd25a6623f
4
+ data.tar.gz: 338b902e3c64d9f96e7b7822353a7b664ab112cd3993e7a7ec06cda41752521e
5
5
  SHA512:
6
- metadata.gz: 926da4f494be0bce07cb8788ef379478f997290a3939e72e8aedf6f2f38ebac485fa334805f0c9641a06528d15f4238c40dae549c4fca6ab8bc9876b507cf445
7
- data.tar.gz: 6e86387731a4d22d861e474b18481226bcdc19fe0d699dc1f0e96be1ed07f20d4180dd9f402c8637c1c85318df70e63b162f75aea3ba99716b12bd334d177d00
6
+ metadata.gz: 51ea52a62c04917d5ec62c4224ffe91cacf3ccd3cfc796d94d975c309971dc0e789fdec7f4fabcc37f51619d833f070e7d6136f18cdb7113721382392456dd88
7
+ data.tar.gz: ef643098e96d3d1794470f38befb55039916c13b35d7d133596acf42d7217c302d1de4865c62c178e758aa619063ee9469bbbfcda1665c3e19fcca26aaee12ce
@@ -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'
@@ -63,17 +63,33 @@ class Puppeteer
63
63
  end
64
64
  end
65
65
 
66
- # @param {string} projectRoot
67
- # @param {string} preferredRevision
68
- # @param {boolean} isPuppeteerCore
66
+ # @param project_root [String]
67
+ # @param prefereed_revision [String]
68
+ # @param is_puppeteer_core [String]
69
69
  def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
70
70
  @project_root = project_root
71
71
  @preferred_revision = preferred_revision
72
72
  @is_puppeteer_core = is_puppeteer_core
73
73
  end
74
74
 
75
- # @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions & {product?: string, extraPrefsFirefox?: !object})=} options
76
- # @return {!Promise<!Puppeteer.Browser>}
75
+ # @param product [String]
76
+ # @param executable_path [String]
77
+ # @param ignore_default_args [Array<String>|nil]
78
+ # @param handle_SIGINT [Boolean]
79
+ # @param handle_SIGTERM [Boolean]
80
+ # @param handle_SIGHUP [Boolean]
81
+ # @param timeout [Integer]
82
+ # @param dumpio [Boolean]
83
+ # @param env [Hash]
84
+ # @param pipe [Boolean]
85
+ # @param args [Array<String>]
86
+ # @param user_data_dir [String]
87
+ # @param devtools [Boolean]
88
+ # @param headless [Boolean]
89
+ # @param ignore_https_errors [Boolean]
90
+ # @param default_viewport [Puppeteer::Viewport|nil]
91
+ # @param slow_mo [Integer]
92
+ # @return [Puppeteer::Browser]
77
93
  def launch(
78
94
  product: nil,
79
95
  executable_path: nil,
@@ -125,8 +141,13 @@ class Puppeteer
125
141
  end
126
142
  end
127
143
 
128
- # @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserURL?: string, transport?: !Puppeteer.ConnectionTransport})} options
129
- # @return {!Promise<!Puppeteer.Browser>}
144
+ # @param browser_ws_endpoint [String]
145
+ # @param browser_url [String]
146
+ # @param transport [Puppeteer::WebSocketTransport]
147
+ # @param ignore_https_errors [Boolean]
148
+ # @param default_viewport [Puppeteer::Viewport|nil]
149
+ # @param slow_mo [Integer]
150
+ # @return [Puppeteer::Browser]
130
151
  def connect(
131
152
  browser_ws_endpoint: nil,
132
153
  browser_url: nil,
@@ -151,7 +172,7 @@ class Puppeteer
151
172
  end
152
173
  end
153
174
 
154
- # @return {string}
175
+ # @return [String]
155
176
  def executable_path
156
177
  launcher.executable_path
157
178
  end
@@ -165,12 +186,12 @@ class Puppeteer
165
186
  )
166
187
  end
167
188
 
168
- # @return {string}
189
+ # @return [String]
169
190
  def product
170
191
  launcher.product
171
192
  end
172
193
 
173
- # @return {Puppeteer::Devices}
194
+ # @return [Puppeteer::Devices]
174
195
  def devices
175
196
  Puppeteer::Devices
176
197
  end
@@ -180,8 +201,11 @@ class Puppeteer
180
201
  # # ???
181
202
  # end
182
203
 
183
- # @param {!Launcher.ChromeArgOptions=} options
184
- # @return {!Array<string>}
204
+ # @param args [Array<String>]
205
+ # @param user_data_dir [String]
206
+ # @param devtools [Boolean]
207
+ # @param headless [Boolean]
208
+ # @return [Array<String>]
185
209
  def default_args(args: nil, user_data_dir: nil, devtools: nil, headless: nil)
186
210
  options = {
187
211
  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
@@ -46,7 +46,7 @@ class Puppeteer::Browser
46
46
  @contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self. context_id)
47
47
  end
48
48
  @targets = {}
49
- @connection.on_event 'Events.CDPSession.Disconnected' do
49
+ @connection.on_event 'Events.Connection.Disconnected' do
50
50
  emit_event 'Events.Browser.Disconnected'
51
51
  end
52
52
  @connection.on_event 'Target.targetCreated', &method(:handle_target_created)
@@ -54,6 +54,22 @@ class Puppeteer::Browser
54
54
  @connection.on_event 'Target.targetInfoChanged', &method(:handle_target_info_changed)
55
55
  end
56
56
 
57
+ EVENT_MAPPINGS = {
58
+ disconnected: 'Events.Browser.Disconnected',
59
+ targetcreated: 'Events.Browser.TargetCreated',
60
+ targetchanged: 'Events.Browser.TargetChanged',
61
+ targetdestroyed: 'Events.Browser.TargetDestroyed',
62
+ }
63
+
64
+ # @param event_name [Symbol] either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed
65
+ def on(event_name, &block)
66
+ unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
67
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
68
+ end
69
+
70
+ add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
71
+ end
72
+
57
73
  # @return [Puppeteer::BrowserRunner::BrowserProcess]
58
74
  def process
59
75
  @process
@@ -81,6 +97,12 @@ class Puppeteer::Browser
81
97
  @contexts.remove(context_id)
82
98
  end
83
99
 
100
+ class TargetAlreadyExistError < StandardError
101
+ def initialize
102
+ super('Target should not exist before targetCreated')
103
+ end
104
+ end
105
+
84
106
  # @param {!Protocol.Target.targetCreatedPayload} event
85
107
  def handle_target_created(event)
86
108
  target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
@@ -92,6 +114,9 @@ class Puppeteer::Browser
92
114
  @default_context
93
115
  end
94
116
 
117
+ if @targets[target_info.target_id]
118
+ raise TargetAlreadyExistError.new
119
+ end
95
120
  target = Puppeteer::Target.new(
96
121
  target_info: target_info,
97
122
  browser_context: context,
@@ -106,44 +131,31 @@ class Puppeteer::Browser
106
131
  emit_event 'Events.Browser.TargetCreated', target
107
132
  context.emit_event 'Events.BrowserContext.TargetCreated', target
108
133
  end
109
-
110
- if_present(pending_target_info_changed_event.delete(target_info.target_id)) do |pending_event|
111
- handle_target_info_changed(pending_event)
112
- end
113
134
  end
114
135
 
115
-
116
136
  # @param {{targetId: string}} event
117
137
  def handle_target_destroyed(event)
118
138
  target_id = event['targetId']
119
139
  target = @targets[target_id]
120
140
  target.ignore_initialize_callback_promise
121
141
  @targets.delete(target_id)
122
- target.handle_closed
142
+ target.closed_callback
123
143
  if await target.initialized_promise
124
144
  emit_event 'Events.Browser.TargetDestroyed', target
125
145
  target.browser_context.emit_event 'Events.BrowserContext.TargetDestroyed', target
126
146
  end
127
147
  end
128
148
 
149
+ class TargetNotExistError < StandardError
150
+ def initialize
151
+ super('target should exist before targetInfoChanged')
152
+ end
153
+ end
154
+
129
155
  # @param {!Protocol.Target.targetInfoChangedPayload} event
130
156
  def handle_target_info_changed(event)
131
157
  target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
132
- target = @targets[target_info.target_id]
133
- if !target
134
- # targetCreated is sometimes notified after targetInfoChanged.
135
- # We don't raise error. Instead, keep the event as a pending change,
136
- # and handle it on handle_target_created.
137
- #
138
- # 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"}}}
139
- # E, [2020-04-22T00:22:26.630448 #79646] ERROR -- : target should exist before targetInfoChanged (StandardError)
140
- # 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"}}}
141
- pending_target_info_changed_event[target_info.target_id] = event
142
- return
143
- # original implementation is:
144
- #
145
- # raise StandardError.new('target should exist before targetInfoChanged')
146
- end
158
+ target = @targets[target_info.target_id] or raise TargetNotExistError.new
147
159
  previous_url = target.url
148
160
  was_initialized = target.initialized?
149
161
  target.handle_target_info_changed(target_info)
@@ -153,10 +165,6 @@ class Puppeteer::Browser
153
165
  end
154
166
  end
155
167
 
156
- private def pending_target_info_changed_event
157
- @pending_target_info_changed_event ||= {}
158
- end
159
-
160
168
  # @return [String]
161
169
  def websocket_endpoint
162
170
  @connection.url
@@ -191,6 +199,11 @@ class Puppeteer::Browser
191
199
  targets.first { |target| target.type == 'browser' }
192
200
  end
193
201
 
202
+ # used only in Target#opener
203
+ private def find_target_by_id(target_id)
204
+ @targets[target_id]
205
+ end
206
+
194
207
  # @param {function(!Target):boolean} predicate
195
208
  # @param {{timeout?: number}=} options
196
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']