playwright-ruby-client 0.7.1 → 1.14.beta1

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -0
  3. data/documentation/docs/api/accessibility.md +52 -1
  4. data/documentation/docs/api/browser.md +8 -2
  5. data/documentation/docs/api/browser_context.md +28 -0
  6. data/documentation/docs/api/browser_type.md +1 -0
  7. data/documentation/docs/api/download.md +97 -0
  8. data/documentation/docs/api/element_handle.md +38 -4
  9. data/documentation/docs/api/experimental/android_device.md +1 -0
  10. data/documentation/docs/api/frame.md +89 -17
  11. data/documentation/docs/api/keyboard.md +11 -20
  12. data/documentation/docs/api/locator.md +650 -0
  13. data/documentation/docs/api/page.md +135 -19
  14. data/documentation/docs/api/response.md +16 -0
  15. data/documentation/docs/api/touchscreen.md +8 -0
  16. data/documentation/docs/api/worker.md +37 -0
  17. data/documentation/docs/article/guides/inspector.md +31 -0
  18. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +91 -0
  19. data/documentation/docs/article/guides/semi_automation.md +5 -1
  20. data/documentation/docs/include/api_coverage.md +77 -14
  21. data/lib/playwright.rb +36 -4
  22. data/lib/playwright/accessibility_impl.rb +50 -0
  23. data/lib/playwright/channel_owners/artifact.rb +4 -0
  24. data/lib/playwright/channel_owners/browser_context.rb +77 -3
  25. data/lib/playwright/channel_owners/element_handle.rb +11 -4
  26. data/lib/playwright/channel_owners/frame.rb +107 -34
  27. data/lib/playwright/channel_owners/page.rb +163 -55
  28. data/lib/playwright/channel_owners/response.rb +8 -0
  29. data/lib/playwright/channel_owners/worker.rb +23 -0
  30. data/lib/playwright/connection.rb +2 -4
  31. data/lib/playwright/{download.rb → download_impl.rb} +5 -1
  32. data/lib/playwright/javascript/expression.rb +5 -4
  33. data/lib/playwright/locator_impl.rb +314 -0
  34. data/lib/playwright/route_handler_entry.rb +3 -2
  35. data/lib/playwright/timeout_settings.rb +4 -4
  36. data/lib/playwright/touchscreen_impl.rb +7 -0
  37. data/lib/playwright/transport.rb +0 -1
  38. data/lib/playwright/url_matcher.rb +12 -2
  39. data/lib/playwright/version.rb +2 -2
  40. data/lib/playwright/web_socket_client.rb +164 -0
  41. data/lib/playwright/web_socket_transport.rb +104 -0
  42. data/lib/playwright_api/accessibility.rb +1 -1
  43. data/lib/playwright_api/android_device.rb +6 -5
  44. data/lib/playwright_api/browser.rb +10 -4
  45. data/lib/playwright_api/browser_context.rb +12 -7
  46. data/lib/playwright_api/browser_type.rb +2 -1
  47. data/lib/playwright_api/cdp_session.rb +6 -6
  48. data/lib/playwright_api/download.rb +70 -0
  49. data/lib/playwright_api/element_handle.rb +38 -18
  50. data/lib/playwright_api/frame.rb +95 -44
  51. data/lib/playwright_api/locator.rb +509 -0
  52. data/lib/playwright_api/page.rb +102 -49
  53. data/lib/playwright_api/response.rb +10 -0
  54. data/lib/playwright_api/touchscreen.rb +1 -1
  55. data/lib/playwright_api/worker.rb +13 -3
  56. metadata +17 -7
@@ -8,7 +8,6 @@ module Playwright
8
8
  # ref: https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_transport.py
9
9
  class Transport
10
10
  # @param playwright_cli_executable_path [String] path to playwright-cli.
11
- # @param debug [Boolean]
12
11
  def initialize(playwright_cli_executable_path:)
13
12
  @driver_executable_path = playwright_cli_executable_path
14
13
  @debug = ENV['DEBUG'].to_s == 'true' || ENV['DEBUG'].to_s == '1'
