playwright-ruby-client 0.0.8 → 1.58.1.alpha1

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 (209) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +4 -0
  3. data/CLAUDE/api_generation.md +28 -0
  4. data/CLAUDE/ci_expectations.md +23 -0
  5. data/CLAUDE/gem_release_flow.md +39 -0
  6. data/CLAUDE/past_upgrade_pr_patterns.md +42 -0
  7. data/CLAUDE/playwright_upgrade_workflow.md +35 -0
  8. data/CLAUDE/rspec_debugging.md +30 -0
  9. data/CLAUDE/unimplemented_examples.md +18 -0
  10. data/CLAUDE.md +32 -0
  11. data/CONTRIBUTING.md +5 -0
  12. data/README.md +60 -16
  13. data/documentation/README.md +33 -0
  14. data/documentation/babel.config.js +3 -0
  15. data/documentation/docs/api/api_request.md +7 -0
  16. data/documentation/docs/api/api_request_context.md +298 -0
  17. data/documentation/docs/api/api_response.md +114 -0
  18. data/documentation/docs/api/browser.md +237 -0
  19. data/documentation/docs/api/browser_context.md +503 -0
  20. data/documentation/docs/api/browser_type.md +184 -0
  21. data/documentation/docs/api/cdp_session.md +44 -0
  22. data/documentation/docs/api/clock.md +154 -0
  23. data/documentation/docs/api/console_message.md +85 -0
  24. data/documentation/docs/api/dialog.md +84 -0
  25. data/documentation/docs/api/download.md +111 -0
  26. data/documentation/docs/api/element_handle.md +694 -0
  27. data/documentation/docs/api/experimental/_category_.yml +3 -0
  28. data/documentation/docs/api/experimental/android.md +42 -0
  29. data/documentation/docs/api/experimental/android_device.md +109 -0
  30. data/documentation/docs/api/experimental/android_input.md +43 -0
  31. data/documentation/docs/api/experimental/android_socket.md +7 -0
  32. data/documentation/docs/api/experimental/android_web_view.md +7 -0
  33. data/documentation/docs/api/file_chooser.md +53 -0
  34. data/documentation/docs/api/frame.md +1218 -0
  35. data/documentation/docs/api/frame_locator.md +348 -0
  36. data/documentation/docs/api/js_handle.md +121 -0
  37. data/documentation/docs/api/keyboard.md +170 -0
  38. data/documentation/docs/api/locator.md +1495 -0
  39. data/documentation/docs/api/locator_assertions.md +827 -0
  40. data/documentation/docs/api/mouse.md +86 -0
  41. data/documentation/docs/api/page.md +1946 -0
  42. data/documentation/docs/api/page_assertions.md +65 -0
  43. data/documentation/docs/api/playwright.md +66 -0
  44. data/documentation/docs/api/request.md +255 -0
  45. data/documentation/docs/api/response.md +176 -0
  46. data/documentation/docs/api/route.md +205 -0
  47. data/documentation/docs/api/selectors.md +63 -0
  48. data/documentation/docs/api/touchscreen.md +22 -0
  49. data/documentation/docs/api/tracing.md +129 -0
  50. data/documentation/docs/api/web_socket.md +51 -0
  51. data/documentation/docs/api/worker.md +83 -0
  52. data/documentation/docs/article/api_coverage.mdx +11 -0
  53. data/documentation/docs/article/getting_started.md +161 -0
  54. data/documentation/docs/article/guides/_category_.yml +3 -0
  55. data/documentation/docs/article/guides/download_playwright_driver.md +55 -0
  56. data/documentation/docs/article/guides/inspector.md +31 -0
  57. data/documentation/docs/article/guides/launch_browser.md +121 -0
  58. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +112 -0
  59. data/documentation/docs/article/guides/rails_integration.md +278 -0
  60. data/documentation/docs/article/guides/rails_integration_with_null_driver.md +145 -0
  61. data/documentation/docs/article/guides/recording_video.md +79 -0
  62. data/documentation/docs/article/guides/rspec_integration.md +59 -0
  63. data/documentation/docs/article/guides/semi_automation.md +71 -0
  64. data/documentation/docs/article/guides/use_storage_state.md +78 -0
  65. data/documentation/docs/include/api_coverage.md +671 -0
  66. data/documentation/docusaurus.config.js +114 -0
  67. data/documentation/package.json +39 -0
  68. data/documentation/sidebars.js +15 -0
  69. data/documentation/src/components/HomepageFeatures.js +61 -0
  70. data/documentation/src/components/HomepageFeatures.module.css +13 -0
  71. data/documentation/src/css/custom.css +44 -0
  72. data/documentation/src/pages/index.js +49 -0
  73. data/documentation/src/pages/index.module.css +41 -0
  74. data/documentation/src/pages/markdown-page.md +7 -0
  75. data/documentation/static/.nojekyll +0 -0
  76. data/documentation/static/img/playwright-logo.svg +9 -0
  77. data/documentation/static/img/playwright-ruby-client.png +0 -0
  78. data/documentation/static/img/undraw_dropdown_menu.svg +1 -0
  79. data/documentation/static/img/undraw_web_development.svg +1 -0
  80. data/documentation/static/img/undraw_windows.svg +1 -0
  81. data/documentation/yarn.lock +9005 -0
  82. data/lib/playwright/{input_types/android_input.rb → android_input_impl.rb} +5 -1
  83. data/lib/playwright/api_implementation.rb +18 -0
  84. data/lib/playwright/api_response_impl.rb +77 -0
  85. data/lib/playwright/channel.rb +62 -1
  86. data/lib/playwright/channel_owner.rb +70 -7
  87. data/lib/playwright/channel_owners/android.rb +16 -3
  88. data/lib/playwright/channel_owners/android_device.rb +22 -66
  89. data/lib/playwright/channel_owners/api_request_context.rb +247 -0
  90. data/lib/playwright/channel_owners/artifact.rb +40 -0
  91. data/lib/playwright/channel_owners/binding_call.rb +70 -0
  92. data/lib/playwright/channel_owners/browser.rb +114 -22
  93. data/lib/playwright/channel_owners/browser_context.rb +589 -15
  94. data/lib/playwright/channel_owners/browser_type.rb +90 -1
  95. data/lib/playwright/channel_owners/cdp_session.rb +19 -0
  96. data/lib/playwright/channel_owners/dialog.rb +32 -0
  97. data/lib/playwright/channel_owners/element_handle.rb +107 -43
  98. data/lib/playwright/channel_owners/fetch_request.rb +8 -0
  99. data/lib/playwright/channel_owners/frame.rb +334 -104
  100. data/lib/playwright/channel_owners/js_handle.rb +9 -13
  101. data/lib/playwright/channel_owners/local_utils.rb +82 -0
  102. data/lib/playwright/channel_owners/page.rb +778 -95
  103. data/lib/playwright/channel_owners/playwright.rb +25 -30
  104. data/lib/playwright/channel_owners/request.rb +120 -18
  105. data/lib/playwright/channel_owners/response.rb +113 -0
  106. data/lib/playwright/channel_owners/route.rb +181 -0
  107. data/lib/playwright/channel_owners/stream.rb +30 -0
  108. data/lib/playwright/channel_owners/tracing.rb +117 -0
  109. data/lib/playwright/channel_owners/web_socket.rb +96 -0
  110. data/lib/playwright/channel_owners/worker.rb +46 -0
  111. data/lib/playwright/channel_owners/writable_stream.rb +14 -0
  112. data/lib/playwright/clock_impl.rb +67 -0
  113. data/lib/playwright/connection.rb +111 -63
  114. data/lib/playwright/console_message_impl.rb +29 -0
  115. data/lib/playwright/download_impl.rb +32 -0
  116. data/lib/playwright/errors.rb +42 -5
  117. data/lib/playwright/event_emitter.rb +17 -3
  118. data/lib/playwright/event_emitter_proxy.rb +49 -0
  119. data/lib/playwright/events.rb +10 -5
  120. data/lib/playwright/file_chooser_impl.rb +24 -0
  121. data/lib/playwright/frame_locator_impl.rb +66 -0
  122. data/lib/playwright/har_router.rb +89 -0
  123. data/lib/playwright/http_headers.rb +14 -0
  124. data/lib/playwright/input_files.rb +102 -15
  125. data/lib/playwright/javascript/expression.rb +7 -11
  126. data/lib/playwright/javascript/regex.rb +23 -0
  127. data/lib/playwright/javascript/source_url.rb +16 -0
  128. data/lib/playwright/javascript/value_parser.rb +108 -19
  129. data/lib/playwright/javascript/value_serializer.rb +47 -8
  130. data/lib/playwright/javascript/visitor_info.rb +26 -0
  131. data/lib/playwright/javascript.rb +2 -10
  132. data/lib/playwright/{input_types/keyboard.rb → keyboard_impl.rb} +6 -2
  133. data/lib/playwright/locator_assertions_impl.rb +571 -0
  134. data/lib/playwright/locator_impl.rb +544 -0
  135. data/lib/playwright/locator_utils.rb +136 -0
  136. data/lib/playwright/mouse_impl.rb +57 -0
  137. data/lib/playwright/page_assertions_impl.rb +154 -0
  138. data/lib/playwright/playwright_api.rb +102 -30
  139. data/lib/playwright/raw_headers.rb +61 -0
  140. data/lib/playwright/route_handler.rb +78 -0
  141. data/lib/playwright/select_option_values.rb +34 -13
  142. data/lib/playwright/selectors_impl.rb +45 -0
  143. data/lib/playwright/test.rb +102 -0
  144. data/lib/playwright/timeout_settings.rb +9 -4
  145. data/lib/playwright/touchscreen_impl.rb +14 -0
  146. data/lib/playwright/transport.rb +61 -10
  147. data/lib/playwright/url_matcher.rb +24 -2
  148. data/lib/playwright/utils.rb +48 -13
  149. data/lib/playwright/version.rb +2 -1
  150. data/lib/playwright/video.rb +54 -0
  151. data/lib/playwright/waiter.rb +166 -0
  152. data/lib/playwright/web_socket_client.rb +167 -0
  153. data/lib/playwright/web_socket_transport.rb +116 -0
  154. data/lib/playwright.rb +188 -11
  155. data/lib/playwright_api/android.rb +46 -11
  156. data/lib/playwright_api/android_device.rb +182 -31
  157. data/lib/playwright_api/android_input.rb +22 -13
  158. data/lib/playwright_api/android_socket.rb +18 -0
  159. data/lib/playwright_api/android_web_view.rb +24 -0
  160. data/lib/playwright_api/api_request.rb +26 -0
  161. data/lib/playwright_api/api_request_context.rb +311 -0
  162. data/lib/playwright_api/api_response.rb +92 -0
  163. data/lib/playwright_api/browser.rb +116 -103
  164. data/lib/playwright_api/browser_context.rb +290 -389
  165. data/lib/playwright_api/browser_type.rb +96 -118
  166. data/lib/playwright_api/cdp_session.rb +36 -39
  167. data/lib/playwright_api/clock.rb +121 -0
  168. data/lib/playwright_api/console_message.rb +35 -19
  169. data/lib/playwright_api/dialog.rb +53 -50
  170. data/lib/playwright_api/download.rb +49 -43
  171. data/lib/playwright_api/element_handle.rb +354 -402
  172. data/lib/playwright_api/file_chooser.rb +15 -18
  173. data/lib/playwright_api/frame.rb +703 -603
  174. data/lib/playwright_api/frame_locator.rb +285 -0
  175. data/lib/playwright_api/js_handle.rb +50 -76
  176. data/lib/playwright_api/keyboard.rb +67 -146
  177. data/lib/playwright_api/locator.rb +1304 -0
  178. data/lib/playwright_api/locator_assertions.rb +704 -0
  179. data/lib/playwright_api/mouse.rb +23 -29
  180. data/lib/playwright_api/page.rb +1196 -1176
  181. data/lib/playwright_api/page_assertions.rb +60 -0
  182. data/lib/playwright_api/playwright.rb +54 -122
  183. data/lib/playwright_api/request.rb +112 -74
  184. data/lib/playwright_api/response.rb +92 -20
  185. data/lib/playwright_api/route.rb +152 -62
  186. data/lib/playwright_api/selectors.rb +47 -61
  187. data/lib/playwright_api/touchscreen.rb +8 -2
  188. data/lib/playwright_api/tracing.rb +128 -0
  189. data/lib/playwright_api/web_socket.rb +43 -5
  190. data/lib/playwright_api/worker.rb +74 -34
  191. data/playwright.gemspec +14 -9
  192. data/sig/playwright.rbs +658 -0
  193. metadata +216 -50
  194. data/docs/api_coverage.md +0 -354
  195. data/lib/playwright/channel_owners/chromium_browser.rb +0 -8
  196. data/lib/playwright/channel_owners/chromium_browser_context.rb +0 -8
  197. data/lib/playwright/channel_owners/console_message.rb +0 -21
  198. data/lib/playwright/channel_owners/firefox_browser.rb +0 -8
  199. data/lib/playwright/channel_owners/selectors.rb +0 -4
  200. data/lib/playwright/channel_owners/webkit_browser.rb +0 -8
  201. data/lib/playwright/input_type.rb +0 -19
  202. data/lib/playwright/input_types/mouse.rb +0 -4
  203. data/lib/playwright/input_types/touchscreen.rb +0 -4
  204. data/lib/playwright/javascript/function.rb +0 -67
  205. data/lib/playwright/wait_helper.rb +0 -73
  206. data/lib/playwright_api/accessibility.rb +0 -93
  207. data/lib/playwright_api/binding_call.rb +0 -23
  208. data/lib/playwright_api/chromium_browser_context.rb +0 -57
  209. data/lib/playwright_api/video.rb +0 -24
