puppeteer-ruby 0.0.9 → 0.0.14

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