@@ -1,19 +1,29 @@
1
1
  module Playwright
2
2
  class UrlMatcher
3
3
  # @param url [String|Regexp]
4
- def initialize(url)
4
+ # @param base_url [String|nil]
5
+ def initialize(url, base_url:)
5
6
  @url = url
7
+ @base_url = base_url
6
8
  end
7
9
 
8
10
  def match?(target_url)
9
11
  case @url
10
12
  when String
11
- @url == target_url || File.fnmatch?(@url, target_url)
13
+ joined_url == target_url || File.fnmatch?(@url, target_url)
12
14
  when Regexp
13
15
  @url.match?(target_url)
14
16
  else
15
17
  false
16
18
  end
17
19
  end
20
+
21
+ private def joined_url
22
+ if @base_url && !@url.start_with?('*')
23
+ URI.join(@base_url, @url).to_s
24
+ else
25
+ @url
26
+ end
27
+ end
18
28
  end
19
29
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '0.7.1'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.12.0'
4
+ VERSION = '1.14.beta1'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.14.0'
6
6
  end
@@ -0,0 +1,164 @@
1
+ require 'openssl'
2
+ require 'socket'
3
+
4
+ begin
5
+ require 'websocket/driver'
6
+ rescue LoadError
7
+ raise "websocket-driver is required. Add `gem 'websocket-driver'` to your Gemfile"
8
+ end
9
+
10
+ # ref: https://github.com/rails/rails/blob/master/actioncable/lib/action_cable/connection/client_socket.rb
11
+ # ref: https://github.com/cavalle/chrome_remote/blob/master/lib/chrome_remote/web_socket_client.rb
12
+ module Playwright
13
+ class WebSocketClient
14
+ class SecureSocketFactory
15
+ def initialize(host, port)
16
+ @host = host
17
+ @port = port || 443
18
+ end
19
+
20
+ def create
21
+ tcp_socket = TCPSocket.new(@host, @port)
22
+ OpenSSL::SSL::SSLSocket.new(tcp_socket).tap(&:connect)
23
+ end
24
+ end
25
+
26
+ class DriverImpl # providing #url, #write(string)
27
+ def initialize(url)
28
+ @url = url
29
+
30
+ endpoint = URI.parse(url)
31
+ @socket =
32
+ if endpoint.scheme == 'wss'
33
+ SecureSocketFactory.new(endpoint.host, endpoint.port).create
34
+ else
35
+ TCPSocket.new(endpoint.host, endpoint.port)
36
+ end
37
+ end
38
+
39
+ attr_reader :url
40
+
41
+ def write(data)
42
+ @socket.write(data)
43
+ rescue Errno::EPIPE
44
+ raise EOFError.new('already closed')
45
+ rescue Errno::ECONNRESET
46
+ raise EOFError.new('closed by remote')
47
+ end
48
+
49
+ def readpartial(maxlen = 1024)
50
+ @socket.readpartial(maxlen)
51
+ rescue Errno::ECONNRESET
52
+ raise EOFError.new('closed by remote')
53
+ end
54
+
55
+ def disconnect
56
+ @socket.close
57
+ end
58
+ end
59
+
60
+ STATE_CONNECTING = 0
61
+ STATE_OPENED = 1
62
+ STATE_CLOSING = 2
63
+ STATE_CLOSED = 3
64
+
65
+ def initialize(url:, max_payload_size:)
66
+ @impl = DriverImpl.new(url)
67
+ @driver = ::WebSocket::Driver.client(@impl, max_length: max_payload_size)
68
+
69
+ setup
70
+ end
71
+
72
+ class TransportError < StandardError; end
73
+
74
+ private def setup
75
+ @ready_state = STATE_CONNECTING
76
+ @driver.on(:open) do
77
+ @ready_state = STATE_OPENED
78
+ handle_on_open
79
+ end
80
+ @driver.on(:close) do |event|
81
+ @ready_state = STATE_CLOSED
82
+ handle_on_close(reason: event.reason, code: event.code)
83
+ end
84
+ @driver.on(:error) do |event|
85
+ if !handle_on_error(error_message: event.message)
86
+ raise TransportError.new(event.message)
87
+ end
88
+ end
89
+ @driver.on(:message) do |event|
90
+ handle_on_message(event.data)
91
+ end
92
+ end
93
+
94
+ private def wait_for_data
95
+ @driver.parse(@impl.readpartial)
96
+ end
97
+
98
+ def start
99
+ @driver.start
100
+
101
+ Thread.new do
102
+ wait_for_data until @ready_state >= STATE_CLOSING
103
+ rescue EOFError
104
+ # Google Chrome was gone.
105
+ # We have nothing todo. Just finish polling.
106
+ if @ready_state < STATE_CLOSING
107
+ handle_on_close(reason: 'Going Away', code: 1001)
108
+ end
109
+ end
110
+ end
111
+
112
+ # @param message [String]
113
+ def send_text(message)
114
+ return if @ready_state >= STATE_CLOSING
115
+ @driver.text(message)
116
+ end
117
+
118
+ def close(code: 1000, reason: "")
119
+ return if @ready_state >= STATE_CLOSING
120
+ @ready_state = STATE_CLOSING
121
+ @driver.close(reason, code)
122
+ end
123
+
124
+ def on_open(&block)
125
+ @on_open = block
126
+ end
127
+
128
+ # @param block [Proc(reason: String, code: Numeric)]
129
+ def on_close(&block)
130
+ @on_close = block
131
+ end
132
+
133
+ # @param block [Proc(error_message: String)]
134
+ def on_error(&block)
135
+ @on_error = block
136
+ end
137
+
138
+ def on_message(&block)
139
+ @on_message = block
140
+ end
141
+
142
+ private def handle_on_open
143
+ @on_open&.call
144
+ end
145
+
146
+ private def handle_on_close(reason:, code:)
147
+ @on_close&.call(reason, code)
148
+ @impl.disconnect
149
+ end
150
+
151
+ private def handle_on_error(error_message:)
152
+ return false if @on_error.nil?
153
+
154
+ @on_error.call(error_message)
155
+ true
156
+ end
157
+
158
+ private def handle_on_message(data)
159
+ return if @ready_state != STATE_OPENED
160
+
161
+ @on_message&.call(data)
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Playwright
6
+ # ref: https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_transport.py
7
+ class WebSocketTransport
8
+ # @param ws_endpoint [String] EndpointURL of WebSocket
9
+ def initialize(ws_endpoint:)
10
+ @ws_endpoint = ws_endpoint
11
+ @debug = ENV['DEBUG'].to_s == 'true' || ENV['DEBUG'].to_s == '1'
12
+ end
13
+
14
+ def on_message_received(&block)
15
+ @on_message = block
16
+ end
17
+
18
+ def on_driver_crashed(&block)
19
+ @on_driver_crashed = block
20
+ end
21
+
22
+ class AlreadyDisconnectedError < StandardError ; end
23
+
24
+ # @param message [Hash]
25
+ def send_message(message)
26
+ debug_send_message(message) if @debug
27
+ msg = JSON.dump(message)
28
+
29
+ @ws.send_text(msg)
30
+ rescue Errno::EPIPE, IOError
31
+ raise AlreadyDisconnectedError.new('send_message failed')
32
+ end
33
+
34
+ # Terminate playwright-cli driver.
35
+ def stop
36
+ return unless @ws
37
+
38
+ future = Concurrent::Promises.resolvable_future
39
+
40
+ @ws.on_close do
41
+ future.fulfill(nil)
42
+ end
43
+
44
+ begin
45
+ @ws.close
46
+ rescue EOFError => err
47
+ # ignore EOLError. The connection is already closed.
48
+ future.fulfill(err)
49
+ end
50
+
51
+ # Wait for closed actually.
52
+ future.value!
53
+ end
54
+
55
+ # Start `playwright-cli run-driver`
56
+ #
57
+ # @note This method blocks until playwright-cli exited. Consider using Thread or Future.
58
+ def async_run
59
+ ws = WebSocketClient.new(
60
+ url: @ws_endpoint,
61
+ max_payload_size: 256 * 1024 * 1024, # 256MB
62
+ )
63
+ promise = Concurrent::Promises.resolvable_future
64
+ ws.on_open do
65
+ promise.fulfill(ws)
66
+ end
67
+ ws.on_error do |error_message|
68
+ promise.reject(WebSocketClient::TransportError.new(error_message))
69
+ end
70
+
71
+ # Some messages can be sent just after start, before setting @ws.on_message
72
+ # So set this handler before ws.start.
73
+ ws.on_message do |data|
74
+ handle_on_message(data)
75
+ end
76
+
77
+ ws.start
78
+ @ws = promise.value!
79
+ @ws.on_error do |error|
80
+ puts "[WebSocketTransport] error: #{error}"
81
+ @on_driver_crashed&.call
82
+ end
83
+ rescue Errno::ECONNREFUSED => err
84
+ raise WebSocketClient::TransportError.new(err)
85
+ end
86
+
87
+ private
88
+
89
+ def handle_on_message(data)
90
+ obj = JSON.parse(data)
91
+
92
+ debug_recv_message(obj) if @debug
93
+ @on_message&.call(obj)
94
+ end
95
+
96
+ def debug_send_message(message)
97
+ puts "\x1b[33mSEND>\x1b[0m#{message}"
98
+ end
99
+
100
+ def debug_recv_message(message)
101
+ puts "\x1b[33mRECV>\x1b[0m#{message}"
102
+ end
103
+ end
104
+ end
@@ -44,7 +44,7 @@ module Playwright
44
44
  # print(node["name"])
