puppeteer-bidi 0.0.1.beta1 → 0.0.1.beta3
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/CLAUDE.md +50 -4
- data/README.md +8 -1
- data/Steepfile +36 -0
- data/lib/puppeteer/bidi/async_utils.rb +1 -0
- data/lib/puppeteer/bidi/browser.rb +38 -24
- data/lib/puppeteer/bidi/browser_context.rb +13 -4
- data/lib/puppeteer/bidi/browser_launcher.rb +1 -0
- data/lib/puppeteer/bidi/connection.rb +26 -9
- data/lib/puppeteer/bidi/core/browser.rb +15 -14
- data/lib/puppeteer/bidi/core/browsing_context.rb +64 -46
- data/lib/puppeteer/bidi/core/disposable.rb +10 -3
- data/lib/puppeteer/bidi/core/errors.rb +18 -1
- data/lib/puppeteer/bidi/core/event_emitter.rb +18 -9
- data/lib/puppeteer/bidi/core/navigation.rb +4 -3
- data/lib/puppeteer/bidi/core/realm.rb +29 -26
- data/lib/puppeteer/bidi/core/request.rb +33 -29
- data/lib/puppeteer/bidi/core/session.rb +14 -11
- data/lib/puppeteer/bidi/core/user_context.rb +17 -16
- data/lib/puppeteer/bidi/core/user_prompt.rb +8 -7
- data/lib/puppeteer/bidi/core.rb +1 -0
- data/lib/puppeteer/bidi/deserializer.rb +1 -0
- data/lib/puppeteer/bidi/element_handle.rb +52 -52
- data/lib/puppeteer/bidi/errors.rb +1 -0
- data/lib/puppeteer/bidi/file_chooser.rb +1 -0
- data/lib/puppeteer/bidi/frame.rb +70 -70
- data/lib/puppeteer/bidi/http_response.rb +1 -0
- data/lib/puppeteer/bidi/injected_source.rb +1 -0
- data/lib/puppeteer/bidi/js_handle.rb +23 -23
- data/lib/puppeteer/bidi/keyboard.rb +24 -13
- data/lib/puppeteer/bidi/lazy_arg.rb +1 -0
- data/lib/puppeteer/bidi/mouse.rb +31 -18
- data/lib/puppeteer/bidi/page.rb +87 -87
- data/lib/puppeteer/bidi/query_handler.rb +3 -0
- data/lib/puppeteer/bidi/realm.rb +70 -6
- data/lib/puppeteer/bidi/serializer.rb +1 -0
- data/lib/puppeteer/bidi/target.rb +24 -0
- data/lib/puppeteer/bidi/task_manager.rb +9 -3
- data/lib/puppeteer/bidi/timeout_settings.rb +1 -0
- data/lib/puppeteer/bidi/transport.rb +1 -0
- data/lib/puppeteer/bidi/version.rb +1 -1
- data/lib/puppeteer/bidi/wait_task.rb +1 -0
- data/lib/puppeteer/bidi.rb +8 -4
- data/sig/_external.rbs +128 -0
- data/sig/_supplementary.rbs +20 -0
- data/sig/puppeteer/bidi/async_utils.rbs +68 -0
- data/sig/puppeteer/bidi/browser.rbs +35 -26
- data/sig/puppeteer/bidi/browser_context.rbs +39 -0
- data/sig/puppeteer/bidi/browser_launcher.rbs +45 -0
- data/sig/puppeteer/bidi/connection.rbs +67 -0
- data/sig/puppeteer/bidi/core/browser.rbs +79 -0
- data/sig/puppeteer/bidi/core/browsing_context.rbs +210 -0
- data/sig/puppeteer/bidi/core/disposable.rbs +42 -0
- data/sig/puppeteer/bidi/core/errors.rbs +65 -0
- data/sig/puppeteer/bidi/core/event_emitter.rbs +50 -0
- data/sig/puppeteer/bidi/core/navigation.rbs +37 -0
- data/sig/puppeteer/bidi/core/realm.rbs +132 -0
- data/sig/puppeteer/bidi/core/request.rbs +120 -0
- data/sig/puppeteer/bidi/core/session.rbs +65 -0
- data/sig/puppeteer/bidi/core/user_context.rbs +72 -0
- data/sig/puppeteer/bidi/core/user_prompt.rbs +52 -0
- data/sig/puppeteer/bidi/core.rbs +9 -0
- data/sig/puppeteer/bidi/deserializer.rbs +28 -0
- data/sig/puppeteer/bidi/element_handle.rbs +52 -52
- data/sig/puppeteer/bidi/errors.rbs +34 -0
- data/sig/puppeteer/bidi/file_chooser.rbs +27 -0
- data/sig/puppeteer/bidi/frame.rbs +70 -70
- data/sig/puppeteer/bidi/http_response.rbs +18 -0
- data/sig/puppeteer/bidi/injected_source.rbs +21 -0
- data/sig/puppeteer/bidi/js_handle.rbs +23 -23
- data/sig/puppeteer/bidi/keyboard.rbs +57 -0
- data/sig/puppeteer/bidi/lazy_arg.rbs +15 -0
- data/sig/puppeteer/bidi/mouse.rbs +73 -0
- data/sig/puppeteer/bidi/page.rbs +87 -87
- data/sig/puppeteer/bidi/query_handler.rbs +113 -0
- data/sig/puppeteer/bidi/realm.rbs +141 -0
- data/sig/puppeteer/bidi/serializer.rbs +31 -0
- data/sig/puppeteer/bidi/target.rbs +68 -0
- data/sig/puppeteer/bidi/task_manager.rbs +36 -0
- data/sig/puppeteer/bidi/timeout_settings.rbs +14 -0
- data/sig/puppeteer/bidi/transport.rbs +43 -0
- data/sig/puppeteer/bidi/wait_task.rbs +62 -0
- data/sig/puppeteer/bidi.rbs +8 -4
- metadata +36 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a297f926102da482b6ffaecf8f894cb95dffb910f6743ebc75d0414f1aae00f
|
|
4
|
+
data.tar.gz: 81c8b08b57b53ca739af7e864723686965278d60bd5d0d1197aff31dd37b299f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 519a8a8e1dccfc046de5c8bea356a59d3b5e40e79e8040f85fbbe370f1530170ccbd555b32a242841d132130ef4da85eeedc58bac3f554ab34159faa0b807826
|
|
7
|
+
data.tar.gz: d60e4cb2eb5caf33a055d394861814f4ecd3f8b561796ff5cb69cce17a5efe59ae3e07cc98e9e5c46b90a68944f20090cfccb6726849cf774f0f0f015fbffaf1
|
data/CLAUDE.md
CHANGED
|
@@ -86,14 +86,15 @@ Use [rbs-inline](https://github.com/soutaro/rbs-inline) for type annotations in
|
|
|
86
86
|
class Example
|
|
87
87
|
attr_reader :name #: String
|
|
88
88
|
|
|
89
|
-
# @rbs name: String
|
|
89
|
+
# @rbs name: String -- The name to set
|
|
90
90
|
# @rbs return: void
|
|
91
91
|
def initialize(name)
|
|
92
92
|
@name = name
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
#
|
|
96
|
-
# @rbs
|
|
95
|
+
# Query for an element matching the selector
|
|
96
|
+
# @rbs selector: String -- CSS selector to query
|
|
97
|
+
# @rbs return: ElementHandle? -- Matching element or nil
|
|
97
98
|
def query_selector(selector)
|
|
98
99
|
# ...
|
|
99
100
|
end
|
|
@@ -103,8 +104,10 @@ end
|
|
|
103
104
|
**Conventions:**
|
|
104
105
|
- Use `A?` for nullable types (not `A | nil`)
|
|
105
106
|
- Use `A | B | nil` for union types with nil
|
|
106
|
-
-
|
|
107
|
+
- **Always include descriptions** with `--` separator: `# @rbs name: String -- the name`
|
|
107
108
|
- Public methods should have type annotations
|
|
109
|
+
- **Do NOT use `@rbs!` blocks** - RubyMine IDE doesn't recognize them
|
|
110
|
+
- **Use direct union types** instead of type aliases: `BrowserTarget | PageTarget | FrameTarget` not `target`
|
|
108
111
|
|
|
109
112
|
**Generate RBS files:**
|
|
110
113
|
```bash
|
|
@@ -113,6 +116,49 @@ bundle exec rake rbs # Generates sig/**/*.rbs
|
|
|
113
116
|
|
|
114
117
|
**Note:** `sig/` directory is gitignored. RBS files are generated automatically during `rake build`.
|
|
115
118
|
|
|
119
|
+
### Type Checking with Steep
|
|
120
|
+
|
|
121
|
+
Run type checking locally:
|
|
122
|
+
```bash
|
|
123
|
+
bundle exec rake rbs # Generate RBS files first
|
|
124
|
+
bundle exec steep check # Run type checker
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Steepfile Configuration:**
|
|
128
|
+
- Currently configured with lenient `:hint` level diagnostics for gradual typing
|
|
129
|
+
- As type coverage improves, change to `:warning` or `:error` in `Steepfile`
|
|
130
|
+
|
|
131
|
+
**Special RBS Files (manually maintained, NOT gitignored):**
|
|
132
|
+
|
|
133
|
+
1. **`sig/_external.rbs`** - External dependency stubs
|
|
134
|
+
- Types for async gem (`Async`, `Kernel#Async`, `Kernel#Sync`, `Async::Task`, etc.)
|
|
135
|
+
- Standard library extensions (`Dir.mktmpdir`, `Time.parse`)
|
|
136
|
+
- Third-party types (`Singleton`, `Protocol::WebSocket`)
|
|
137
|
+
|
|
138
|
+
2. **`sig/_supplementary.rbs`** - Types rbs-inline cannot generate
|
|
139
|
+
- `extend self` pattern: Add `extend ModuleName` declaration
|
|
140
|
+
- Singleton pattern: Add `extend Singleton::SingletonClassMethods`
|
|
141
|
+
|
|
142
|
+
**Common Issues:**
|
|
143
|
+
|
|
144
|
+
1. **Type alias must be lowercase**: In RBS, `type target = ...` not `type Target = ...`
|
|
145
|
+
|
|
146
|
+
2. **`extend self` not recognized**: Add to `sig/_supplementary.rbs`:
|
|
147
|
+
```rbs
|
|
148
|
+
module Foo
|
|
149
|
+
extend Foo # Makes instance methods callable as singleton methods
|
|
150
|
+
end
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
3. **Singleton pattern**: Add to `sig/_supplementary.rbs`:
|
|
154
|
+
```rbs
|
|
155
|
+
class Bar
|
|
156
|
+
extend Singleton::SingletonClassMethods
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
4. **Missing external types**: Add stubs to `sig/_external.rbs`
|
|
161
|
+
|
|
116
162
|
### Testing
|
|
117
163
|
|
|
118
164
|
- Use RSpec for unit and integration tests
|
data/README.md
CHANGED
|
@@ -471,7 +471,14 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
|
471
471
|
|
|
472
472
|
### Type Annotations
|
|
473
473
|
|
|
474
|
-
This gem includes RBS type definitions generated by [rbs-inline](https://github.com/soutaro/rbs-inline).
|
|
474
|
+
This gem includes RBS type definitions generated by [rbs-inline](https://github.com/soutaro/rbs-inline). Type checking is performed with [Steep](https://github.com/soutaro/steep).
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
bundle exec rake rbs # Generate RBS files
|
|
478
|
+
bundle exec steep check # Run type checker
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
For development guidelines on type annotations, see `CLAUDE.md`.
|
|
475
482
|
|
|
476
483
|
## Contributing
|
|
477
484
|
|
data/Steepfile
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Steepfile for type checking
|
|
2
|
+
|
|
3
|
+
target :lib do
|
|
4
|
+
signature "sig"
|
|
5
|
+
|
|
6
|
+
check "lib"
|
|
7
|
+
|
|
8
|
+
# Standard library
|
|
9
|
+
library "json"
|
|
10
|
+
library "base64"
|
|
11
|
+
library "fileutils"
|
|
12
|
+
library "uri"
|
|
13
|
+
library "net-http"
|
|
14
|
+
|
|
15
|
+
# Configure diagnostic severity
|
|
16
|
+
# Start with lenient settings and tighten over time
|
|
17
|
+
# Using :hint for issues that don't block CI, :warning for informational
|
|
18
|
+
configure_code_diagnostics do |hash|
|
|
19
|
+
# Ignore common Ruby patterns that are hard to type
|
|
20
|
+
hash[Steep::Diagnostic::Ruby::UnannotatedEmptyCollection] = :hint
|
|
21
|
+
|
|
22
|
+
# Gradual typing: treat missing methods and type mismatches as hints
|
|
23
|
+
# These can be tightened to :warning or :error as type coverage improves
|
|
24
|
+
hash[Steep::Diagnostic::Ruby::UnknownConstant] = :hint
|
|
25
|
+
hash[Steep::Diagnostic::Ruby::NoMethod] = :hint
|
|
26
|
+
hash[Steep::Diagnostic::Ruby::UnresolvedOverloading] = :hint
|
|
27
|
+
hash[Steep::Diagnostic::Ruby::IncompatibleAssignment] = :hint
|
|
28
|
+
hash[Steep::Diagnostic::Ruby::ArgumentTypeMismatch] = :hint
|
|
29
|
+
hash[Steep::Diagnostic::Ruby::ReturnTypeMismatch] = :hint
|
|
30
|
+
hash[Steep::Diagnostic::Ruby::BlockTypeMismatch] = :hint
|
|
31
|
+
hash[Steep::Diagnostic::Ruby::BreakTypeMismatch] = :hint
|
|
32
|
+
hash[Steep::Diagnostic::Ruby::ImplicitBreakValueMismatch] = :hint
|
|
33
|
+
hash[Steep::Diagnostic::Ruby::UnexpectedBlockGiven] = :hint
|
|
34
|
+
hash[Steep::Diagnostic::Ruby::UnexpectedPositionalArgument] = :hint
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -12,9 +12,9 @@ module Puppeteer
|
|
|
12
12
|
attr_reader :process #: untyped
|
|
13
13
|
attr_reader :default_browser_context #: BrowserContext
|
|
14
14
|
|
|
15
|
-
# @rbs connection: Connection
|
|
16
|
-
# @rbs launcher: BrowserLauncher?
|
|
17
|
-
# @rbs return: Browser
|
|
15
|
+
# @rbs connection: Connection -- BiDi connection
|
|
16
|
+
# @rbs launcher: BrowserLauncher? -- Browser launcher instance
|
|
17
|
+
# @rbs return: Browser -- Browser instance
|
|
18
18
|
def self.create(connection:, launcher: nil)
|
|
19
19
|
# Create a new BiDi session
|
|
20
20
|
session = Core::Session.from(
|
|
@@ -48,10 +48,10 @@ module Puppeteer
|
|
|
48
48
|
)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
# @rbs connection: Connection
|
|
52
|
-
# @rbs launcher: BrowserLauncher?
|
|
53
|
-
# @rbs core_browser: Core::Browser
|
|
54
|
-
# @rbs session: Core::Session
|
|
51
|
+
# @rbs connection: Connection -- BiDi connection
|
|
52
|
+
# @rbs launcher: BrowserLauncher? -- Browser launcher instance
|
|
53
|
+
# @rbs core_browser: Core::Browser -- Core browser instance
|
|
54
|
+
# @rbs session: Core::Session -- BiDi session
|
|
55
55
|
# @rbs return: void
|
|
56
56
|
def initialize(connection:, launcher:, core_browser:, session:)
|
|
57
57
|
@connection = connection
|
|
@@ -69,8 +69,12 @@ module Puppeteer
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
# Launch a new Firefox browser instance
|
|
72
|
-
# @rbs
|
|
73
|
-
# @rbs
|
|
72
|
+
# @rbs executable_path: String
|
|
73
|
+
# @rbs user_data_dir: String
|
|
74
|
+
# @rbs headless: bool
|
|
75
|
+
# @rbs args: Array[String]
|
|
76
|
+
# @rbs timeout: Numeric
|
|
77
|
+
# @rbs return: Browser -- Browser instance
|
|
74
78
|
def self.launch(**options)
|
|
75
79
|
launcher = BrowserLauncher.new(
|
|
76
80
|
executable_path: options[:executable_path],
|
|
@@ -95,27 +99,37 @@ module Puppeteer
|
|
|
95
99
|
browser
|
|
96
100
|
end
|
|
97
101
|
|
|
102
|
+
# Connect to an existing Firefox browser instance
|
|
103
|
+
# @rbs ws_endpoint: String -- WebSocket endpoint URL
|
|
104
|
+
# @rbs return: Browser -- Browser instance
|
|
105
|
+
def self.connect(ws_endpoint)
|
|
106
|
+
transport = Transport.new(ws_endpoint)
|
|
107
|
+
AsyncUtils.async_timeout(30 * 1000, transport.connect).wait
|
|
108
|
+
connection = Connection.new(transport)
|
|
109
|
+
create(connection: connection, launcher: nil)
|
|
110
|
+
end
|
|
111
|
+
|
|
98
112
|
# Get BiDi session status
|
|
99
|
-
# @rbs return: untyped
|
|
113
|
+
# @rbs return: untyped -- Session status
|
|
100
114
|
def status
|
|
101
|
-
@connection.
|
|
115
|
+
@connection.async_send_command('session.status').wait
|
|
102
116
|
end
|
|
103
117
|
|
|
104
118
|
# Create a new page (Puppeteer-like API)
|
|
105
|
-
# @rbs return: Page
|
|
119
|
+
# @rbs return: Page -- New page instance
|
|
106
120
|
def new_page
|
|
107
121
|
@default_browser_context.new_page
|
|
108
122
|
end
|
|
109
123
|
|
|
110
124
|
# Get all pages
|
|
111
|
-
# @rbs return: Array[Page]
|
|
125
|
+
# @rbs return: Array[Page] -- All pages
|
|
112
126
|
def pages
|
|
113
127
|
@default_browser_context.pages
|
|
114
128
|
end
|
|
115
129
|
|
|
116
130
|
# Register event handler
|
|
117
|
-
# @rbs event: String | Symbol
|
|
118
|
-
# @rbs &block: (untyped) -> void
|
|
131
|
+
# @rbs event: String | Symbol -- Event name
|
|
132
|
+
# @rbs &block: (untyped) -> void -- Event handler
|
|
119
133
|
# @rbs return: void
|
|
120
134
|
def on(event, &block)
|
|
121
135
|
@connection.on(event, &block)
|
|
@@ -143,9 +157,9 @@ module Puppeteer
|
|
|
143
157
|
end
|
|
144
158
|
|
|
145
159
|
# Wait until a target (top-level browsing context) satisfies the predicate.
|
|
146
|
-
# @rbs timeout: Integer?
|
|
147
|
-
# @rbs &predicate: (
|
|
148
|
-
# @rbs return:
|
|
160
|
+
# @rbs timeout: Integer? -- Timeout in milliseconds (default: 30000)
|
|
161
|
+
# @rbs &predicate: (BrowserTarget | PageTarget | FrameTarget) -> boolish -- Predicate evaluated against each Target
|
|
162
|
+
# @rbs return: BrowserTarget | PageTarget | FrameTarget -- Matching target
|
|
149
163
|
def wait_for_target(timeout: nil, &predicate)
|
|
150
164
|
predicate ||= ->(_target) { true }
|
|
151
165
|
timeout_ms = timeout || 30_000
|
|
@@ -237,8 +251,8 @@ module Puppeteer
|
|
|
237
251
|
|
|
238
252
|
private
|
|
239
253
|
|
|
240
|
-
# @rbs &block: (
|
|
241
|
-
# @rbs return: Enumerator[
|
|
254
|
+
# @rbs &block: (BrowserTarget | PageTarget | FrameTarget) -> void -- Block to yield each target to
|
|
255
|
+
# @rbs return: Enumerator[BrowserTarget | PageTarget | FrameTarget, void] -- Enumerator of targets
|
|
242
256
|
def each_target(&block)
|
|
243
257
|
return enum_for(:each_target) unless block_given?
|
|
244
258
|
return unless @core_browser
|
|
@@ -260,8 +274,8 @@ module Puppeteer
|
|
|
260
274
|
end
|
|
261
275
|
end
|
|
262
276
|
|
|
263
|
-
# @rbs predicate: (
|
|
264
|
-
# @rbs return:
|
|
277
|
+
# @rbs predicate: ^(BrowserTarget | PageTarget | FrameTarget) -> boolish -- Predicate to match targets
|
|
278
|
+
# @rbs return: (BrowserTarget | PageTarget | FrameTarget)? -- Matching target or nil
|
|
265
279
|
def find_target(predicate)
|
|
266
280
|
each_target do |target|
|
|
267
281
|
return target if predicate.call(target)
|
|
@@ -269,8 +283,8 @@ module Puppeteer
|
|
|
269
283
|
nil
|
|
270
284
|
end
|
|
271
285
|
|
|
272
|
-
# @rbs user_context: Core::UserContext
|
|
273
|
-
# @rbs return: BrowserContext?
|
|
286
|
+
# @rbs user_context: Core::UserContext -- User context to get browser context for
|
|
287
|
+
# @rbs return: BrowserContext? -- Browser context or nil
|
|
274
288
|
def browser_context_for(user_context)
|
|
275
289
|
return @browser_contexts[user_context.id] if @browser_contexts.key?(user_context.id)
|
|
276
290
|
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
2
3
|
|
|
3
4
|
module Puppeteer
|
|
4
5
|
module Bidi
|
|
5
6
|
# BrowserContext represents an isolated browsing session
|
|
6
7
|
# This is a high-level wrapper around Core::UserContext
|
|
7
8
|
class BrowserContext
|
|
8
|
-
attr_reader :user_context
|
|
9
|
+
attr_reader :user_context #: Core::UserContext
|
|
10
|
+
attr_reader :browser #: Browser
|
|
9
11
|
|
|
12
|
+
# @rbs browser: Browser -- Parent browser instance
|
|
13
|
+
# @rbs user_context: Core::UserContext -- Associated user context
|
|
14
|
+
# @rbs return: void
|
|
10
15
|
def initialize(browser, user_context)
|
|
11
16
|
@browser = browser
|
|
12
17
|
@user_context = user_context
|
|
@@ -14,18 +19,21 @@ module Puppeteer
|
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
# Create a new page (tab/window)
|
|
17
|
-
# @return
|
|
22
|
+
# @rbs return: Page -- New page instance
|
|
18
23
|
def new_page
|
|
19
24
|
browsing_context = @user_context.create_browsing_context('tab')
|
|
20
25
|
page_for(browsing_context)
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
# Get all pages in this context
|
|
24
|
-
# @return [
|
|
29
|
+
# @rbs return: Array[Page] -- All pages
|
|
25
30
|
def pages
|
|
26
31
|
@pages.values
|
|
27
32
|
end
|
|
28
33
|
|
|
34
|
+
# Get or create a Page for the given browsing context
|
|
35
|
+
# @rbs browsing_context: Core::BrowsingContext -- Browsing context
|
|
36
|
+
# @rbs return: Page -- Page instance
|
|
29
37
|
def page_for(browsing_context)
|
|
30
38
|
@pages[browsing_context.id] ||= begin
|
|
31
39
|
page = Page.new(self, browsing_context)
|
|
@@ -39,12 +47,13 @@ module Puppeteer
|
|
|
39
47
|
end
|
|
40
48
|
|
|
41
49
|
# Close the browser context
|
|
50
|
+
# @rbs return: void
|
|
42
51
|
def close
|
|
43
52
|
@user_context.close
|
|
44
53
|
end
|
|
45
54
|
|
|
46
55
|
# Check if context is closed
|
|
47
|
-
# @return
|
|
56
|
+
# @rbs return: bool -- Whether the context is closed
|
|
48
57
|
def closed?
|
|
49
58
|
@user_context.disposed?
|
|
50
59
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
2
3
|
|
|
3
4
|
require 'async'
|
|
4
5
|
require 'async/promise'
|
|
@@ -11,23 +12,25 @@ module Puppeteer
|
|
|
11
12
|
class TimeoutError < Error; end
|
|
12
13
|
class ProtocolError < Error; end
|
|
13
14
|
|
|
14
|
-
DEFAULT_TIMEOUT = 30_000
|
|
15
|
+
DEFAULT_TIMEOUT = 30_000 #: Integer -- 30 seconds in milliseconds
|
|
15
16
|
|
|
17
|
+
# @rbs transport: Transport
|
|
18
|
+
# @rbs return: void
|
|
16
19
|
def initialize(transport)
|
|
17
20
|
@transport = transport
|
|
18
21
|
@next_id = 1
|
|
19
|
-
@pending_commands = {}
|
|
20
|
-
@event_listeners = {}
|
|
22
|
+
@pending_commands = {} #: Hash[Integer, Hash[Symbol, untyped]]
|
|
23
|
+
@event_listeners = {} #: Hash[String, Array[^(untyped) -> void]]
|
|
21
24
|
@closed = false
|
|
22
25
|
|
|
23
26
|
setup_transport_handlers
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
# Send a BiDi command and wait for response
|
|
27
|
-
# @
|
|
28
|
-
# @
|
|
29
|
-
# @
|
|
30
|
-
# @return [Hash]
|
|
30
|
+
# @rbs method: String
|
|
31
|
+
# @rbs params: Hash[String | Symbol, untyped]
|
|
32
|
+
# @rbs timeout: Integer
|
|
33
|
+
# @rbs return: Async::Task[Hash[String, untyped]]
|
|
31
34
|
def async_send_command(method, params = {}, timeout: DEFAULT_TIMEOUT)
|
|
32
35
|
raise ProtocolError, 'Connection is closed' if @closed
|
|
33
36
|
|
|
@@ -81,14 +84,18 @@ module Puppeteer
|
|
|
81
84
|
end
|
|
82
85
|
|
|
83
86
|
# Subscribe to BiDi events
|
|
84
|
-
# @
|
|
85
|
-
# @
|
|
87
|
+
# @rbs event: String
|
|
88
|
+
# @rbs &block: (untyped) -> void
|
|
89
|
+
# @rbs return: void
|
|
86
90
|
def on(event, &block)
|
|
87
91
|
@event_listeners[event] ||= []
|
|
88
92
|
@event_listeners[event] << block
|
|
89
93
|
end
|
|
90
94
|
|
|
91
95
|
# Unsubscribe from BiDi events
|
|
96
|
+
# @rbs event: String
|
|
97
|
+
# @rbs &block: ((untyped) -> void)?
|
|
98
|
+
# @rbs return: void
|
|
92
99
|
def off(event, &block)
|
|
93
100
|
return unless @event_listeners[event]
|
|
94
101
|
|
|
@@ -100,6 +107,7 @@ module Puppeteer
|
|
|
100
107
|
end
|
|
101
108
|
|
|
102
109
|
# Close the connection
|
|
110
|
+
# @rbs return: void
|
|
103
111
|
def close
|
|
104
112
|
return if @closed
|
|
105
113
|
|
|
@@ -114,18 +122,21 @@ module Puppeteer
|
|
|
114
122
|
@transport.close
|
|
115
123
|
end
|
|
116
124
|
|
|
125
|
+
# @rbs return: bool
|
|
117
126
|
def closed?
|
|
118
127
|
@closed
|
|
119
128
|
end
|
|
120
129
|
|
|
121
130
|
private
|
|
122
131
|
|
|
132
|
+
# @rbs return: Integer
|
|
123
133
|
def next_id
|
|
124
134
|
id = @next_id
|
|
125
135
|
@next_id += 1
|
|
126
136
|
id
|
|
127
137
|
end
|
|
128
138
|
|
|
139
|
+
# @rbs return: void
|
|
129
140
|
def setup_transport_handlers
|
|
130
141
|
@transport.on_message do |message|
|
|
131
142
|
handle_message(message)
|
|
@@ -136,6 +147,8 @@ module Puppeteer
|
|
|
136
147
|
end
|
|
137
148
|
end
|
|
138
149
|
|
|
150
|
+
# @rbs message: Hash[String, untyped]
|
|
151
|
+
# @rbs return: void
|
|
139
152
|
def handle_message(message)
|
|
140
153
|
# Response to a command (has 'id' field)
|
|
141
154
|
if message['id']
|
|
@@ -148,6 +161,8 @@ module Puppeteer
|
|
|
148
161
|
end
|
|
149
162
|
end
|
|
150
163
|
|
|
164
|
+
# @rbs message: Hash[String, untyped]
|
|
165
|
+
# @rbs return: void
|
|
151
166
|
def handle_response(message)
|
|
152
167
|
id = message['id']
|
|
153
168
|
pending = @pending_commands.delete(id)
|
|
@@ -161,6 +176,8 @@ module Puppeteer
|
|
|
161
176
|
pending[:promise].resolve(message)
|
|
162
177
|
end
|
|
163
178
|
|
|
179
|
+
# @rbs message: Hash[String, untyped]
|
|
180
|
+
# @rbs return: void
|
|
164
181
|
def handle_event(message)
|
|
165
182
|
method = message['method']
|
|
166
183
|
params = message['params'] || {}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
2
3
|
|
|
3
4
|
module Puppeteer
|
|
4
5
|
module Bidi
|
|
@@ -9,8 +10,8 @@ module Puppeteer
|
|
|
9
10
|
include Disposable::DisposableMixin
|
|
10
11
|
|
|
11
12
|
# Create a browser instance from a session
|
|
12
|
-
# @
|
|
13
|
-
# @return [Browser] Browser instance
|
|
13
|
+
# @rbs session: Session -- BiDi session
|
|
14
|
+
# @rbs return: Async::Task[Browser] -- Browser instance
|
|
14
15
|
def self.from(session)
|
|
15
16
|
browser = new(session)
|
|
16
17
|
Async do
|
|
@@ -44,18 +45,19 @@ module Puppeteer
|
|
|
44
45
|
alias disposed? disconnected?
|
|
45
46
|
|
|
46
47
|
# Get the default user context
|
|
47
|
-
# @return
|
|
48
|
+
# @rbs return: UserContext? -- Default user context
|
|
48
49
|
def default_user_context
|
|
49
50
|
@user_contexts[UserContext::DEFAULT]
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
# Get all user contexts
|
|
53
|
-
# @return [
|
|
54
|
+
# @rbs return: Array[UserContext] -- All user contexts
|
|
54
55
|
def user_contexts
|
|
55
56
|
@user_contexts.values
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
# Close the browser
|
|
60
|
+
# @rbs return: Async::Task[void]
|
|
59
61
|
def close
|
|
60
62
|
Async do
|
|
61
63
|
return if @closed
|
|
@@ -69,11 +71,9 @@ module Puppeteer
|
|
|
69
71
|
end
|
|
70
72
|
|
|
71
73
|
# Add a preload script to the browser
|
|
72
|
-
# @
|
|
73
|
-
# @
|
|
74
|
-
# @
|
|
75
|
-
# @option options [String] :sandbox Sandbox name
|
|
76
|
-
# @return [String] Script ID
|
|
74
|
+
# @rbs function_declaration: String -- JavaScript function to preload
|
|
75
|
+
# @rbs **options: untyped -- Preload script options
|
|
76
|
+
# @rbs return: Async::Task[String] -- Script ID
|
|
77
77
|
def add_preload_script(function_declaration, **options)
|
|
78
78
|
raise BrowserDisconnectedError, @reason if disconnected?
|
|
79
79
|
|
|
@@ -90,16 +90,16 @@ module Puppeteer
|
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
# Remove a preload script
|
|
93
|
-
# @
|
|
93
|
+
# @rbs script: String -- Script ID
|
|
94
|
+
# @rbs return: Async::Task[untyped]
|
|
94
95
|
def remove_preload_script(script)
|
|
95
96
|
raise BrowserDisconnectedError, @reason if disconnected?
|
|
96
97
|
@session.async_send_command('script.removePreloadScript', { script: script })
|
|
97
98
|
end
|
|
98
99
|
|
|
99
100
|
# Create a new user context
|
|
100
|
-
# @
|
|
101
|
-
# @
|
|
102
|
-
# @return [UserContext] New user context
|
|
101
|
+
# @rbs **options: untyped -- User context options
|
|
102
|
+
# @rbs return: Async::Task[UserContext] -- New user context
|
|
103
103
|
def create_user_context(**options)
|
|
104
104
|
raise BrowserDisconnectedError, @reason if disconnected?
|
|
105
105
|
|
|
@@ -122,7 +122,8 @@ module Puppeteer
|
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
# Remove a network intercept
|
|
125
|
-
# @
|
|
125
|
+
# @rbs intercept: String -- Intercept ID
|
|
126
|
+
# @rbs return: Async::Task[untyped]
|
|
126
127
|
def remove_intercept(intercept)
|
|
127
128
|
raise BrowserDisconnectedError, @reason if disconnected?
|
|
128
129
|
@session.async_send_command('network.removeIntercept', { intercept: intercept })
|