playwright-ruby-client 0.6.2 → 0.7.0
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/documentation/docs/api/browser.md +2 -1
- data/documentation/docs/api/browser_context.md +1 -1
- data/documentation/docs/api/browser_type.md +54 -1
- data/documentation/docs/api/experimental/android.md +3 -2
- data/documentation/docs/api/page.md +8 -0
- data/documentation/docs/api/route.md +20 -21
- data/documentation/docs/api/tracing.md +8 -15
- data/documentation/docs/api/web_socket.md +38 -1
- data/documentation/docs/article/guides/launch_browser.md +2 -0
- data/documentation/docs/article/guides/rails_integration.md +156 -2
- data/documentation/docs/article/guides/recording_video.md +79 -0
- data/documentation/docs/article/guides/semi_automation.md +67 -0
- data/documentation/docs/include/api_coverage.md +7 -8
- data/documentation/package.json +1 -1
- data/documentation/yarn.lock +478 -498
- data/lib/playwright/channel_owners/browser.rb +15 -27
- data/lib/playwright/channel_owners/browser_context.rb +13 -5
- data/lib/playwright/channel_owners/browser_type.rb +23 -8
- data/lib/playwright/channel_owners/page.rb +6 -1
- data/lib/playwright/channel_owners/web_socket.rb +87 -0
- data/lib/playwright/tracing_impl.rb +9 -9
- data/lib/playwright/version.rb +1 -1
- data/lib/playwright_api/android.rb +9 -8
- data/lib/playwright_api/android_device.rb +6 -6
- data/lib/playwright_api/browser.rb +9 -8
- data/lib/playwright_api/browser_context.rb +8 -8
- data/lib/playwright_api/browser_type.rb +12 -11
- data/lib/playwright_api/console_message.rb +6 -6
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +6 -6
- data/lib/playwright_api/frame.rb +6 -6
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/page.rb +14 -14
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +6 -6
- data/lib/playwright_api/response.rb +6 -6
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/selectors.rb +6 -6
- data/lib/playwright_api/tracing.rb +6 -12
- data/lib/playwright_api/web_socket.rb +28 -6
- data/lib/playwright_api/worker.rb +6 -6
- data/playwright.gemspec +2 -1
- metadata +33 -16
@@ -7,7 +7,7 @@ module Playwright
|
|
7
7
|
private def after_initialize
|
8
8
|
@connected = true
|
9
9
|
@closed_or_closing = false
|
10
|
-
@remote =
|
10
|
+
@remote = false
|
11
11
|
|
12
12
|
@contexts = Set.new
|
13
13
|
@channel.on('close', method(:on_close))
|
@@ -30,36 +30,32 @@ module Playwright
|
|
30
30
|
@contexts << context
|
31
31
|
context.browser = self
|
32
32
|
context.options = params
|
33
|
+
return context unless block
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
context.close
|
39
|
-
end
|
40
|
-
else
|
41
|
-
context
|
35
|
+
begin
|
36
|
+
block.call(context)
|
37
|
+
ensure
|
38
|
+
context.close
|
42
39
|
end
|
43
40
|
end
|
44
41
|
|
45
|
-
def new_page(**options)
|
42
|
+
def new_page(**options, &block)
|
46
43
|
context = new_context(**options)
|
47
44
|
page = context.new_page
|
48
45
|
page.owned_context = context
|
49
46
|
context.owner_page = page
|
50
|
-
|
47
|
+
|
48
|
+
return page unless block
|
49
|
+
|
50
|
+
begin
|
51
|
+
block.call(page)
|
52
|
+
ensure
|
53
|
+
page.close
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
57
|
def close
|
54
58
|
return if @closed_or_closing
|
55
|
-
if @remote
|
56
|
-
@contexts.each do |context|
|
57
|
-
context.pages.each do |page|
|
58
|
-
page.send(:on_close)
|
59
|
-
end
|
60
|
-
context.send(:on_close)
|
61
|
-
end
|
62
|
-
end
|
63
59
|
@closed_or_closing = true
|
64
60
|
@channel.send_message_to_server('close')
|
65
61
|
nil
|
@@ -89,14 +85,6 @@ module Playwright
|
|
89
85
|
|
90
86
|
private def on_close(_ = {})
|
91
87
|
@connected = false
|
92
|
-
if @remote
|
93
|
-
@contexts.each do |context|
|
94
|
-
context.pages.each do |page|
|
95
|
-
page.send(:on_close)
|
96
|
-
end
|
97
|
-
context.send(:on_close)
|
98
|
-
end
|
99
|
-
end
|
100
88
|
emit(Events::Browser::Disconnected, self)
|
101
89
|
@closed_or_closing = true
|
102
90
|
end
|
@@ -46,6 +46,8 @@ module Playwright
|
|
46
46
|
ChannelOwners::Request.from_nullable(params['page']),
|
47
47
|
)
|
48
48
|
})
|
49
|
+
|
50
|
+
@closed_promise = Concurrent::Promises.resolvable_future
|
49
51
|
end
|
50
52
|
|
51
53
|
private def on_page(page)
|
@@ -111,10 +113,17 @@ module Playwright
|
|
111
113
|
end
|
112
114
|
|
113
115
|
# @returns [Playwright::Page]
|
114
|
-
def new_page
|
116
|
+
def new_page(&block)
|
115
117
|
raise 'Please use browser.new_context' if @owner_page
|
116
118
|
resp = @channel.send_message_to_server('newPage')
|
117
|
-
ChannelOwners::Page.from(resp)
|
119
|
+
page = ChannelOwners::Page.from(resp)
|
120
|
+
return page unless block
|
121
|
+
|
122
|
+
begin
|
123
|
+
block.call(page)
|
124
|
+
ensure
|
125
|
+
page.close
|
126
|
+
end
|
118
127
|
end
|
119
128
|
|
120
129
|
def cookies(urls: nil)
|
@@ -223,15 +232,14 @@ module Playwright
|
|
223
232
|
end
|
224
233
|
|
225
234
|
private def on_close
|
226
|
-
@closed_or_closing = true
|
227
235
|
@browser&.send(:remove_context, self)
|
228
236
|
emit(Events::BrowserContext::Close)
|
237
|
+
@closed_promise.fulfill(true)
|
229
238
|
end
|
230
239
|
|
231
240
|
def close
|
232
|
-
return if @closed_or_closing
|
233
|
-
@closed_or_closing = true
|
234
241
|
@channel.send_message_to_server('close')
|
242
|
+
@closed_promise.value!
|
235
243
|
nil
|
236
244
|
rescue => err
|
237
245
|
raise unless safe_close_error?(err)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Playwright
|
2
2
|
define_channel_owner :BrowserType do
|
3
|
+
include Utils::PrepareBrowserContextOptions
|
4
|
+
|
3
5
|
def name
|
4
6
|
@initializer['name']
|
5
7
|
end
|
@@ -11,15 +13,28 @@ module Playwright
|
|
11
13
|
def launch(options, &block)
|
12
14
|
resp = @channel.send_message_to_server('launch', options.compact)
|
13
15
|
browser = ChannelOwners::Browser.from(resp)
|
16
|
+
return browser unless block
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
begin
|
19
|
+
block.call(browser)
|
20
|
+
ensure
|
21
|
+
browser.close
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def launch_persistent_context(userDataDir, **options, &block)
|
26
|
+
params = options.dup
|
27
|
+
prepare_browser_context_options(params)
|
28
|
+
params['userDataDir'] = userDataDir
|
29
|
+
|
30
|
+
resp = @channel.send_message_to_server('launchPersistentContext', params.compact)
|
31
|
+
context = ChannelOwners::Browser.from(resp)
|
32
|
+
return context unless block
|
33
|
+
|
34
|
+
begin
|
35
|
+
block.call(context)
|
36
|
+
ensure
|
37
|
+
context.close
|
23
38
|
end
|
24
39
|
end
|
25
40
|
|
@@ -65,7 +65,8 @@ module Playwright
|
|
65
65
|
emit(Events::Page::WebSocket, ChannelOwners::WebSocket.from(params['webSocket']))
|
66
66
|
})
|
67
67
|
@channel.on('worker', ->(params) {
|
68
|
-
|
68
|
+
worker = ChannelOwners::Worker.from(params['worker'])
|
69
|
+
# on_worker(worker)
|
69
70
|
})
|
70
71
|
end
|
71
72
|
|
@@ -773,6 +774,10 @@ module Playwright
|
|
773
774
|
expect_event(Events::Page::Response, predicate: predicate, timeout: timeout, &block)
|
774
775
|
end
|
775
776
|
|
777
|
+
def expect_websocket(predicate: nil, timeout: nil, &block)
|
778
|
+
expect_event(Events::Page::WebSocket, predicate: predicate, timeout: timeout, &block)
|
779
|
+
end
|
780
|
+
|
776
781
|
# called from Frame with send(:timeout_settings)
|
777
782
|
private def timeout_settings
|
778
783
|
@timeout_settings
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module Playwright
|
4
|
+
define_channel_owner :WebSocket do
|
5
|
+
private def after_initialize
|
6
|
+
@closed = false
|
7
|
+
|
8
|
+
@channel.on('frameSent', -> (params) {
|
9
|
+
on_frame_sent(params['opcode'], params['data'])
|
10
|
+
})
|
11
|
+
@channel.on('frameReceived', -> (params) {
|
12
|
+
on_frame_received(params['opcode'], params['data'])
|
13
|
+
})
|
14
|
+
@channel.on('socketError', -> (params) {
|
15
|
+
emit(Events::WebSocket::Error, params['error'])
|
16
|
+
})
|
17
|
+
@channel.on('close', -> (_) { on_close })
|
18
|
+
end
|
19
|
+
|
20
|
+
def url
|
21
|
+
@initializer['url']
|
22
|
+
end
|
23
|
+
|
24
|
+
class SocketClosedError < StandardError
|
25
|
+
def initialize
|
26
|
+
super('Socket closed')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class SocketError < StandardError
|
31
|
+
def initialize
|
32
|
+
super('Socket error')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class PageClosedError < StandardError
|
37
|
+
def initialize
|
38
|
+
super('Page closed')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def expect_event(event, predicate: nil, timeout: nil, &block)
|
43
|
+
wait_helper = WaitHelper.new
|
44
|
+
wait_helper.reject_on_timeout(timeout || @parent.send(:timeout_settings).timeout, "Timeout while waiting for event \"#{event}\"")
|
45
|
+
|
46
|
+
unless event == Events::WebSocket::Close
|
47
|
+
wait_helper.reject_on_event(self, Events::WebSocket::Close, SocketClosedError.new)
|
48
|
+
end
|
49
|
+
|
50
|
+
unless event == Events::WebSocket::Error
|
51
|
+
wait_helper.reject_on_event(self, Events::WebSocket::Error, SocketError.new)
|
52
|
+
end
|
53
|
+
|
54
|
+
wait_helper.reject_on_event(@parent, 'close', PageClosedError.new)
|
55
|
+
wait_helper.wait_for_event(self, event, predicate: predicate)
|
56
|
+
block&.call
|
57
|
+
|
58
|
+
wait_helper.promise.value!
|
59
|
+
end
|
60
|
+
alias_method :wait_for_event, :expect_event
|
61
|
+
|
62
|
+
private def on_frame_sent(opcode, data)
|
63
|
+
if opcode == 2
|
64
|
+
emit(Events::WebSocket::FrameSent, Base64.strict_decode64(data))
|
65
|
+
else
|
66
|
+
emit(Events::WebSocket::FrameSent, data)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private def on_frame_received(opcode, data)
|
71
|
+
if opcode == 2
|
72
|
+
emit(Events::WebSocket::FrameReceived, Base64.strict_decode64(data))
|
73
|
+
else
|
74
|
+
emit(Events::WebSocket::FrameReceived, data)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def closed?
|
79
|
+
@closed
|
80
|
+
end
|
81
|
+
|
82
|
+
private def on_close
|
83
|
+
@closed = true
|
84
|
+
emit(Events::WebSocket::Close)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -15,17 +15,17 @@ module Playwright
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# Stop tracing.
|
18
|
-
def stop
|
18
|
+
def stop(path: nil)
|
19
19
|
@channel.send_message_to_server('tracingStop')
|
20
|
-
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
if path
|
22
|
+
resp = @channel.send_message_to_server('tracingExport')
|
23
|
+
artifact = ChannelOwners::Artifact.from(resp)
|
24
|
+
# if self._context._browser:
|
25
|
+
# artifact._is_remote = self._context._browser._is_remote
|
26
|
+
artifact.save_as(path)
|
27
|
+
artifact.delete
|
28
|
+
end
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/lib/playwright/version.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Playwright
|
2
|
-
# Playwright has **experimental** support for Android automation.
|
2
|
+
# Playwright has **experimental** support for Android automation. See [here](./mobile.md) for more information. You can
|
3
|
+
# access android namespace via:
|
3
4
|
#
|
4
5
|
# An example of the Android automation script would be:
|
5
6
|
#
|
6
7
|
# Note that since you don't need Playwright to install web browsers when testing Android, you can omit browser download
|
7
8
|
# via setting the following environment variable when installing Playwright:
|
8
9
|
#
|
9
|
-
# ```
|
10
|
+
# ```bash js
|
10
11
|
# PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i -D playwright
|
11
12
|
# ```
|
12
13
|
class Android < PlaywrightApi
|
@@ -22,12 +23,6 @@ module Playwright
|
|
22
23
|
end
|
23
24
|
alias_method :default_timeout=, :set_default_timeout
|
24
25
|
|
25
|
-
# -- inherited from EventEmitter --
|
26
|
-
# @nodoc
|
27
|
-
def once(event, callback)
|
28
|
-
event_emitter_proxy.once(event, callback)
|
29
|
-
end
|
30
|
-
|
31
26
|
# -- inherited from EventEmitter --
|
32
27
|
# @nodoc
|
33
28
|
def on(event, callback)
|
@@ -40,6 +35,12 @@ module Playwright
|
|
40
35
|
event_emitter_proxy.off(event, callback)
|
41
36
|
end
|
42
37
|
|
38
|
+
# -- inherited from EventEmitter --
|
39
|
+
# @nodoc
|
40
|
+
def once(event, callback)
|
41
|
+
event_emitter_proxy.once(event, callback)
|
42
|
+
end
|
43
|
+
|
43
44
|
private def event_emitter_proxy
|
44
45
|
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
45
46
|
end
|
@@ -171,12 +171,6 @@ module Playwright
|
|
171
171
|
wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
|
172
172
|
end
|
173
173
|
|
174
|
-
# -- inherited from EventEmitter --
|
175
|
-
# @nodoc
|
176
|
-
def once(event, callback)
|
177
|
-
event_emitter_proxy.once(event, callback)
|
178
|
-
end
|
179
|
-
|
180
174
|
# -- inherited from EventEmitter --
|
181
175
|
# @nodoc
|
182
176
|
def on(event, callback)
|
@@ -189,6 +183,12 @@ module Playwright
|
|
189
183
|
event_emitter_proxy.off(event, callback)
|
190
184
|
end
|
191
185
|
|
186
|
+
# -- inherited from EventEmitter --
|
187
|
+
# @nodoc
|
188
|
+
def once(event, callback)
|
189
|
+
event_emitter_proxy.once(event, callback)
|
190
|
+
end
|
191
|
+
|
192
192
|
private def event_emitter_proxy
|
193
193
|
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
194
194
|
end
|
@@ -125,8 +125,9 @@ module Playwright
|
|
125
125
|
storageState: nil,
|
126
126
|
timezoneId: nil,
|
127
127
|
userAgent: nil,
|
128
|
-
viewport: nil
|
129
|
-
|
128
|
+
viewport: nil,
|
129
|
+
&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)))
|
130
131
|
end
|
131
132
|
|
132
133
|
# > NOTE: Tracing is only supported on Chromium-based browsers.
|
@@ -155,12 +156,6 @@ module Playwright
|
|
155
156
|
wrap_impl(@impl.version)
|
156
157
|
end
|
157
158
|
|
158
|
-
# -- inherited from EventEmitter --
|
159
|
-
# @nodoc
|
160
|
-
def once(event, callback)
|
161
|
-
event_emitter_proxy.once(event, callback)
|
162
|
-
end
|
163
|
-
|
164
159
|
# -- inherited from EventEmitter --
|
165
160
|
# @nodoc
|
166
161
|
def on(event, callback)
|
@@ -173,6 +168,12 @@ module Playwright
|
|
173
168
|
event_emitter_proxy.off(event, callback)
|
174
169
|
end
|
175
170
|
|
171
|
+
# -- inherited from EventEmitter --
|
172
|
+
# @nodoc
|
173
|
+
def once(event, callback)
|
174
|
+
event_emitter_proxy.once(event, callback)
|
175
|
+
end
|
176
|
+
|
176
177
|
private def event_emitter_proxy
|
177
178
|
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
178
179
|
end
|
@@ -208,8 +208,8 @@ module Playwright
|
|
208
208
|
end
|
209
209
|
|
210
210
|
# Creates a new page in the browser context.
|
211
|
-
def new_page
|
212
|
-
wrap_impl(@impl.new_page)
|
211
|
+
def new_page(&block)
|
212
|
+
wrap_impl(@impl.new_page(&wrap_block_call(block)))
|
213
213
|
end
|
214
214
|
|
215
215
|
# Returns all open pages in the context.
|
@@ -382,12 +382,6 @@ module Playwright
|
|
382
382
|
wrap_impl(@impl.pause)
|
383
383
|
end
|
384
384
|
|
385
|
-
# -- inherited from EventEmitter --
|
386
|
-
# @nodoc
|
387
|
-
def once(event, callback)
|
388
|
-
event_emitter_proxy.once(event, callback)
|
389
|
-
end
|
390
|
-
|
391
385
|
# -- inherited from EventEmitter --
|
392
386
|
# @nodoc
|
393
387
|
def on(event, callback)
|
@@ -400,6 +394,12 @@ module Playwright
|
|
400
394
|
event_emitter_proxy.off(event, callback)
|
401
395
|
end
|
402
396
|
|
397
|
+
# -- inherited from EventEmitter --
|
398
|
+
# @nodoc
|
399
|
+
def once(event, callback)
|
400
|
+
event_emitter_proxy.once(event, callback)
|
401
|
+
end
|
402
|
+
|
403
403
|
private def event_emitter_proxy
|
404
404
|
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
405
405
|
end
|