45
45
  # ```
46
46
  def snapshot(interestingOnly: nil, root: nil)
47
- raise NotImplementedError.new('snapshot is not implemented yet.')
47
+ wrap_impl(@impl.snapshot(interestingOnly: unwrap_impl(interestingOnly), root: unwrap_impl(root)))
48
48
  end
49
49
  end
50
50
  end
@@ -40,6 +40,7 @@ module Playwright
40
40
  # Launches Chrome browser on the device, and returns its persistent context.
41
41
  def launch_browser(
42
42
  acceptDownloads: nil,
43
+ baseURL: nil,
43
44
  bypassCSP: nil,
44
45
  colorScheme: nil,
45
46
  command: nil,
@@ -65,7 +66,7 @@ module Playwright
65
66
  userAgent: nil,
66
67
  viewport: nil,
67
68
  &block)
68
- wrap_impl(@impl.launch_browser(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), command: unwrap_impl(command), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
69
+ wrap_impl(@impl.launch_browser(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), command: unwrap_impl(command), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
69
70
  end
70
71
 
71
72
  # Performs a long tap on the widget defined by `selector`.
@@ -162,13 +163,13 @@ module Playwright
162
163
  end
163
164
 
164
165
  # @nodoc
165
- def tree
166
- wrap_impl(@impl.tree)
166
+ def tap_on(selector, duration: nil, timeout: nil)
167
+ wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
167
168
  end
168
169
 
169
170
  # @nodoc
170
- def tap_on(selector, duration: nil, timeout: nil)
171
- wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
171
+ def tree
172
+ wrap_impl(@impl.tree)
172
173
  end
173
174
 
174
175
  # -- inherited from EventEmitter --
@@ -65,6 +65,7 @@ module Playwright
65
65
  # ```
66
66
  def new_context(
67
67
  acceptDownloads: nil,
68
+ baseURL: nil,
68
69
  bypassCSP: nil,
69
70
  colorScheme: nil,
70
71
  deviceScaleFactor: nil,
@@ -91,7 +92,7 @@ module Playwright
91
92
  userAgent: nil,
92
93
  viewport: nil,
93
94
  &block)
94
- wrap_impl(@impl.new_context(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
95
+ wrap_impl(@impl.new_context(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
95
96
  end
96
97
 
97
98
  # Creates a new page in a new browser context. Closing this page will close the context as well.
@@ -101,6 +102,7 @@ module Playwright
101
102
  # [`method: BrowserContext.newPage`] to control their exact life times.
102
103
  def new_page(
103
104
  acceptDownloads: nil,
105
+ baseURL: nil,
104
106
  bypassCSP: nil,
105
107
  colorScheme: nil,
106
108
  deviceScaleFactor: nil,
@@ -127,10 +129,12 @@ module Playwright
127
129
  userAgent: nil,
128
130
  viewport: nil,
129
131
  &block)
130
- wrap_impl(@impl.new_page(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
132
+ wrap_impl(@impl.new_page(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
131
133
  end
132
134
 
133
- # > NOTE: Tracing is only supported on Chromium-based browsers.
135
+ # > NOTE: This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)
136
+ # which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](../trace-viewer) could be
137
+ # found [here](./class-tracing).
134
138
  #
135
139
  # You can use [`method: Browser.startTracing`] and [`method: Browser.stopTracing`] to create a trace file that can be
136
140
  # opened in Chrome DevTools performance panel.
@@ -144,7 +148,9 @@ module Playwright
144
148
  wrap_impl(@impl.start_tracing(page: unwrap_impl(page), categories: unwrap_impl(categories), path: unwrap_impl(path), screenshots: unwrap_impl(screenshots)))
145
149
  end
146
150
 
147
- # > NOTE: Tracing is only supported on Chromium-based browsers.
151
+ # > NOTE: This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)
152
+ # which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](../trace-viewer) could be
153
+ # found [here](./class-tracing).
148
154
  #
149
155
  # Returns the buffer with trace data.
150
156
  def stop_tracing
@@ -59,7 +59,7 @@ module Playwright
59
59
  #
60
60
  # All existing background pages in the context.
61
61
  def background_pages
62
- raise NotImplementedError.new('background_pages is not implemented yet.')
62
+ wrap_impl(@impl.background_pages)
63
63
  end
64
64
 
65
65
  # Returns the browser instance of the context. If it was launched as a persistent context null gets returned.
@@ -268,7 +268,7 @@ module Playwright
268
268
  #
269
269
  # All existing service workers in the context.
270
270
  def service_workers
271
- raise NotImplementedError.new('service_workers is not implemented yet.')
271
+ wrap_impl(@impl.service_workers)
272
272
  end
273
273
 
274
274
  # This setting will change the default maximum navigation time for the following methods and related shortcuts:
@@ -325,7 +325,7 @@ module Playwright
325
325
 
326
326
  # Returns storage state for this browser context, contains current cookies and local storage snapshot.
327
327
  def storage_state(path: nil)
328
- raise NotImplementedError.new('storage_state is not implemented yet.')
328
+ wrap_impl(@impl.storage_state(path: unwrap_impl(path)))
329
329
  end
330
330
 
331
331
  # Removes a route created with [`method: BrowserContext.route`]. When `handler` is not specified, removes all routes for
@@ -362,6 +362,11 @@ module Playwright
362
362
  raise NotImplementedError.new('wait_for_event is not implemented yet.')
363
363
  end
364
364
 
365
+ # @nodoc
366
+ def enable_debug_console!
367
+ wrap_impl(@impl.enable_debug_console!)
368
+ end
369
+
365
370
  # @nodoc
366
371
  def browser=(req)
367
372
  wrap_impl(@impl.browser=(unwrap_impl(req)))
@@ -373,13 +378,13 @@ module Playwright
373
378
  end
374
379
 
375
380
  # @nodoc
376
- def options=(req)
377
- wrap_impl(@impl.options=(unwrap_impl(req)))
381
+ def pause
382
+ wrap_impl(@impl.pause)
378
383
  end
379
384
 
380
385
  # @nodoc
381
- def pause
382
- wrap_impl(@impl.pause)
386
+ def options=(req)
387
+ wrap_impl(@impl.options=(unwrap_impl(req)))
383
388
  end
384
389
 
385
390
  # -- inherited from EventEmitter --