puppeteer-bidi 0.0.1.beta10 → 0.0.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +44 -0
  3. data/API_COVERAGE.md +345 -0
  4. data/CLAUDE/porting_puppeteer.md +20 -0
  5. data/CLAUDE.md +2 -1
  6. data/DEVELOPMENT.md +14 -0
  7. data/README.md +47 -415
  8. data/development/generate_api_coverage.rb +411 -0
  9. data/development/puppeteer_revision.txt +1 -0
  10. data/lib/puppeteer/bidi/browser.rb +118 -22
  11. data/lib/puppeteer/bidi/browser_context.rb +185 -2
  12. data/lib/puppeteer/bidi/connection.rb +16 -5
  13. data/lib/puppeteer/bidi/cookie_utils.rb +192 -0
  14. data/lib/puppeteer/bidi/core/browsing_context.rb +83 -40
  15. data/lib/puppeteer/bidi/core/realm.rb +6 -0
  16. data/lib/puppeteer/bidi/core/request.rb +79 -35
  17. data/lib/puppeteer/bidi/core/user_context.rb +5 -3
  18. data/lib/puppeteer/bidi/element_handle.rb +200 -8
  19. data/lib/puppeteer/bidi/errors.rb +4 -0
  20. data/lib/puppeteer/bidi/frame.rb +115 -11
  21. data/lib/puppeteer/bidi/http_request.rb +577 -0
  22. data/lib/puppeteer/bidi/http_response.rb +161 -10
  23. data/lib/puppeteer/bidi/locator.rb +792 -0
  24. data/lib/puppeteer/bidi/page.rb +859 -7
  25. data/lib/puppeteer/bidi/query_handler.rb +1 -1
  26. data/lib/puppeteer/bidi/version.rb +1 -1
  27. data/lib/puppeteer/bidi.rb +39 -6
  28. data/sig/puppeteer/bidi/browser.rbs +53 -6
  29. data/sig/puppeteer/bidi/browser_context.rbs +36 -0
  30. data/sig/puppeteer/bidi/cookie_utils.rbs +64 -0
  31. data/sig/puppeteer/bidi/core/browsing_context.rbs +16 -6
  32. data/sig/puppeteer/bidi/core/request.rbs +14 -11
  33. data/sig/puppeteer/bidi/core/user_context.rbs +2 -2
  34. data/sig/puppeteer/bidi/element_handle.rbs +28 -0
  35. data/sig/puppeteer/bidi/errors.rbs +4 -0
  36. data/sig/puppeteer/bidi/frame.rbs +17 -0
  37. data/sig/puppeteer/bidi/http_request.rbs +162 -0
  38. data/sig/puppeteer/bidi/http_response.rbs +67 -8
  39. data/sig/puppeteer/bidi/locator.rbs +267 -0
  40. data/sig/puppeteer/bidi/page.rbs +170 -0
  41. data/sig/puppeteer/bidi.rbs +15 -3
  42. metadata +12 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a52c1dcb0d3a791f2754c968a543411c98051380796455da1f0e24404923aa8
4
- data.tar.gz: cd9c3880fe2f8ab49201c681efd39a95a77b477e6445cd620e3cdb3e7a7014d3
3
+ metadata.gz: 59931b8cfbf15b649c6d4202eed284ab7c5e7f50dfbbbbeae1ec0e15423aa9bf
4
+ data.tar.gz: 21eed43df8ece3625be9a701730d5f736a6f4ba02a894631af957bf61b1b5e7c
5
5
  SHA512:
6
- metadata.gz: 516d9e6b86a99902e20db1fd43d7d8521fcf8ce6850d72cf253cc6ae5af97f5bd591e2138f0c733d2d96f89f606e45f3d8b6f015ca4730e7b8f75b306dcbd0df
7
- data.tar.gz: a2314ab02834c9ded0abdf5ba85bbae5dcf2252c9dbeaaf81c9f2d6c332d16fc291a6b18d6e36bc470d0585f960fb4cac8aa090467329fa816b47e693df7b024
6
+ metadata.gz: 4e677ea4db58824f6b25ce4e78c587a1e8cae7dfdb9881a4eb0e47f562fe4f8d9c67ead75e9b93b3a870722856097997000d873067fc6d28e89e114afe225c19
7
+ data.tar.gz: 54b4d4dc626bb50f72871e8ff560321c0345f31f9ce60f0409cbb0afe3145f379f863180412497b3e5f830fe758faacdeacf573c58a71e09223def214991652c
data/AGENTS.md ADDED
@@ -0,0 +1,44 @@
1
+ # Repository Guidelines
2
+
3
+ ## Start Here (Project-Specific Guidance)
4
+
5
+ - Read `CLAUDE.md` and `CLAUDE/` first; they define the core async architecture, porting workflow, and testing strategy.
6
+ - Ruby: requires `>= 3.2` (CI covers 3.2–3.4). Prefer a version manager (`rbenv`, `asdf`, etc.) over system Ruby.
7
+
8
+ ## Project Structure & Module Organization
9
+
10
+ - `lib/puppeteer/bidi/`: user-facing API (sync, calls `.wait`).
11
+ - `lib/puppeteer/bidi/core/`: low-level BiDi core (async, returns `Async::Task`).
12
+ - `spec/integration/`: browser-driven specs; fixtures in `spec/assets/`.
13
+
14
+ ## Build, Test, and Development Commands
15
+
16
+ - See `DEVELOPMENT.md` for the full command list and environment variables.
17
+ - Run RSpec via `rbenv exec bundle exec rspec ...` when using rbenv.
18
+
19
+ ## Coding Style & Naming Conventions
20
+
21
+ - Ruby: 2-space indent, double-quoted strings, ~120 char lines; follow RuboCop (`.rubocop.yml`).
22
+ - BiDi-only: do not introduce CDP-related ports.
23
+ - Async: core returns `Async::Task`; upper layer must call `.wait` on every core call (see `CLAUDE/two_layer_architecture.md`).
24
+ - Reviews to watch: WS messages can be handled out-of-order; “wait for event” code must not hang (register listeners before commands, handle “already happened”, cancel on errors).
25
+
26
+ ## Testing Guidelines
27
+
28
+ - Prefer `spec/integration/` and the shared-browser `with_test_state` pattern (see `CLAUDE/testing_strategy.md`).
29
+ - Use `pending` for browser limitations vs `skip` for unimplemented features.
30
+
31
+ ## Commit & Pull Request Guidelines
32
+
33
+ - See `DEVELOPMENT.md` for commit, PR, and release conventions.
34
+
35
+ ## Agent Notes (Porting/Review)
36
+
37
+ - When porting from upstream TS, mirror optional vs default fields: defaults are for validation, and optional keys should be omitted from payloads unless explicitly provided.
38
+ - Match upstream error messages as closely as possible (including interpolated values) so tests align with Puppeteer.
39
+ - In core layer option checks, use key presence (`options.key?`) when upstream uses `'in'` to distinguish "missing" from `nil`.
40
+ - During reviews, compare both implementation (`packages/puppeteer-core/src/bidi/*.ts`) and tests (`test/src/page.spec.ts`) to catch behavior parity gaps.
41
+
42
+ ## Security & Configuration Tips
43
+
44
+ - Do not commit credentials; review network-fetched changes (e.g., `scripts/update_injected_source.rb` → `lib/puppeteer/bidi/injected.js`) carefully.
data/API_COVERAGE.md ADDED
@@ -0,0 +1,345 @@
1
+ # API Coverage
2
+
3
+ - Puppeteer commit: `7d750c25cb29764f2fb31cb90b750a8eec350199`
4
+ - Generated by: `development/generate_api_coverage.rb`
5
+ - Coverage: `174/274` (`63.50%`)
6
+
7
+ ## Browser (Puppeteer::Bidi::Browser)
8
+
9
+ | Node.js | Ruby | Supported |
10
+ | --- | --- | :---: |
11
+ | `Browser.addScreen` | `Puppeteer::Bidi::Browser#add_screen` | ❌ |
12
+ | `Browser.browserContexts` | `Puppeteer::Bidi::Browser#browser_contexts` | ❌ |
13
+ | `Browser.close` | `Puppeteer::Bidi::Browser#close` | ✅ |
14
+ | `Browser.cookies` | `Puppeteer::Bidi::Browser#cookies` | ✅ |
15
+ | `Browser.createBrowserContext` | `Puppeteer::Bidi::Browser#create_browser_context` | ✅ |
16
+ | `Browser.defaultBrowserContext` | `Puppeteer::Bidi::Browser#default_browser_context` | ✅ |
17
+ | `Browser.deleteCookie` | `Puppeteer::Bidi::Browser#delete_cookie` | ✅ |
18
+ | `Browser.deleteMatchingCookies` | `Puppeteer::Bidi::Browser#delete_matching_cookies` | ✅ |
19
+ | `Browser.disconnect` | `Puppeteer::Bidi::Browser#disconnect` | ✅ |
20
+ | `Browser.getWindowBounds` | `Puppeteer::Bidi::Browser#get_window_bounds` | ❌ |
21
+ | `Browser.installExtension` | `Puppeteer::Bidi::Browser#install_extension` | ❌ |
22
+ | `Browser.isConnected` | `Puppeteer::Bidi::Browser#is_connected` | ❌ |
23
+ | `Browser.newPage` | `Puppeteer::Bidi::Browser#new_page` | ✅ |
24
+ | `Browser.pages` | `Puppeteer::Bidi::Browser#pages` | ✅ |
25
+ | `Browser.process` | `Puppeteer::Bidi::Browser#process` | ✅ |
26
+ | `Browser.removeScreen` | `Puppeteer::Bidi::Browser#remove_screen` | ❌ |
27
+ | `Browser.screens` | `Puppeteer::Bidi::Browser#screens` | ❌ |
28
+ | `Browser.setCookie` | `Puppeteer::Bidi::Browser#set_cookie` | ✅ |
29
+ | `Browser.setWindowBounds` | `Puppeteer::Bidi::Browser#set_window_bounds` | ❌ |
30
+ | `Browser.target` | `Puppeteer::Bidi::Browser#target` | ❌ |
31
+ | `Browser.targets` | `Puppeteer::Bidi::Browser#targets` | ❌ |
32
+ | `Browser.uninstallExtension` | `Puppeteer::Bidi::Browser#uninstall_extension` | ❌ |
33
+ | `Browser.userAgent` | `Puppeteer::Bidi::Browser#user_agent` | ✅ |
34
+ | `Browser.version` | `Puppeteer::Bidi::Browser#version` | ❌ |
35
+ | `Browser.waitForTarget` | `Puppeteer::Bidi::Browser#wait_for_target` | ✅ |
36
+ | `Browser.wsEndpoint` | `Puppeteer::Bidi::Browser#ws_endpoint` | ✅ |
37
+
38
+ ## BrowserContext (Puppeteer::Bidi::BrowserContext)
39
+
40
+ | Node.js | Ruby | Supported |
41
+ | --- | --- | :---: |
42
+ | `BrowserContext.browser` | `Puppeteer::Bidi::BrowserContext#browser` | ✅ |
43
+ | `BrowserContext.clearPermissionOverrides` | `Puppeteer::Bidi::BrowserContext#clear_permission_overrides` | ❌ |
44
+ | `BrowserContext.close` | `Puppeteer::Bidi::BrowserContext#close` | ✅ |
45
+ | `BrowserContext.cookies` | `Puppeteer::Bidi::BrowserContext#cookies` | ✅ |
46
+ | `BrowserContext.deleteCookie` | `Puppeteer::Bidi::BrowserContext#delete_cookie` | ✅ |
47
+ | `BrowserContext.deleteMatchingCookies` | `Puppeteer::Bidi::BrowserContext#delete_matching_cookies` | ✅ |
48
+ | `BrowserContext.newPage` | `Puppeteer::Bidi::BrowserContext#new_page` | ✅ |
49
+ | `BrowserContext.overridePermissions` | `Puppeteer::Bidi::BrowserContext#override_permissions` | ✅ |
50
+ | `BrowserContext.pages` | `Puppeteer::Bidi::BrowserContext#pages` | ✅ |
51
+ | `BrowserContext.setCookie` | `Puppeteer::Bidi::BrowserContext#set_cookie` | ✅ |
52
+ | `BrowserContext.targets` | `Puppeteer::Bidi::BrowserContext#targets` | ❌ |
53
+ | `BrowserContext.waitForTarget` | `Puppeteer::Bidi::BrowserContext#wait_for_target` | ❌ |
54
+
55
+ ## ElementHandle (Puppeteer::Bidi::ElementHandle)
56
+
57
+ | Node.js | Ruby | Supported |
58
+ | --- | --- | :---: |
59
+ | `ElementHandle.$` | `Puppeteer::Bidi::ElementHandle#query_selector` | ✅ |
60
+ | `ElementHandle.$$` | `Puppeteer::Bidi::ElementHandle#query_selector_all` | ✅ |
61
+ | `ElementHandle.$$eval` | `Puppeteer::Bidi::ElementHandle#eval_on_selector_all` | ✅ |
62
+ | `ElementHandle.$eval` | `Puppeteer::Bidi::ElementHandle#eval_on_selector` | ✅ |
63
+ | `ElementHandle.asLocator` | `Puppeteer::Bidi::ElementHandle#as_locator` | ✅ |
64
+ | `ElementHandle.autofill` | `Puppeteer::Bidi::ElementHandle#autofill` | ❌ |
65
+ | `ElementHandle.backendNodeId` | `Puppeteer::Bidi::ElementHandle#backend_node_id` | ❌ |
66
+ | `ElementHandle.boundingBox` | `Puppeteer::Bidi::ElementHandle#bounding_box` | ✅ |
67
+ | `ElementHandle.boxModel` | `Puppeteer::Bidi::ElementHandle#box_model` | ✅ |
68
+ | `ElementHandle.click` | `Puppeteer::Bidi::ElementHandle#click` | ✅ |
69
+ | `ElementHandle.clickablePoint` | `Puppeteer::Bidi::ElementHandle#clickable_point` | ✅ |
70
+ | `ElementHandle.contentFrame` | `Puppeteer::Bidi::ElementHandle#content_frame` | ✅ |
71
+ | `ElementHandle.drag` | `Puppeteer::Bidi::ElementHandle#drag` | ❌ |
72
+ | `ElementHandle.dragAndDrop` | `Puppeteer::Bidi::ElementHandle#drag_and_drop` | ❌ |
73
+ | `ElementHandle.dragEnter` | `Puppeteer::Bidi::ElementHandle#drag_enter` | ❌ |
74
+ | `ElementHandle.dragOver` | `Puppeteer::Bidi::ElementHandle#drag_over` | ❌ |
75
+ | `ElementHandle.drop` | `Puppeteer::Bidi::ElementHandle#drop` | ❌ |
76
+ | `ElementHandle.focus` | `Puppeteer::Bidi::ElementHandle#focus` | ✅ |
77
+ | `ElementHandle.hover` | `Puppeteer::Bidi::ElementHandle#hover` | ✅ |
78
+ | `ElementHandle.isHidden` | `Puppeteer::Bidi::ElementHandle#hidden?` | ✅ |
79
+ | `ElementHandle.isIntersectingViewport` | `Puppeteer::Bidi::ElementHandle#intersecting_viewport?` | ✅ |
80
+ | `ElementHandle.isVisible` | `Puppeteer::Bidi::ElementHandle#visible?` | ✅ |
81
+ | `ElementHandle.press` | `Puppeteer::Bidi::ElementHandle#press` | ✅ |
82
+ | `ElementHandle.screenshot` | `Puppeteer::Bidi::ElementHandle#screenshot` | ✅ |
83
+ | `ElementHandle.scrollIntoView` | `Puppeteer::Bidi::ElementHandle#scroll_into_view` | ✅ |
84
+ | `ElementHandle.select` | `Puppeteer::Bidi::ElementHandle#select` | ✅ |
85
+ | `ElementHandle.tap` | `Puppeteer::Bidi::ElementHandle#tap` | ❌ |
86
+ | `ElementHandle.toElement` | `Puppeteer::Bidi::ElementHandle#to_element` | ✅ |
87
+ | `ElementHandle.touchEnd` | `Puppeteer::Bidi::ElementHandle#touch_end` | ❌ |
88
+ | `ElementHandle.touchMove` | `Puppeteer::Bidi::ElementHandle#touch_move` | ❌ |
89
+ | `ElementHandle.touchStart` | `Puppeteer::Bidi::ElementHandle#touch_start` | ❌ |
90
+ | `ElementHandle.type` | `Puppeteer::Bidi::ElementHandle#type` | ✅ |
91
+ | `ElementHandle.uploadFile` | `Puppeteer::Bidi::ElementHandle#upload_file` | ✅ |
92
+ | `ElementHandle.waitForSelector` | `Puppeteer::Bidi::ElementHandle#wait_for_selector` | ✅ |
93
+
94
+ ## FileChooser (Puppeteer::Bidi::FileChooser)
95
+
96
+ | Node.js | Ruby | Supported |
97
+ | --- | --- | :---: |
98
+ | `FileChooser.accept` | `Puppeteer::Bidi::FileChooser#accept` | ✅ |
99
+ | `FileChooser.cancel` | `Puppeteer::Bidi::FileChooser#cancel` | ✅ |
100
+ | `FileChooser.isMultiple` | `Puppeteer::Bidi::FileChooser#multiple?` | ✅ |
101
+
102
+ ## Frame (Puppeteer::Bidi::Frame)
103
+
104
+ | Node.js | Ruby | Supported |
105
+ | --- | --- | :---: |
106
+ | `Frame.$` | `Puppeteer::Bidi::Frame#query_selector` | ✅ |
107
+ | `Frame.$$` | `Puppeteer::Bidi::Frame#query_selector_all` | ✅ |
108
+ | `Frame.$$eval` | `Puppeteer::Bidi::Frame#eval_on_selector_all` | ✅ |
109
+ | `Frame.$eval` | `Puppeteer::Bidi::Frame#eval_on_selector` | ✅ |
110
+ | `Frame.addScriptTag` | `Puppeteer::Bidi::Frame#add_script_tag` | ❌ |
111
+ | `Frame.addStyleTag` | `Puppeteer::Bidi::Frame#add_style_tag` | ❌ |
112
+ | `Frame.childFrames` | `Puppeteer::Bidi::Frame#child_frames` | ✅ |
113
+ | `Frame.click` | `Puppeteer::Bidi::Frame#click` | ✅ |
114
+ | `Frame.content` | `Puppeteer::Bidi::Frame#content` | ❌ |
115
+ | `Frame.evaluate` | `Puppeteer::Bidi::Frame#evaluate` | ✅ |
116
+ | `Frame.evaluateHandle` | `Puppeteer::Bidi::Frame#evaluate_handle` | ✅ |
117
+ | `Frame.focus` | `Puppeteer::Bidi::Frame#focus` | ❌ |
118
+ | `Frame.frameElement` | `Puppeteer::Bidi::Frame#frame_element` | ✅ |
119
+ | `Frame.goto` | `Puppeteer::Bidi::Frame#goto` | ✅ |
120
+ | `Frame.hover` | `Puppeteer::Bidi::Frame#hover` | ✅ |
121
+ | `Frame.isDetached` | `Puppeteer::Bidi::Frame#detached?` | ✅ |
122
+ | `Frame.locator` | `Puppeteer::Bidi::Frame#locator` | ✅ |
123
+ | `Frame.name` | `Puppeteer::Bidi::Frame#name` | ✅ |
124
+ | `Frame.page` | `Puppeteer::Bidi::Frame#page` | ✅ |
125
+ | `Frame.parentFrame` | `Puppeteer::Bidi::Frame#parent_frame` | ✅ |
126
+ | `Frame.select` | `Puppeteer::Bidi::Frame#select` | ✅ |
127
+ | `Frame.setContent` | `Puppeteer::Bidi::Frame#set_content` | ✅ |
128
+ | `Frame.tap` | `Puppeteer::Bidi::Frame#tap` | ❌ |
129
+ | `Frame.title` | `Puppeteer::Bidi::Frame#title` | ❌ |
130
+ | `Frame.type` | `Puppeteer::Bidi::Frame#type` | ✅ |
131
+ | `Frame.url` | `Puppeteer::Bidi::Frame#url` | ✅ |
132
+ | `Frame.waitForFunction` | `Puppeteer::Bidi::Frame#wait_for_function` | ✅ |
133
+ | `Frame.waitForNavigation` | `Puppeteer::Bidi::Frame#wait_for_navigation` | ✅ |
134
+ | `Frame.waitForSelector` | `Puppeteer::Bidi::Frame#wait_for_selector` | ✅ |
135
+
136
+ ## HTTPRequest (Puppeteer::Bidi::HTTPRequest)
137
+
138
+ | Node.js | Ruby | Supported |
139
+ | --- | --- | :---: |
140
+ | `HTTPRequest.abort` | `Puppeteer::Bidi::HTTPRequest#abort` | ✅ |
141
+ | `HTTPRequest.abortErrorReason` | `Puppeteer::Bidi::HTTPRequest#abort_error_reason` | ✅ |
142
+ | `HTTPRequest.continue` | `Puppeteer::Bidi::HTTPRequest#continue` | ✅ |
143
+ | `HTTPRequest.continueRequestOverrides` | `Puppeteer::Bidi::HTTPRequest#continue_request_overrides` | ✅ |
144
+ | `HTTPRequest.enqueueInterceptAction` | `Puppeteer::Bidi::HTTPRequest#enqueue_intercept_action` | ✅ |
145
+ | `HTTPRequest.failure` | `Puppeteer::Bidi::HTTPRequest#failure` | ✅ |
146
+ | `HTTPRequest.fetchPostData` | `Puppeteer::Bidi::HTTPRequest#fetch_post_data` | ✅ |
147
+ | `HTTPRequest.finalizeInterceptions` | `Puppeteer::Bidi::HTTPRequest#finalize_interceptions` | ✅ |
148
+ | `HTTPRequest.frame` | `Puppeteer::Bidi::HTTPRequest#frame` | ✅ |
149
+ | `HTTPRequest.hasPostData` | `Puppeteer::Bidi::HTTPRequest#has_post_data` | ❌ |
150
+ | `HTTPRequest.headers` | `Puppeteer::Bidi::HTTPRequest#headers` | ✅ |
151
+ | `HTTPRequest.initiator` | `Puppeteer::Bidi::HTTPRequest#initiator` | ✅ |
152
+ | `HTTPRequest.interceptResolutionState` | `Puppeteer::Bidi::HTTPRequest#intercept_resolution_state` | ✅ |
153
+ | `HTTPRequest.isInterceptResolutionHandled` | `Puppeteer::Bidi::HTTPRequest#intercept_resolution_handled?` | ✅ |
154
+ | `HTTPRequest.isNavigationRequest` | `Puppeteer::Bidi::HTTPRequest#navigation_request?` | ✅ |
155
+ | `HTTPRequest.method` | `Puppeteer::Bidi::HTTPRequest#method` | ✅ |
156
+ | `HTTPRequest.postData` | `Puppeteer::Bidi::HTTPRequest#post_data` | ✅ |
157
+ | `HTTPRequest.redirectChain` | `Puppeteer::Bidi::HTTPRequest#redirect_chain` | ✅ |
158
+ | `HTTPRequest.resourceType` | `Puppeteer::Bidi::HTTPRequest#resource_type` | ✅ |
159
+ | `HTTPRequest.respond` | `Puppeteer::Bidi::HTTPRequest#respond` | ✅ |
160
+ | `HTTPRequest.response` | `Puppeteer::Bidi::HTTPRequest#response` | ✅ |
161
+ | `HTTPRequest.responseForRequest` | `Puppeteer::Bidi::HTTPRequest#response_for_request` | ✅ |
162
+ | `HTTPRequest.url` | `Puppeteer::Bidi::HTTPRequest#url` | ✅ |
163
+
164
+ ## HTTPResponse (Puppeteer::Bidi::HTTPResponse)
165
+
166
+ | Node.js | Ruby | Supported |
167
+ | --- | --- | :---: |
168
+ | `HTTPResponse.buffer` | `Puppeteer::Bidi::HTTPResponse#buffer` | ✅ |
169
+ | `HTTPResponse.content` | `Puppeteer::Bidi::HTTPResponse#content` | ✅ |
170
+ | `HTTPResponse.frame` | `Puppeteer::Bidi::HTTPResponse#frame` | ✅ |
171
+ | `HTTPResponse.fromCache` | `Puppeteer::Bidi::HTTPResponse#from_cache` | ❌ |
172
+ | `HTTPResponse.fromServiceWorker` | `Puppeteer::Bidi::HTTPResponse#from_service_worker` | ❌ |
173
+ | `HTTPResponse.headers` | `Puppeteer::Bidi::HTTPResponse#headers` | ✅ |
174
+ | `HTTPResponse.json` | `Puppeteer::Bidi::HTTPResponse#json` | ✅ |
175
+ | `HTTPResponse.ok` | `Puppeteer::Bidi::HTTPResponse#ok` | ❌ |
176
+ | `HTTPResponse.remoteAddress` | `Puppeteer::Bidi::HTTPResponse#remote_address` | ✅ |
177
+ | `HTTPResponse.request` | `Puppeteer::Bidi::HTTPResponse#request` | ✅ |
178
+ | `HTTPResponse.securityDetails` | `Puppeteer::Bidi::HTTPResponse#security_details` | ✅ |
179
+ | `HTTPResponse.status` | `Puppeteer::Bidi::HTTPResponse#status` | ✅ |
180
+ | `HTTPResponse.statusText` | `Puppeteer::Bidi::HTTPResponse#status_text` | ✅ |
181
+ | `HTTPResponse.text` | `Puppeteer::Bidi::HTTPResponse#text` | ✅ |
182
+ | `HTTPResponse.timing` | `Puppeteer::Bidi::HTTPResponse#timing` | ✅ |
183
+ | `HTTPResponse.url` | `Puppeteer::Bidi::HTTPResponse#url` | ✅ |
184
+
185
+ ## JSHandle (Puppeteer::Bidi::JSHandle)
186
+
187
+ | Node.js | Ruby | Supported |
188
+ | --- | --- | :---: |
189
+ | `JSHandle.asElement` | `Puppeteer::Bidi::JSHandle#as_element` | ✅ |
190
+ | `JSHandle.dispose` | `Puppeteer::Bidi::JSHandle#dispose` | ✅ |
191
+ | `JSHandle.evaluate` | `Puppeteer::Bidi::JSHandle#evaluate` | ✅ |
192
+ | `JSHandle.evaluateHandle` | `Puppeteer::Bidi::JSHandle#evaluate_handle` | ✅ |
193
+ | `JSHandle.getProperties` | `Puppeteer::Bidi::JSHandle#get_properties` | ✅ |
194
+ | `JSHandle.getProperty` | `Puppeteer::Bidi::JSHandle#get_property` | ✅ |
195
+ | `JSHandle.jsonValue` | `Puppeteer::Bidi::JSHandle#json_value` | ✅ |
196
+ | `JSHandle.remoteObject` | `Puppeteer::Bidi::JSHandle#remote_object` | ✅ |
197
+ | `JSHandle.toString` | `Puppeteer::Bidi::JSHandle#to_string` | ❌ |
198
+
199
+ ## Keyboard (Puppeteer::Bidi::Keyboard)
200
+
201
+ | Node.js | Ruby | Supported |
202
+ | --- | --- | :---: |
203
+ | `Keyboard.down` | `Puppeteer::Bidi::Keyboard#down` | ✅ |
204
+ | `Keyboard.press` | `Puppeteer::Bidi::Keyboard#press` | ✅ |
205
+ | `Keyboard.sendCharacter` | `Puppeteer::Bidi::Keyboard#send_character` | ✅ |
206
+ | `Keyboard.type` | `Puppeteer::Bidi::Keyboard#type` | ✅ |
207
+ | `Keyboard.up` | `Puppeteer::Bidi::Keyboard#up` | ✅ |
208
+
209
+ ## Mouse (Puppeteer::Bidi::Mouse)
210
+
211
+ | Node.js | Ruby | Supported |
212
+ | --- | --- | :---: |
213
+ | `Mouse.click` | `Puppeteer::Bidi::Mouse#click` | ✅ |
214
+ | `Mouse.down` | `Puppeteer::Bidi::Mouse#down` | ✅ |
215
+ | `Mouse.drag` | `Puppeteer::Bidi::Mouse#drag` | ❌ |
216
+ | `Mouse.dragAndDrop` | `Puppeteer::Bidi::Mouse#drag_and_drop` | ❌ |
217
+ | `Mouse.dragEnter` | `Puppeteer::Bidi::Mouse#drag_enter` | ❌ |
218
+ | `Mouse.dragOver` | `Puppeteer::Bidi::Mouse#drag_over` | ❌ |
219
+ | `Mouse.drop` | `Puppeteer::Bidi::Mouse#drop` | ❌ |
220
+ | `Mouse.move` | `Puppeteer::Bidi::Mouse#move` | ✅ |
221
+ | `Mouse.reset` | `Puppeteer::Bidi::Mouse#reset` | ✅ |
222
+ | `Mouse.up` | `Puppeteer::Bidi::Mouse#up` | ✅ |
223
+ | `Mouse.wheel` | `Puppeteer::Bidi::Mouse#wheel` | ✅ |
224
+
225
+ ## Page (Puppeteer::Bidi::Page)
226
+
227
+ | Node.js | Ruby | Supported |
228
+ | --- | --- | :---: |
229
+ | `Page.$` | `Puppeteer::Bidi::Page#query_selector` | ✅ |
230
+ | `Page.$$` | `Puppeteer::Bidi::Page#query_selector_all` | ✅ |
231
+ | `Page.$$eval` | `Puppeteer::Bidi::Page#eval_on_selector_all` | ✅ |
232
+ | `Page.$eval` | `Puppeteer::Bidi::Page#eval_on_selector` | ✅ |
233
+ | `Page.addScriptTag` | `Puppeteer::Bidi::Page#add_script_tag` | ❌ |
234
+ | `Page.addStyleTag` | `Puppeteer::Bidi::Page#add_style_tag` | ❌ |
235
+ | `Page.authenticate` | `Puppeteer::Bidi::Page#authenticate` | ✅ |
236
+ | `Page.bringToFront` | `Puppeteer::Bidi::Page#bring_to_front` | ❌ |
237
+ | `Page.browser` | `Puppeteer::Bidi::Page#browser` | ❌ |
238
+ | `Page.browserContext` | `Puppeteer::Bidi::Page#browser_context` | ✅ |
239
+ | `Page.click` | `Puppeteer::Bidi::Page#click` | ✅ |
240
+ | `Page.close` | `Puppeteer::Bidi::Page#close` | ✅ |
241
+ | `Page.content` | `Puppeteer::Bidi::Page#content` | ✅ |
242
+ | `Page.cookies` | `Puppeteer::Bidi::Page#cookies` | ✅ |
243
+ | `Page.createCDPSession` | `Puppeteer::Bidi::Page#create_cdp_session` | ❌ |
244
+ | `Page.createPDFStream` | `Puppeteer::Bidi::Page#create_pdf_stream` | ❌ |
245
+ | `Page.deleteCookie` | `Puppeteer::Bidi::Page#delete_cookie` | ✅ |
246
+ | `Page.emulate` | `Puppeteer::Bidi::Page#emulate` | ❌ |
247
+ | `Page.emulateCPUThrottling` | `Puppeteer::Bidi::Page#emulate_cpu_throttling` | ❌ |
248
+ | `Page.emulateFocusedPage` | `Puppeteer::Bidi::Page#emulate_focused_page` | ❌ |
249
+ | `Page.emulateIdleState` | `Puppeteer::Bidi::Page#emulate_idle_state` | ❌ |
250
+ | `Page.emulateMediaFeatures` | `Puppeteer::Bidi::Page#emulate_media_features` | ❌ |
251
+ | `Page.emulateMediaType` | `Puppeteer::Bidi::Page#emulate_media_type` | ❌ |
252
+ | `Page.emulateNetworkConditions` | `Puppeteer::Bidi::Page#emulate_network_conditions` | ❌ |
253
+ | `Page.emulateTimezone` | `Puppeteer::Bidi::Page#emulate_timezone` | ❌ |
254
+ | `Page.emulateVisionDeficiency` | `Puppeteer::Bidi::Page#emulate_vision_deficiency` | ❌ |
255
+ | `Page.evaluate` | `Puppeteer::Bidi::Page#evaluate` | ✅ |
256
+ | `Page.evaluateHandle` | `Puppeteer::Bidi::Page#evaluate_handle` | ✅ |
257
+ | `Page.evaluateOnNewDocument` | `Puppeteer::Bidi::Page#evaluate_on_new_document` | ❌ |
258
+ | `Page.exposeFunction` | `Puppeteer::Bidi::Page#expose_function` | ❌ |
259
+ | `Page.focus` | `Puppeteer::Bidi::Page#focus` | ✅ |
260
+ | `Page.frames` | `Puppeteer::Bidi::Page#frames` | ✅ |
261
+ | `Page.getDefaultNavigationTimeout` | `Puppeteer::Bidi::Page#get_default_navigation_timeout` | ❌ |
262
+ | `Page.getDefaultTimeout` | `Puppeteer::Bidi::Page#get_default_timeout` | ❌ |
263
+ | `Page.goBack` | `Puppeteer::Bidi::Page#go_back` | ✅ |
264
+ | `Page.goForward` | `Puppeteer::Bidi::Page#go_forward` | ✅ |
265
+ | `Page.goto` | `Puppeteer::Bidi::Page#goto` | ✅ |
266
+ | `Page.hover` | `Puppeteer::Bidi::Page#hover` | ✅ |
267
+ | `Page.isClosed` | `Puppeteer::Bidi::Page#closed?` | ✅ |
268
+ | `Page.isDragInterceptionEnabled` | `Puppeteer::Bidi::Page#is_drag_interception_enabled` | ❌ |
269
+ | `Page.isJavaScriptEnabled` | `Puppeteer::Bidi::Page#is_java_script_enabled` | ❌ |
270
+ | `Page.isServiceWorkerBypassed` | `Puppeteer::Bidi::Page#is_service_worker_bypassed` | ❌ |
271
+ | `Page.locator` | `Puppeteer::Bidi::Page#locator` | ✅ |
272
+ | `Page.mainFrame` | `Puppeteer::Bidi::Page#main_frame` | ✅ |
273
+ | `Page.metrics` | `Puppeteer::Bidi::Page#metrics` | ❌ |
274
+ | `Page.openDevTools` | `Puppeteer::Bidi::Page#open_dev_tools` | ❌ |
275
+ | `Page.pdf` | `Puppeteer::Bidi::Page#pdf` | ❌ |
276
+ | `Page.queryObjects` | `Puppeteer::Bidi::Page#query_objects` | ❌ |
277
+ | `Page.reload` | `Puppeteer::Bidi::Page#reload` | ✅ |
278
+ | `Page.removeExposedFunction` | `Puppeteer::Bidi::Page#remove_exposed_function` | ❌ |
279
+ | `Page.removeScriptToEvaluateOnNewDocument` | `Puppeteer::Bidi::Page#remove_script_to_evaluate_on_new_document` | ❌ |
280
+ | `Page.resize` | `Puppeteer::Bidi::Page#resize` | ❌ |
281
+ | `Page.screencast` | `Puppeteer::Bidi::Page#screencast` | ❌ |
282
+ | `Page.screenshot` | `Puppeteer::Bidi::Page#screenshot` | ✅ |
283
+ | `Page.select` | `Puppeteer::Bidi::Page#select` | ✅ |
284
+ | `Page.setBypassCSP` | `Puppeteer::Bidi::Page#set_bypass_csp` | ❌ |
285
+ | `Page.setBypassServiceWorker` | `Puppeteer::Bidi::Page#set_bypass_service_worker` | ❌ |
286
+ | `Page.setCacheEnabled` | `Puppeteer::Bidi::Page#set_cache_enabled` | ✅ |
287
+ | `Page.setContent` | `Puppeteer::Bidi::Page#set_content` | ✅ |
288
+ | `Page.setCookie` | `Puppeteer::Bidi::Page#set_cookie` | ✅ |
289
+ | `Page.setDefaultNavigationTimeout` | `Puppeteer::Bidi::Page#set_default_navigation_timeout` | ❌ |
290
+ | `Page.setDefaultTimeout` | `Puppeteer::Bidi::Page#set_default_timeout` | ✅ |
291
+ | `Page.setDragInterception` | `Puppeteer::Bidi::Page#set_drag_interception` | ❌ |
292
+ | `Page.setExtraHTTPHeaders` | `Puppeteer::Bidi::Page#set_extra_http_headers` | ✅ |
293
+ | `Page.setGeolocation` | `Puppeteer::Bidi::Page#set_geolocation` | ✅ |
294
+ | `Page.setJavaScriptEnabled` | `Puppeteer::Bidi::Page#set_java_script_enabled` | ❌ |
295
+ | `Page.setOfflineMode` | `Puppeteer::Bidi::Page#set_offline_mode` | ❌ |
296
+ | `Page.setRequestInterception` | `Puppeteer::Bidi::Page#set_request_interception` | ✅ |
297
+ | `Page.setUserAgent` | `Puppeteer::Bidi::Page#set_user_agent` | ✅ |
298
+ | `Page.setViewport` | `Puppeteer::Bidi::Page#set_viewport` | ✅ |
299
+ | `Page.tap` | `Puppeteer::Bidi::Page#tap` | ❌ |
300
+ | `Page.target` | `Puppeteer::Bidi::Page#target` | ❌ |
301
+ | `Page.title` | `Puppeteer::Bidi::Page#title` | ✅ |
302
+ | `Page.type` | `Puppeteer::Bidi::Page#type` | ✅ |
303
+ | `Page.url` | `Puppeteer::Bidi::Page#url` | ✅ |
304
+ | `Page.viewport` | `Puppeteer::Bidi::Page#viewport` | ✅ |
305
+ | `Page.waitForDevicePrompt` | `Puppeteer::Bidi::Page#wait_for_device_prompt` | ❌ |
306
+ | `Page.waitForFileChooser` | `Puppeteer::Bidi::Page#wait_for_file_chooser` | ✅ |
307
+ | `Page.waitForFrame` | `Puppeteer::Bidi::Page#wait_for_frame` | ❌ |
308
+ | `Page.waitForFunction` | `Puppeteer::Bidi::Page#wait_for_function` | ✅ |
309
+ | `Page.waitForNavigation` | `Puppeteer::Bidi::Page#wait_for_navigation` | ✅ |
310
+ | `Page.waitForNetworkIdle` | `Puppeteer::Bidi::Page#wait_for_network_idle` | ✅ |
311
+ | `Page.waitForRequest` | `Puppeteer::Bidi::Page#wait_for_request` | ✅ |
312
+ | `Page.waitForResponse` | `Puppeteer::Bidi::Page#wait_for_response` | ✅ |
313
+ | `Page.waitForSelector` | `Puppeteer::Bidi::Page#wait_for_selector` | ✅ |
314
+ | `Page.windowId` | `Puppeteer::Bidi::Page#window_id` | ❌ |
315
+ | `Page.workers` | `Puppeteer::Bidi::Page#workers` | ❌ |
316
+
317
+ ## Puppeteer (Puppeteer::Bidi)
318
+
319
+ | Node.js | Ruby | Supported |
320
+ | --- | --- | :---: |
321
+ | `Puppeteer.clearCustomQueryHandlers` | `Puppeteer::Bidi.clear_custom_query_handlers` | ❌ |
322
+ | `Puppeteer.connect` | `Puppeteer::Bidi.connect` | ✅ |
323
+ | `PuppeteerNode.connect` | `Puppeteer::Bidi.connect` | ✅ |
324
+ | `Puppeteer.customQueryHandlerNames` | `Puppeteer::Bidi.custom_query_handler_names` | ❌ |
325
+ | `PuppeteerNode.defaultArgs` | `Puppeteer::Bidi.default_args` | ❌ |
326
+ | `PuppeteerNode.executablePath` | `Puppeteer::Bidi.executable_path` | ❌ |
327
+ | `PuppeteerNode.launch` | `Puppeteer::Bidi.launch` | ✅ |
328
+ | `Puppeteer.registerCustomQueryHandler` | `Puppeteer::Bidi.register_custom_query_handler` | ❌ |
329
+ | `PuppeteerNode.trimCache` | `Puppeteer::Bidi.trim_cache` | ❌ |
330
+ | `Puppeteer.unregisterCustomQueryHandler` | `Puppeteer::Bidi.unregister_custom_query_handler` | ❌ |
331
+
332
+ ## Target (Puppeteer::Bidi::Target)
333
+
334
+ | Node.js | Ruby | Supported |
335
+ | --- | --- | :---: |
336
+ | `Target.asPage` | `Puppeteer::Bidi::Target#as_page` | ❌ |
337
+ | `Target.browser` | `Puppeteer::Bidi::Target#browser` | ❌ |
338
+ | `Target.browserContext` | `Puppeteer::Bidi::Target#browser_context` | ❌ |
339
+ | `Target.createCDPSession` | `Puppeteer::Bidi::Target#create_cdp_session` | ❌ |
340
+ | `Target.opener` | `Puppeteer::Bidi::Target#opener` | ❌ |
341
+ | `Target.page` | `Puppeteer::Bidi::Target#page` | ❌ |
342
+ | `Target.type` | `Puppeteer::Bidi::Target#type` | ❌ |
343
+ | `Target.url` | `Puppeteer::Bidi::Target#url` | ❌ |
344
+ | `Target.worker` | `Puppeteer::Bidi::Target#worker` | ❌ |
345
+
@@ -212,3 +212,23 @@ curl -sL https://raw.githubusercontent.com/puppeteer/puppeteer/main/test/assets/
212
212
  ```
213
213
 
214
214
  **Why this matters**: Test assets are designed to test specific edge cases (rotated elements, complex layouts, etc.). Using simplified versions defeats the purpose of these tests.
215
+
216
+ ## 9. API Coverage Update
217
+
218
+ **IMPORTANT**: When implementing new Puppeteer API methods, update `API_COVERAGE.md`:
219
+
220
+ 1. Find the corresponding entry in the table (e.g., `Browser.userAgent`, `Page.setUserAgent`)
221
+ 2. Change the status from `❌` to `✅`
222
+ 3. Update the coverage count at the top of the file
223
+
224
+ ```markdown
225
+ # Before
226
+ - Coverage: `156/274` (`56.93%`)
227
+ | `Browser.userAgent` | `Puppeteer::Bidi::Browser#user_agent` | ❌ |
228
+
229
+ # After (implemented 2 new methods: 156 + 2 = 158)
230
+ - Coverage: `158/274` (`57.66%`)
231
+ | `Browser.userAgent` | `Puppeteer::Bidi::Browser#user_agent` | ✅ |
232
+ ```
233
+
234
+ **CI will fail** if API_COVERAGE.md is not updated when new methods are implemented. The API Coverage check compares implemented methods against the coverage file.
data/CLAUDE.md CHANGED
@@ -60,7 +60,8 @@ This project uses **Async (Fiber-based)**, NOT concurrent-ruby (Thread-based).
60
60
  2. Understand BiDi protocol calls
61
61
  3. Implement with proper deserialization
62
62
  4. Port tests from Puppeteer
63
- 5. See [Porting Puppeteer Guide](CLAUDE/porting_puppeteer.md)
63
+ 5. **Update `API_COVERAGE.md`** - Mark implemented methods as ✅ and update coverage count
64
+ 6. See [Porting Puppeteer Guide](CLAUDE/porting_puppeteer.md)
64
65
 
65
66
  ## Coding Conventions
66
67
 
data/DEVELOPMENT.md ADDED
@@ -0,0 +1,14 @@
1
+ # Development guide
2
+
3
+ ## Running checks
4
+
5
+ ```bash
6
+ # Run all specs and RuboCop
7
+ bundle exec rake
8
+
9
+ # Only run integration specs (launches Firefox)
10
+ bundle exec rspec spec/integration/
11
+
12
+ # Type checking
13
+ bundle exec rake rbs && bundle exec steep check
14
+ ```