@@ -1,90 +1,93 @@
1
1
  module Playwright
2
+ #
2
3
  # `Dialog` objects are dispatched by page via the [`event: Page.dialog`] event.
3
- #
4
+ #
4
5
  # An example of using `Dialog` class:
5
- #
6
6
  #
7
- # ```js
8
- # const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
9
- #
10
- # (async () => {
11
- # const browser = await chromium.launch();
12
- # const page = await browser.newPage();
13
- # page.on('dialog', async dialog => {
14
- # console.log(dialog.message());
15
- # await dialog.dismiss();
16
- # await browser.close();
17
- # });
18
- # page.evaluate(() => alert('1'));
19
- # })();
20
- # ```
21
- #
22
- # ```python async
23
- # import asyncio
24
- # from playwright.async_api import async_playwright
25
- #
26
- # async def handle_dialog(dialog):
27
- # print(dialog.message)
28
- # await dialog.dismiss()
29
- #
30
- # async def run(playwright):
31
- # chromium = playwright.chromium
32
- # browser = await chromium.launch()
33
- # page = await browser.new_page()
34
- # page.on("dialog", handle_dialog)
35
- # page.evaluate("alert('1')")
36
- # await browser.close()
37
- #
38
- # async def main():
39
- # async with async_playwright() as playwright:
40
- # await run(playwright)
41
- # asyncio.run(main())
42
- # ```
43
- #
44
7
  # ```python sync
