puppeteer-ruby 0.0.12 → 0.0.17
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +2 -14
- data/.github/workflows/docs.yml +45 -0
- data/.github/workflows/reviewdog.yml +15 -0
- data/README.md +52 -1
- data/lib/puppeteer.rb +10 -2
- data/lib/puppeteer/browser.rb +53 -34
- data/lib/puppeteer/browser_context.rb +35 -5
- data/lib/puppeteer/cdp_session.rb +3 -19
- data/lib/puppeteer/concurrent_ruby_utils.rb +6 -0
- data/lib/puppeteer/connection.rb +9 -16
- data/lib/puppeteer/debug_print.rb +1 -1
- data/lib/puppeteer/define_async_method.rb +23 -0
- data/lib/puppeteer/dom_world.rb +67 -78
- data/lib/puppeteer/element_handle.rb +19 -47
- data/lib/puppeteer/emulation_manager.rb +2 -6
- data/lib/puppeteer/env.rb +18 -0
- data/lib/puppeteer/execution_context.rb +1 -6
- data/lib/puppeteer/frame.rb +34 -39
- data/lib/puppeteer/frame_manager.rb +7 -25
- data/lib/puppeteer/js_handle.rb +3 -12
- data/lib/puppeteer/keyboard.rb +9 -29
- data/lib/puppeteer/launcher/chrome.rb +9 -7
- data/lib/puppeteer/mouse.rb +20 -24
- data/lib/puppeteer/network_manager.rb +163 -5
- data/lib/puppeteer/page.rb +213 -179
- data/lib/puppeteer/page/pdf_options.rb +166 -0
- data/lib/puppeteer/remote_object.rb +2 -5
- data/lib/puppeteer/request.rb +330 -0
- data/lib/puppeteer/response.rb +113 -0
- data/lib/puppeteer/touch_screen.rb +2 -7
- data/lib/puppeteer/version.rb +1 -1
- data/lib/puppeteer/wait_task.rb +2 -4
- data/lib/puppeteer/web_socket.rb +7 -0
- data/puppeteer-ruby.gemspec +2 -1
- metadata +25 -103
- data/docs/Puppeteer.html +0 -2338
- data/docs/Puppeteer/AsyncAwaitBehavior.html +0 -105
- data/docs/Puppeteer/Browser.html +0 -2258
- data/docs/Puppeteer/BrowserContext.html +0 -809
- data/docs/Puppeteer/BrowserFetcher.html +0 -214
- data/docs/Puppeteer/BrowserRunner.html +0 -914
- data/docs/Puppeteer/BrowserRunner/BrowserProcess.html +0 -477
- data/docs/Puppeteer/CDPSession.html +0 -813
- data/docs/Puppeteer/CDPSession/Error.html +0 -124
- data/docs/Puppeteer/ConcurrentRubyUtils.html +0 -438
- data/docs/Puppeteer/Connection.html +0 -964
- data/docs/Puppeteer/Connection/MessageCallback.html +0 -434
- data/docs/Puppeteer/Connection/ProtocolError.html +0 -216
- data/docs/Puppeteer/Connection/RequestDebugPrinter.html +0 -217
- data/docs/Puppeteer/Connection/ResponseDebugPrinter.html +0 -244
- data/docs/Puppeteer/ConsoleMessage.html +0 -565
- data/docs/Puppeteer/ConsoleMessage/Location.html +0 -433
- data/docs/Puppeteer/DOMWorld.html +0 -2219
- data/docs/Puppeteer/DOMWorld/DetachedError.html +0 -124
- data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +0 -124
- data/docs/Puppeteer/DebugPrint.html +0 -233
- data/docs/Puppeteer/Device.html +0 -470
- data/docs/Puppeteer/Devices.html +0 -139
- data/docs/Puppeteer/ElementHandle.html +0 -2542
- data/docs/Puppeteer/ElementHandle/BoundingBox.html +0 -507
- data/docs/Puppeteer/ElementHandle/BoxModel.html +0 -404
- data/docs/Puppeteer/ElementHandle/ElementNotFoundError.html +0 -206
- data/docs/Puppeteer/ElementHandle/ElementNotVisibleError.html +0 -206
- data/docs/Puppeteer/ElementHandle/Point.html +0 -492
- data/docs/Puppeteer/ElementHandle/ScrollIntoViewError.html +0 -124
- data/docs/Puppeteer/EmulationManager.html +0 -454
- data/docs/Puppeteer/EventCallbackable.html +0 -499
- data/docs/Puppeteer/EventCallbackable/EventListeners.html +0 -435
- data/docs/Puppeteer/ExecutionContext.html +0 -998
- data/docs/Puppeteer/ExecutionContext/EvaluationError.html +0 -124
- data/docs/Puppeteer/ExecutionContext/JavaScriptExpression.html +0 -357
- data/docs/Puppeteer/ExecutionContext/JavaScriptFunction.html +0 -389
- data/docs/Puppeteer/FileChooser.html +0 -455
- data/docs/Puppeteer/Frame.html +0 -3813
- data/docs/Puppeteer/FrameManager.html +0 -2410
- data/docs/Puppeteer/FrameManager/NavigationError.html +0 -124
- data/docs/Puppeteer/IfPresent.html +0 -222
- data/docs/Puppeteer/JSHandle.html +0 -1352
- data/docs/Puppeteer/Keyboard.html +0 -1557
- data/docs/Puppeteer/Keyboard/KeyDefinition.html +0 -831
- data/docs/Puppeteer/Keyboard/KeyDescription.html +0 -603
- data/docs/Puppeteer/Launcher.html +0 -237
- data/docs/Puppeteer/Launcher/Base.html +0 -385
- data/docs/Puppeteer/Launcher/Base/ExecutablePathNotFound.html +0 -124
- data/docs/Puppeteer/Launcher/BrowserOptions.html +0 -441
- data/docs/Puppeteer/Launcher/Chrome.html +0 -669
- data/docs/Puppeteer/Launcher/Chrome/DefaultArgs.html +0 -382
- data/docs/Puppeteer/Launcher/ChromeArgOptions.html +0 -531
- data/docs/Puppeteer/Launcher/LaunchOptions.html +0 -893
- data/docs/Puppeteer/LifecycleWatcher.html +0 -834
- data/docs/Puppeteer/LifecycleWatcher/ExpectedLifecycle.html +0 -363
- data/docs/Puppeteer/LifecycleWatcher/FrameDetachedError.html +0 -206
- data/docs/Puppeteer/LifecycleWatcher/TerminatedError.html +0 -124
- data/docs/Puppeteer/Mouse.html +0 -1095
- data/docs/Puppeteer/Mouse/Button.html +0 -136
- data/docs/Puppeteer/NetworkManager.html +0 -901
- data/docs/Puppeteer/NetworkManager/Credentials.html +0 -385
- data/docs/Puppeteer/Page.html +0 -6173
- data/docs/Puppeteer/Page/FileChooserTimeoutError.html +0 -206
- data/docs/Puppeteer/Page/ScreenshotOptions.html +0 -845
- data/docs/Puppeteer/Page/ScriptTag.html +0 -555
- data/docs/Puppeteer/Page/StyleTag.html +0 -448
- data/docs/Puppeteer/Page/TargetCrashedError.html +0 -124
- data/docs/Puppeteer/RemoteObject.html +0 -1087
- data/docs/Puppeteer/Target.html +0 -1336
- data/docs/Puppeteer/Target/InitializeFailure.html +0 -124
- data/docs/Puppeteer/Target/TargetInfo.html +0 -729
- data/docs/Puppeteer/TimeoutError.html +0 -135
- data/docs/Puppeteer/TimeoutSettings.html +0 -496
- data/docs/Puppeteer/TouchScreen.html +0 -464
- data/docs/Puppeteer/Viewport.html +0 -837
- data/docs/Puppeteer/WaitTask.html +0 -637
- data/docs/Puppeteer/WaitTask/TerminatedError.html +0 -124
- data/docs/Puppeteer/WaitTask/TimeoutError.html +0 -206
- data/docs/Puppeteer/WebSocket.html +0 -673
- data/docs/Puppeteer/WebSocket/DriverImpl.html +0 -412
- data/docs/Puppeteer/WebSocket/TransportError.html +0 -124
- data/docs/Puppeteer/WebSocketTransport.html +0 -600
- data/docs/Puppeteer/WebSocktTransportError.html +0 -124
- data/docs/_index.html +0 -816
- data/docs/class_list.html +0 -51
- data/docs/css/common.css +0 -1
- data/docs/css/full_list.css +0 -58
- data/docs/css/style.css +0 -496
- data/docs/file.README.html +0 -125
- data/docs/file_list.html +0 -56
- data/docs/frames.html +0 -17
- data/docs/index.html +0 -125
- data/docs/js/app.js +0 -314
- data/docs/js/full_list.js +0 -216
- data/docs/js/jquery.js +0 -4
- data/docs/method_list.html +0 -4115
- data/docs/top-level-namespace.html +0 -126
- data/lib/puppeteer/async_await_behavior.rb +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2277fda99720c2566927af9a2acfc56da2b8e87ee10521871c368fd4a05649b2
|
|
4
|
+
data.tar.gz: 59636e168935b0fb6c964cd62355ae3becf8199ed2ee1af58cb512ccacc9d7cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b45495a2ae160e740e242bc04bb81bfa493c1101583393f78e8e7ff3d065c00594fe0196b8225ac73e281a17428127597d11c8f8323ba6b58d64b437e2979d97
|
|
7
|
+
data.tar.gz: 72c9bd1ca17f37927ceb51a79904583c638066e29cdb08cc2534e77bcc7b3ee348e53e69546ecd579917bd6d8db9c4413d4a63cf617ffa33b8c69c756603439e
|
data/.circleci/config.yml
CHANGED
|
@@ -13,21 +13,10 @@ jobs:
|
|
|
13
13
|
- run:
|
|
14
14
|
name: rspec
|
|
15
15
|
command: |
|
|
16
|
-
bundle exec rspec --profile 10 \
|
|
16
|
+
DEBUG=1 bundle exec rspec --profile 10 \
|
|
17
17
|
--format RspecJunitFormatter \
|
|
18
18
|
--out test_results/rspec.xml \
|
|
19
|
-
--format
|
|
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
|
|
19
|
+
--format documentation
|
|
31
20
|
|
|
32
21
|
deploy:
|
|
33
22
|
docker:
|
|
@@ -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
|
@@ -47,9 +47,60 @@ end
|
|
|
47
47
|
|
|
48
48
|
More usage examples can be found [here](https://github.com/YusukeIwaki/puppeteer-ruby-example)
|
|
49
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
|
+
|
|
50
101
|
## API
|
|
51
102
|
|
|
52
|
-
https://yusukeiwaki.github.io/puppeteer-ruby/
|
|
103
|
+
https://yusukeiwaki.github.io/puppeteer-ruby-docs/
|
|
53
104
|
|
|
54
105
|
## Contributing
|
|
55
106
|
|
data/lib/puppeteer.rb
CHANGED
|
@@ -2,14 +2,16 @@ require 'concurrent'
|
|
|
2
2
|
|
|
3
3
|
class Puppeteer; end
|
|
4
4
|
|
|
5
|
+
require 'puppeteer/env'
|
|
6
|
+
|
|
5
7
|
# Custom data types.
|
|
6
8
|
require 'puppeteer/device'
|
|
7
9
|
require 'puppeteer/errors'
|
|
8
10
|
require 'puppeteer/viewport'
|
|
9
11
|
|
|
10
12
|
# Modules
|
|
11
|
-
require 'puppeteer/async_await_behavior'
|
|
12
13
|
require 'puppeteer/concurrent_ruby_utils'
|
|
14
|
+
require 'puppeteer/define_async_method'
|
|
13
15
|
require 'puppeteer/debug_print'
|
|
14
16
|
require 'puppeteer/event_callbackable'
|
|
15
17
|
require 'puppeteer/if_present'
|
|
@@ -36,6 +38,8 @@ require 'puppeteer/mouse'
|
|
|
36
38
|
require 'puppeteer/network_manager'
|
|
37
39
|
require 'puppeteer/page'
|
|
38
40
|
require 'puppeteer/remote_object'
|
|
41
|
+
require 'puppeteer/request'
|
|
42
|
+
require 'puppeteer/response'
|
|
39
43
|
require 'puppeteer/target'
|
|
40
44
|
require 'puppeteer/timeout_settings'
|
|
41
45
|
require 'puppeteer/touch_screen'
|
|
@@ -166,7 +170,11 @@ class Puppeteer
|
|
|
166
170
|
}.compact
|
|
167
171
|
browser = launcher.connect(options)
|
|
168
172
|
if block_given?
|
|
169
|
-
|
|
173
|
+
begin
|
|
174
|
+
yield(browser)
|
|
175
|
+
ensure
|
|
176
|
+
browser.disconnect
|
|
177
|
+
end
|
|
170
178
|
else
|
|
171
179
|
browser
|
|
172
180
|
end
|
data/lib/puppeteer/browser.rb
CHANGED
|
@@ -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::
|
|
8
|
+
using Puppeteer::DefineAsyncMethod
|
|
9
9
|
|
|
10
10
|
# @param {!Puppeteer.Connection} connection
|
|
11
11
|
# @param {!Array<string>} contextIds
|
|
@@ -43,7 +43,7 @@ class Puppeteer::Browser
|
|
|
43
43
|
@default_context = Puppeteer::BrowserContext.new(@connection, self, nil)
|
|
44
44
|
@contexts = {}
|
|
45
45
|
context_ids.each do |context_id|
|
|
46
|
-
@contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self
|
|
46
|
+
@contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self, context_id)
|
|
47
47
|
end
|
|
48
48
|
@targets = {}
|
|
49
49
|
@connection.on_event 'Events.Connection.Disconnected' do
|
|
@@ -70,6 +70,15 @@ class Puppeteer::Browser
|
|
|
70
70
|
add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
# @param event_name [Symbol]
|
|
74
|
+
def once(event_name, &block)
|
|
75
|
+
unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
|
|
76
|
+
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
observe_first(EVENT_MAPPINGS[event_name.to_sym], &block)
|
|
80
|
+
end
|
|
81
|
+
|
|
73
82
|
# @return [Puppeteer::BrowserRunner::BrowserProcess]
|
|
74
83
|
def process
|
|
75
84
|
@process
|
|
@@ -94,7 +103,13 @@ class Puppeteer::Browser
|
|
|
94
103
|
# @param context_id [String]
|
|
95
104
|
def dispose_context(context_id)
|
|
96
105
|
@connection.send_message('Target.disposeBrowserContext', browserContextId: context_id)
|
|
97
|
-
@contexts.
|
|
106
|
+
@contexts.delete(context_id)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
class TargetAlreadyExistError < StandardError
|
|
110
|
+
def initialize
|
|
111
|
+
super('Target should not exist before targetCreated')
|
|
112
|
+
end
|
|
98
113
|
end
|
|
99
114
|
|
|
100
115
|
# @param {!Protocol.Target.targetCreatedPayload} event
|
|
@@ -108,6 +123,9 @@ class Puppeteer::Browser
|
|
|
108
123
|
@default_context
|
|
109
124
|
end
|
|
110
125
|
|
|
126
|
+
if @targets[target_info.target_id]
|
|
127
|
+
raise TargetAlreadyExistError.new
|
|
128
|
+
end
|
|
111
129
|
target = Puppeteer::Target.new(
|
|
112
130
|
target_info: target_info,
|
|
113
131
|
browser_context: context,
|
|
@@ -122,13 +140,8 @@ class Puppeteer::Browser
|
|
|
122
140
|
emit_event 'Events.Browser.TargetCreated', target
|
|
123
141
|
context.emit_event 'Events.BrowserContext.TargetCreated', target
|
|
124
142
|
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
143
|
end
|
|
130
144
|
|
|
131
|
-
|
|
132
145
|
# @param {{targetId: string}} event
|
|
133
146
|
def handle_target_destroyed(event)
|
|
134
147
|
target_id = event['targetId']
|
|
@@ -142,24 +155,16 @@ class Puppeteer::Browser
|
|
|
142
155
|
end
|
|
143
156
|
end
|
|
144
157
|
|
|
158
|
+
class TargetNotExistError < StandardError
|
|
159
|
+
def initialize
|
|
160
|
+
super('target should exist before targetInfoChanged')
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
145
164
|
# @param {!Protocol.Target.targetInfoChangedPayload} event
|
|
146
165
|
def handle_target_info_changed(event)
|
|
147
166
|
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
|
|
167
|
+
target = @targets[target_info.target_id] or raise TargetNotExistError.new
|
|
163
168
|
previous_url = target.url
|
|
164
169
|
was_initialized = target.initialized?
|
|
165
170
|
target.handle_target_info_changed(target_info)
|
|
@@ -169,12 +174,8 @@ class Puppeteer::Browser
|
|
|
169
174
|
end
|
|
170
175
|
end
|
|
171
176
|
|
|
172
|
-
private def pending_target_info_changed_event
|
|
173
|
-
@pending_target_info_changed_event ||= {}
|
|
174
|
-
end
|
|
175
|
-
|
|
176
177
|
# @return [String]
|
|
177
|
-
def
|
|
178
|
+
def ws_endpoint
|
|
178
179
|
@connection.url
|
|
179
180
|
end
|
|
180
181
|
|
|
@@ -204,7 +205,7 @@ class Puppeteer::Browser
|
|
|
204
205
|
|
|
205
206
|
# @return {!Target}
|
|
206
207
|
def target
|
|
207
|
-
targets.
|
|
208
|
+
targets.find { |target| target.type == 'browser' }
|
|
208
209
|
end
|
|
209
210
|
|
|
210
211
|
# used only in Target#opener
|
|
@@ -212,12 +213,11 @@ class Puppeteer::Browser
|
|
|
212
213
|
@targets[target_id]
|
|
213
214
|
end
|
|
214
215
|
|
|
215
|
-
# @param
|
|
216
|
-
# @
|
|
217
|
-
# @return {!Promise<!Target>}
|
|
216
|
+
# @param predicate [Proc(Puppeteer::Target -> Boolean)]
|
|
217
|
+
# @return [Puppeteer::Target]
|
|
218
218
|
def wait_for_target(predicate:, timeout: nil)
|
|
219
219
|
timeout_in_sec = (timeout || 30000).to_i / 1000.0
|
|
220
|
-
existing_target = targets.
|
|
220
|
+
existing_target = targets.find { |target| predicate.call(target) }
|
|
221
221
|
return existing_target if existing_target
|
|
222
222
|
|
|
223
223
|
event_listening_ids = []
|
|
@@ -241,11 +241,18 @@ class Puppeteer::Browser
|
|
|
241
241
|
else
|
|
242
242
|
target_promise.value!
|
|
243
243
|
end
|
|
244
|
+
rescue Timeout::Error
|
|
245
|
+
raise Puppeteer::TimeoutError.new("waiting for target failed: timeout #{timeout}ms exceeded")
|
|
244
246
|
ensure
|
|
245
247
|
remove_event_listener(*event_listening_ids)
|
|
246
248
|
end
|
|
247
249
|
end
|
|
248
250
|
|
|
251
|
+
# @!method async_wait_for_target(predicate:, timeout: nil)
|
|
252
|
+
#
|
|
253
|
+
# @param predicate [Proc(Puppeteer::Target -> Boolean)]
|
|
254
|
+
define_async_method :async_wait_for_target
|
|
255
|
+
|
|
249
256
|
# @return {!Promise<!Array<!Puppeteer.Page>>}
|
|
250
257
|
def pages
|
|
251
258
|
browser_contexts.flat_map(&:pages)
|
|
@@ -274,7 +281,19 @@ class Puppeteer::Browser
|
|
|
274
281
|
!@connection.closed?
|
|
275
282
|
end
|
|
276
283
|
|
|
284
|
+
class Version
|
|
285
|
+
def initialize(hash)
|
|
286
|
+
@protocol_version = hash['protocolVersion']
|
|
287
|
+
@product = hash['product']
|
|
288
|
+
@revision = hash['revision']
|
|
289
|
+
@user_agent = hash['userAgent']
|
|
290
|
+
@js_version = hash['jsVersion']
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
attr_reader :protocol_version, :product, :revision, :user_agent, :js_version
|
|
294
|
+
end
|
|
295
|
+
|
|
277
296
|
private def get_version
|
|
278
|
-
@connection.send_message('Browser.getVersion')
|
|
297
|
+
Version.new(@connection.send_message('Browser.getVersion'))
|
|
279
298
|
end
|
|
280
299
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
class Puppeteer::BrowserContext
|
|
2
2
|
include Puppeteer::EventCallbackable
|
|
3
|
+
using Puppeteer::DefineAsyncMethod
|
|
3
4
|
|
|
4
5
|
# @param {!Puppeteer.Connection} connection
|
|
5
6
|
# @param {!Browser} browser
|
|
@@ -10,14 +11,38 @@ class Puppeteer::BrowserContext
|
|
|
10
11
|
@id = context_id
|
|
11
12
|
end
|
|
12
13
|
|
|
14
|
+
EVENT_MAPPINGS = {
|
|
15
|
+
disconnected: 'Events.BrowserContext.Disconnected',
|
|
16
|
+
targetcreated: 'Events.BrowserContext.TargetCreated',
|
|
17
|
+
targetchanged: 'Events.BrowserContext.TargetChanged',
|
|
18
|
+
targetdestroyed: 'Events.BrowserContext.TargetDestroyed',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# @param event_name [Symbol] either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed
|
|
22
|
+
def on(event_name, &block)
|
|
23
|
+
unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
|
|
24
|
+
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param event_name [Symbol]
|
|
31
|
+
def once(event_name, &block)
|
|
32
|
+
unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
|
|
33
|
+
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
observe_first(EVENT_MAPPINGS[event_name.to_sym], &block)
|
|
37
|
+
end
|
|
38
|
+
|
|
13
39
|
# @return {!Array<!Target>} target
|
|
14
40
|
def targets
|
|
15
41
|
@browser.targets.select { |target| target.browser_context == self }
|
|
16
42
|
end
|
|
17
43
|
|
|
18
|
-
# @param
|
|
19
|
-
# @
|
|
20
|
-
# @return {!Promise<!Target>}
|
|
44
|
+
# @param predicate [Proc(Puppeteer::Target -> Boolean)]
|
|
45
|
+
# @return [Puppeteer::Target]
|
|
21
46
|
def wait_for_target(predicate:, timeout: nil)
|
|
22
47
|
@browser.wait_for_target(
|
|
23
48
|
predicate: ->(target) { target.browser_context == self && predicate.call(target) },
|
|
@@ -25,13 +50,18 @@ class Puppeteer::BrowserContext
|
|
|
25
50
|
)
|
|
26
51
|
end
|
|
27
52
|
|
|
53
|
+
# @!method async_wait_for_target(predicate:, timeout: nil)
|
|
54
|
+
#
|
|
55
|
+
# @param predicate [Proc(Puppeteer::Target -> Boolean)]
|
|
56
|
+
define_async_method :async_wait_for_target
|
|
57
|
+
|
|
28
58
|
# @return {!Promise<!Array<!Puppeteer.Page>>}
|
|
29
59
|
def pages
|
|
30
60
|
targets.select { |target| target.type == 'page' }.map(&:page).reject { |page| !page }
|
|
31
61
|
end
|
|
32
62
|
|
|
33
63
|
def incognito?
|
|
34
|
-
|
|
64
|
+
!!@id
|
|
35
65
|
end
|
|
36
66
|
|
|
37
67
|
# /**
|
|
@@ -82,7 +112,7 @@ class Puppeteer::BrowserContext
|
|
|
82
112
|
end
|
|
83
113
|
|
|
84
114
|
def close
|
|
85
|
-
|
|
115
|
+
unless @id
|
|
86
116
|
raise 'Non-incognito profiles cannot be closed!'
|
|
87
117
|
end
|
|
88
118
|
@browser.dispose_context(@id)
|