playwright-ruby-client 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|