45
- # # FIXME
46
- # from playwright.sync_api import sync_playwright
47
- #
8
+ # from playwright.sync_api import sync_playwright, Playwright
9
+ #
48
10
  # def handle_dialog(dialog):
49
11
  # print(dialog.message)
50
12
  # dialog.dismiss()
51
- #
52
- # def run(playwright):
13
+ #
14
+ # def run(playwright: Playwright):
53
15
  # chromium = playwright.chromium
54
16
  # browser = chromium.launch()
55
17
  # page = browser.new_page()
56
18
  # page.on("dialog", handle_dialog)
57
19
  # page.evaluate("alert('1')")
58
20
  # browser.close()
59
- #
21
+ #
60
22
  # with sync_playwright() as playwright:
61
23
  # run(playwright)
62
24
  # ```
25
+ #
26
+ # **NOTE**: Dialogs are dismissed automatically, unless there is a [`event: Page.dialog`] listener.
27
+ # When listener is present, it **must** either [`method: Dialog.accept`] or [`method: Dialog.dismiss`] the dialog - otherwise the page will [freeze](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop#never_blocking) waiting for the dialog, and actions like click will never finish.
63
28
  class Dialog < PlaywrightApi
64
29
 
30
+ #
65
31
  # Returns when the dialog has been accepted.
66
32
  def accept(promptText: nil)
67
- raise NotImplementedError.new('accept is not implemented yet.')
33
+ wrap_impl(@impl.accept(promptText: unwrap_impl(promptText)))
68
34
  end
69
35
 
36
+ #
70
37
  # If dialog is prompt, returns default prompt value. Otherwise, returns empty string.
71
38
  def default_value
72
- raise NotImplementedError.new('default_value is not implemented yet.')
39
+ wrap_impl(@impl.default_value)
73
40
  end
74
41
 
42
+ #
75
43
  # Returns when the dialog has been dismissed.
76
44
  def dismiss
77
- raise NotImplementedError.new('dismiss is not implemented yet.')
45
+ wrap_impl(@impl.dismiss)
78
46
  end
79
47
 
48
+ #
80
49
  # A message displayed in the dialog.
81
50
  def message
82
- raise NotImplementedError.new('message is not implemented yet.')
51
+ wrap_impl(@impl.message)
83
52
  end
84
53
 
54
+ #
55
+ # The page that initiated this dialog, if available.
56
+ def page
57
+ wrap_impl(@impl.page)
58
+ end
59
+
60
+ #
85
61
  # Returns dialog's type, can be one of `alert`, `beforeunload`, `confirm` or `prompt`.
86
62
  def type
87
- raise NotImplementedError.new('type is not implemented yet.')
63
+ wrap_impl(@impl.type)
64
+ end
65
+
66
+ # @nodoc
67
+ def accept_async(promptText: nil)
68
+ wrap_impl(@impl.accept_async(promptText: unwrap_impl(promptText)))
69
+ end
70
+
71
+ # -- inherited from EventEmitter --
72
+ # @nodoc
73
+ def once(event, callback)
74
+ event_emitter_proxy.once(event, callback)
75
+ end
76
+
77
+ # -- inherited from EventEmitter --
78
+ # @nodoc
79
+ def on(event, callback)
80
+ event_emitter_proxy.on(event, callback)
81
+ end
82
+
83
+ # -- inherited from EventEmitter --
84
+ # @nodoc
85
+ def off(event, callback)
86
+ event_emitter_proxy.off(event, callback)
87
+ end
88
+
89
+ private def event_emitter_proxy
90
+ @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
88
91
  end
89
92
  end
90
93
  end
@@ -1,78 +1,84 @@
1
1
  module Playwright
2
+ #
2
3
  # `Download` objects are dispatched by page via the [`event: Page.download`] event.
3
- #
4
- # All the downloaded files belonging to the browser context are deleted when the browser context is closed. All downloaded
5
- # files are deleted when the browser closes.
6
- #
7
- # Download event is emitted once the download starts. Download path becomes available once download completes:
8
- #
9
4
  #
10
- # ```js
11
- # const [ download ] = await Promise.all([
12
- # page.waitForEvent('download'), // wait for download to start
13
- # page.click('a')
14
- # ]);
15
- # // wait for download to complete
16
- # const path = await download.path();
17
- # ```
18
- #
19
- # ```python async
20
- # async with page.expect_download() as download_info:
21
- # await page.click("a")
22
- # download = await download_info.value
23
- # # waits for download to complete
24
- # path = await download.path()
25
- # ```
26
- #
5
+ # All the downloaded files belonging to the browser context are deleted when the
6
+ # browser context is closed.
7
+ #
8
+ # Download event is emitted once the download starts. Download path becomes available once download completes.
9
+ #
27
10
  # ```python sync
11
+ # # Start waiting for the download
28
12
  # with page.expect_download() as download_info:
29
- # page.click("a")
13
+ # # Perform the action that initiates download
14
+ # page.get_by_text("Download file").click()
30
15
  # download = download_info.value
31
- # # wait for download to complete
32
- # path = download.path()
16
+ #
17
+ # # Wait for the download process to complete and save the downloaded file somewhere
18
+ # download.save_as("/path/to/save/at/" + download.suggested_filename)
33
19
  # ```
34
- #
35
- # > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
36
- # downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
37
- # performed and user has no access to the downloaded files.
38
20
  class Download < PlaywrightApi
39
21
 
40
- # Returns readable stream for current download or `null` if download failed.
41
- def create_read_stream
42
- raise NotImplementedError.new('create_read_stream is not implemented yet.')
22
+ #
23
+ # Cancels a download. Will not fail if the download is already finished or canceled.
24
+ # Upon successful cancellations, `download.failure()` would resolve to `'canceled'`.
25
+ def cancel
26
+ wrap_impl(@impl.cancel)
43
27
  end
44
28
 
45
- # Deletes the downloaded file.
29
+ #
30
+ # Deletes the downloaded file. Will wait for the download to finish if necessary.
46
31
  def delete
47
- raise NotImplementedError.new('delete is not implemented yet.')
32
+ wrap_impl(@impl.delete)
48
33
  end
49
34
 
50
- # Returns download error if any.
35
+ #
36
+ # Returns download error if any. Will wait for the download to finish if necessary.
51
37
  def failure
52
- raise NotImplementedError.new('failure is not implemented yet.')
38
+ wrap_impl(@impl.failure)
39
+ end
40
+
41
+ #
42
+ # Get the page that the download belongs to.
43
+ def page
44
+ wrap_impl(@impl.page)
53
45
  end
54
46
 
55
- # Returns path to the downloaded file in case of successful download.
47
+ #
48
+ # Returns path to the downloaded file for a successful download, or throws for a failed/canceled download. The method will wait for the download to finish if necessary. The method throws when connected remotely.
49
+ #
50
+ # Note that the download's file name is a random GUID, use [`method: Download.suggestedFilename`]
51
+ # to get suggested file name.
56
52
  def path
57
- raise NotImplementedError.new('path is not implemented yet.')
53
+ wrap_impl(@impl.path)
58
54
  end
59
55
 
60
- # Saves the download to a user-specified path.
56
+ #
57
+ # Copy the download to a user-specified path. It is safe to call this method while the download
58
+ # is still in progress. Will wait for the download to finish if necessary.
59
+ #
60
+ # **Usage**
61
+ #
62
+ # ```python sync
63
+ # download.save_as("/path/to/save/at/" + download.suggested_filename)
64
+ # ```
61
65
  def save_as(path)
62
- raise NotImplementedError.new('save_as is not implemented yet.')
66
+ wrap_impl(@impl.save_as(unwrap_impl(path)))
63
67
  end
64
68
 
69
+ #
65
70
  # Returns suggested filename for this download. It is typically computed by the browser from the
66
71
  # [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) response header
67
72
  # or the `download` attribute. See the spec on [whatwg](https://html.spec.whatwg.org/#downloading-resources). Different
68
73
  # browsers can use different logic for computing it.
69
74
  def suggested_filename
70
- raise NotImplementedError.new('suggested_filename is not implemented yet.')
75
+ wrap_impl(@impl.suggested_filename)
71
76
  end
72
77
 
78
+ #
73
79
  # Returns downloaded url.
74
80
  def url
75
- raise NotImplementedError.new('url is not implemented yet.')
81
+ wrap_impl(@impl.url)
76
82
  end
77
83
  end
78
84
  end