playwright-ruby-client 0.6.3 → 0.7.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.
- checksums.yaml +4 -4
- data/documentation/docs/api/browser.md +12 -1
- data/documentation/docs/api/browser_context.md +11 -1
- data/documentation/docs/api/browser_type.md +54 -1
- data/documentation/docs/api/cdp_session.md +41 -1
- data/documentation/docs/api/experimental/android.md +3 -2
- data/documentation/docs/api/page.md +18 -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 +45 -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 +13 -14
- data/documentation/package.json +1 -1
- data/documentation/yarn.lock +478 -498
- data/lib/playwright/channel_owners/browser.rb +19 -10
- data/lib/playwright/channel_owners/browser_context.rb +14 -2
- data/lib/playwright/channel_owners/browser_type.rb +23 -8
- data/lib/playwright/channel_owners/cdp_session.rb +19 -0
- data/lib/playwright/channel_owners/page.rb +8 -0
- data/lib/playwright/channel_owners/response.rb +1 -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 +3 -2
- data/lib/playwright_api/browser.rb +4 -3
- data/lib/playwright_api/browser_context.rb +3 -3
- data/lib/playwright_api/browser_type.rb +6 -5
- data/lib/playwright_api/cdp_session.rb +24 -2
- data/lib/playwright_api/page.rb +9 -9
- data/lib/playwright_api/response.rb +0 -5
- data/lib/playwright_api/tracing.rb +6 -12
- data/lib/playwright_api/web_socket.rb +28 -6
- data/playwright.gemspec +2 -1
- metadata +34 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8e3e3982a30add91ed67641a29dcff9778c40788c8434d2ef581cb926951968
|
4
|
+
data.tar.gz: bc7c51236c2d9c2632c53dfe25ae7f9f357c1118a434bb1c41f735a0c67c7625
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b438126a715d3c427408fb4d0b13483bb6f96444cb9c359a946da70125f00b0eee488e5753493a5f9e37ff1294209fd58a044721e0c7b0b2e5c06ef2a8611aef
|
7
|
+
data.tar.gz: a13605776cfca08333630a2e18cf53035d71b6b0ea454a27f76bf0562ef1d505844c70b1119bdca2c2cfd400d402d2c62e06fe38d53abf561c005b6127900c83
|
@@ -61,6 +61,16 @@ def connected?
|
|
61
61
|
|
62
62
|
Indicates that the browser is connected.
|
63
63
|
|
64
|
+
## new_browser_cdp_session
|
65
|
+
|
66
|
+
```
|
67
|
+
def new_browser_cdp_session
|
68
|
+
```
|
69
|
+
|
70
|
+
> NOTE: CDP Sessions are only supported on Chromium-based browsers.
|
71
|
+
|
72
|
+
Returns the newly created browser session.
|
73
|
+
|
64
74
|
## new_context
|
65
75
|
|
66
76
|
```
|
@@ -138,7 +148,8 @@ def new_page(
|
|
138
148
|
storageState: nil,
|
139
149
|
timezoneId: nil,
|
140
150
|
userAgent: nil,
|
141
|
-
viewport: nil
|
151
|
+
viewport: nil,
|
152
|
+
&block)
|
142
153
|
```
|
143
154
|
|
144
155
|
Creates a new page in a new browser context. Closing this page will close the context as well.
|
@@ -226,10 +226,20 @@ def grant_permissions(permissions, origin: nil)
|
|
226
226
|
Grants specified permissions to the browser context. Only grants corresponding permissions to the given origin if
|
227
227
|
specified.
|
228
228
|
|
229
|
+
## new_cdp_session
|
230
|
+
|
231
|
+
```
|
232
|
+
def new_cdp_session(page)
|
233
|
+
```
|
234
|
+
|
235
|
+
> NOTE: CDP sessions are only supported on Chromium-based browsers.
|
236
|
+
|
237
|
+
Returns the newly created session.
|
238
|
+
|
229
239
|
## new_page
|
230
240
|
|
231
241
|
```
|
232
|
-
def new_page
|
242
|
+
def new_page(&block)
|
233
243
|
```
|
234
244
|
|
235
245
|
Creates a new page in the browser context.
|
@@ -65,7 +65,7 @@ def launch(
|
|
65
65
|
proxy: nil,
|
66
66
|
slowMo: nil,
|
67
67
|
timeout: nil,
|
68
|
-
|
68
|
+
tracesDir: nil,
|
69
69
|
&block)
|
70
70
|
```
|
71
71
|
|
@@ -96,6 +96,59 @@ differences between Chromium and Chrome.
|
|
96
96
|
[This article](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md)
|
97
97
|
describes some differences for Linux users.
|
98
98
|
|
99
|
+
## launch_persistent_context
|
100
|
+
|
101
|
+
```
|
102
|
+
def launch_persistent_context(
|
103
|
+
userDataDir,
|
104
|
+
acceptDownloads: nil,
|
105
|
+
args: nil,
|
106
|
+
bypassCSP: nil,
|
107
|
+
channel: nil,
|
108
|
+
chromiumSandbox: nil,
|
109
|
+
colorScheme: nil,
|
110
|
+
deviceScaleFactor: nil,
|
111
|
+
devtools: nil,
|
112
|
+
downloadsPath: nil,
|
113
|
+
env: nil,
|
114
|
+
executablePath: nil,
|
115
|
+
extraHTTPHeaders: nil,
|
116
|
+
geolocation: nil,
|
117
|
+
handleSIGHUP: nil,
|
118
|
+
handleSIGINT: nil,
|
119
|
+
handleSIGTERM: nil,
|
120
|
+
hasTouch: nil,
|
121
|
+
headless: nil,
|
122
|
+
httpCredentials: nil,
|
123
|
+
ignoreDefaultArgs: nil,
|
124
|
+
ignoreHTTPSErrors: nil,
|
125
|
+
isMobile: nil,
|
126
|
+
javaScriptEnabled: nil,
|
127
|
+
locale: nil,
|
128
|
+
noViewport: nil,
|
129
|
+
offline: nil,
|
130
|
+
permissions: nil,
|
131
|
+
proxy: nil,
|
132
|
+
record_har_omit_content: nil,
|
133
|
+
record_har_path: nil,
|
134
|
+
record_video_dir: nil,
|
135
|
+
record_video_size: nil,
|
136
|
+
reducedMotion: nil,
|
137
|
+
screen: nil,
|
138
|
+
slowMo: nil,
|
139
|
+
timeout: nil,
|
140
|
+
timezoneId: nil,
|
141
|
+
tracesDir: nil,
|
142
|
+
userAgent: nil,
|
143
|
+
viewport: nil,
|
144
|
+
&block)
|
145
|
+
```
|
146
|
+
|
147
|
+
Returns the persistent browser context instance.
|
148
|
+
|
149
|
+
Launches browser that uses persistent storage located at `userDataDir` and returns the only context. Closing this
|
150
|
+
context will automatically close the browser.
|
151
|
+
|
99
152
|
## name
|
100
153
|
|
101
154
|
```
|
@@ -4,4 +4,44 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# CDPSession
|
6
6
|
|
7
|
-
|
7
|
+
- extends: [EventEmitter]
|
8
|
+
|
9
|
+
The [CDPSession](./cdp_session) instances are used to talk raw Chrome Devtools Protocol:
|
10
|
+
- protocol methods can be called with `session.send_message` method.
|
11
|
+
- protocol events can be subscribed to with `session.on` method.
|
12
|
+
|
13
|
+
Useful links:
|
14
|
+
- Documentation on DevTools Protocol can be found here:
|
15
|
+
[DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/).
|
16
|
+
- Getting Started with DevTools Protocol:
|
17
|
+
https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
client = page.context.new_cdp_session(page)
|
21
|
+
client.send_message('Animation.enable')
|
22
|
+
client.on('Animation.animationCreated', -> (_) { puts 'Animation Created' })
|
23
|
+
response = client.send_message('Animation.getPlaybackRate')
|
24
|
+
puts "Playback rate is #{response['playbackRate']}"
|
25
|
+
client.send_message(
|
26
|
+
'Animation.setPlaybackRate',
|
27
|
+
params: { playbackRate: response['playbackRate'] / 2.0 },
|
28
|
+
)
|
29
|
+
```
|
30
|
+
|
31
|
+
|
32
|
+
## detach
|
33
|
+
|
34
|
+
```
|
35
|
+
def detach
|
36
|
+
```
|
37
|
+
|
38
|
+
Detaches the CDPSession from the target. Once detached, the CDPSession object won't emit any events and can't be used to
|
39
|
+
send messages.
|
40
|
+
|
41
|
+
## send_message
|
42
|
+
|
43
|
+
```
|
44
|
+
def send_message(method, params: nil)
|
45
|
+
```
|
46
|
+
|
47
|
+
|
@@ -4,14 +4,15 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# Android
|
6
6
|
|
7
|
-
Playwright has **experimental** support for Android automation.
|
7
|
+
Playwright has **experimental** support for Android automation. See [here](https://playwright.dev/python/docs/mobile) for more information. You can
|
8
|
+
access android namespace via:
|
8
9
|
|
9
10
|
An example of the Android automation script would be:
|
10
11
|
|
11
12
|
Note that since you don't need Playwright to install web browsers when testing Android, you can omit browser download
|
12
13
|
via setting the following environment variable when installing Playwright:
|
13
14
|
|
14
|
-
```
|
15
|
+
```bash js
|
15
16
|
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i -D playwright
|
16
17
|
```
|
17
18
|
|
@@ -1328,6 +1328,16 @@ puts request.headers
|
|
1328
1328
|
|
1329
1329
|
|
1330
1330
|
|
1331
|
+
## expect_request_finished
|
1332
|
+
|
1333
|
+
```
|
1334
|
+
def expect_request_finished(predicate: nil, timeout: nil, &block)
|
1335
|
+
```
|
1336
|
+
|
1337
|
+
Performs action and waits for a [Request](./request) to finish loading. If predicate is provided, it passes [Request](./request) value into
|
1338
|
+
the `predicate` function and waits for `predicate(request)` to return a truthy value. Will throw an error if the page is
|
1339
|
+
closed before the [`event: Page.requestFinished`] event is fired.
|
1340
|
+
|
1331
1341
|
## expect_response
|
1332
1342
|
|
1333
1343
|
```
|
@@ -1393,6 +1403,14 @@ page.wait_for_url("**/target.html")
|
|
1393
1403
|
|
1394
1404
|
Shortcut for main frame's [Frame#wait_for_url](./frame#wait_for_url).
|
1395
1405
|
|
1406
|
+
## expect_websocket
|
1407
|
+
|
1408
|
+
```
|
1409
|
+
def expect_websocket(predicate: nil, timeout: nil, &block)
|
1410
|
+
```
|
1411
|
+
|
1412
|
+
Performs action and waits for a new [WebSocket](./web_socket). If predicate is provided, it passes [WebSocket](./web_socket) value into the `predicate` function and waits for `predicate.call(web_socket)` to return a truthy value. Will throw an error if the page is closed before the WebSocket event is fired.
|
1413
|
+
|
1396
1414
|
## accessibility
|
1397
1415
|
|
1398
1416
|
## keyboard
|
@@ -23,18 +23,16 @@ def continue(headers: nil, method: nil, postData: nil, url: nil)
|
|
23
23
|
|
24
24
|
Continues route's request with optional overrides.
|
25
25
|
|
26
|
-
```
|
27
|
-
def handle(route, request)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
page.route("**/*", handle)
|
37
|
-
|
26
|
+
```ruby
|
27
|
+
def handle(route, request)
|
28
|
+
# override headers
|
29
|
+
headers = request.headers
|
30
|
+
headers['foo'] = 'bar' # set "foo" header
|
31
|
+
headers['user-agent'] = 'Unknown Browser' # modify user-agent
|
32
|
+
|
33
|
+
route.continue(headers: headers)
|
34
|
+
end
|
35
|
+
page.route("**/*", method(:handle))
|
38
36
|
```
|
39
37
|
|
40
38
|
|
@@ -54,19 +52,20 @@ Fulfills route's request with given response.
|
|
54
52
|
|
55
53
|
An example of fulfilling all requests with 404 responses:
|
56
54
|
|
57
|
-
```
|
58
|
-
page.route("**/*",
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
```ruby
|
56
|
+
page.route("**/*", ->(route, request) {
|
57
|
+
route.fulfill(
|
58
|
+
status: 404,
|
59
|
+
contentType: 'text/plain',
|
60
|
+
body: 'not found!!',
|
61
|
+
)
|
62
|
+
})
|
63
63
|
```
|
64
64
|
|
65
65
|
An example of serving static file:
|
66
66
|
|
67
|
-
```
|
68
|
-
page.route("**/xhr_endpoint",
|
69
|
-
|
67
|
+
```ruby
|
68
|
+
page.route("**/xhr_endpoint", ->(route, _) { route.fulfill(path: "mock_data.json") })
|
70
69
|
```
|
71
70
|
|
72
71
|
|
@@ -9,24 +9,16 @@ Playwright script runs.
|
|
9
9
|
|
10
10
|
Start with specifying the folder traces will be stored in:
|
11
11
|
|
12
|
-
```python sync title=
|
13
|
-
browser = chromium.launch(
|
12
|
+
```python sync title=example_a767dfb400d98aef50f2767b94171d23474ea1ac1cf9b4d75d412936208e652d.py
|
13
|
+
browser = chromium.launch()
|
14
14
|
context = browser.new_context()
|
15
|
-
context.tracing.start(
|
15
|
+
context.tracing.start(screenshots=True, snapshots=True)
|
16
16
|
page.goto("https://playwright.dev")
|
17
|
-
context.tracing.stop()
|
18
|
-
context.tracing.export("trace.zip")
|
17
|
+
context.tracing.stop(path = "trace.zip")
|
19
18
|
|
20
19
|
```
|
21
20
|
|
22
21
|
|
23
|
-
## export
|
24
|
-
|
25
|
-
```
|
26
|
-
def export(path)
|
27
|
-
```
|
28
|
-
|
29
|
-
Export trace into the file with the given name. Should be called after the tracing has stopped.
|
30
22
|
|
31
23
|
## start
|
32
24
|
|
@@ -36,19 +28,20 @@ def start(name: nil, screenshots: nil, snapshots: nil)
|
|
36
28
|
|
37
29
|
Start tracing.
|
38
30
|
|
39
|
-
```python sync title=
|
31
|
+
```python sync title=example_e611abc8b1066118d0c87eae1bbbb08df655f36d50a94402fc56b8713150997b.py
|
40
32
|
context.tracing.start(name="trace", screenshots=True, snapshots=True)
|
41
33
|
page.goto("https://playwright.dev")
|
42
34
|
context.tracing.stop()
|
43
|
-
context.tracing.
|
35
|
+
context.tracing.stop(path = "trace.zip")
|
44
36
|
|
45
37
|
```
|
46
38
|
|
47
39
|
|
40
|
+
|
48
41
|
## stop
|
49
42
|
|
50
43
|
```
|
51
|
-
def stop
|
44
|
+
def stop(path: nil)
|
52
45
|
```
|
53
46
|
|
54
47
|
Stop tracing.
|
@@ -4,4 +4,41 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# WebSocket
|
6
6
|
|
7
|
-
|
7
|
+
The [WebSocket](./web_socket) class represents websocket connections in the page.
|
8
|
+
|
9
|
+
## closed?
|
10
|
+
|
11
|
+
```
|
12
|
+
def closed?
|
13
|
+
```
|
14
|
+
|
15
|
+
Indicates that the web socket has been closed.
|
16
|
+
|
17
|
+
## url
|
18
|
+
|
19
|
+
```
|
20
|
+
def url
|
21
|
+
```
|
22
|
+
|
23
|
+
Contains the URL of the WebSocket.
|
24
|
+
|
25
|
+
## expect_event
|
26
|
+
|
27
|
+
```
|
28
|
+
def expect_event(event, predicate: nil, timeout: nil, &block)
|
29
|
+
```
|
30
|
+
|
31
|
+
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
|
32
|
+
value. Will throw an error if the webSocket is closed before the event is fired. Returns the event data value.
|
33
|
+
|
34
|
+
## wait_for_event
|
35
|
+
|
36
|
+
```
|
37
|
+
def wait_for_event(event, predicate: nil, timeout: nil, &block)
|
38
|
+
```
|
39
|
+
|
40
|
+
> NOTE: In most cases, you should use [WebSocket#wait_for_event](./web_socket#wait_for_event).
|
41
|
+
|
42
|
+
Waits for given `event` to fire. If predicate is provided, it passes event's value into the `predicate` function and
|
43
|
+
waits for `predicate(event)` to return a truthy value. Will throw an error if the socket is closed before the `event` is
|
44
|
+
fired.
|
@@ -117,3 +117,5 @@ Playwright.create(playwright_cli_executable_path: 'npx playwright') do |playwrig
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
```
|
120
|
+
|
121
|
+
Note that each browser context is isolated and not persisted by default. When persistent browser context is needed, we can use [BrowserType#launch_persistent_context](/docs/api/browser_type#launch_persistent_context).
|
@@ -41,7 +41,7 @@ Capybara.default_max_wait_time = 15
|
|
41
41
|
|
42
42
|
### (Optional) Update default driver
|
43
43
|
|
44
|
-
By default, Capybara driver is set to `:rack_test`, which works only with non-JS contents. If your Rails application has many JavaScript contents, it is recommended to change the default driver to `:
|
44
|
+
By default, Capybara driver is set to `:rack_test`, which works only with non-JS contents. If your Rails application has many JavaScript contents, it is recommended to change the default driver to `:playwright`.
|
45
45
|
|
46
46
|
```rb
|
47
47
|
Capybara.default_driver = :playwright
|
@@ -155,8 +155,51 @@ end
|
|
155
155
|
|
156
156
|
Generally, Capybara DSL seems simple, but Playwright-native scripting are more precise and efficient. Also `waitForNavigation`, `waitForSelector`, and many other Playwright functions are available with Playwright-native scripting.
|
157
157
|
|
158
|
+
### Screen recording
|
159
|
+
|
160
|
+
NO NEED to keep sitting in front of screen during test. Just record what happened with video.
|
161
|
+
|
162
|
+
For example, we can store the video for [Allure report](https://github.com/allure-framework/allure-ruby) as below:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
before do |example|
|
166
|
+
Capybara.current_session.driver.on_save_screenrecord do |video_path|
|
167
|
+
Allure.add_attachment(
|
168
|
+
name: "screenrecord - #{example.description}",
|
169
|
+
source: File.read(video_path),
|
170
|
+
type: Allure::ContentType::WEBM,
|
171
|
+
test_case: true,
|
172
|
+
)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
177
|
+

|
178
|
+
|
179
|
+
For more details, refer [Recording video](./recording_video.md#using-screen-recording-from-capybara-driver)
|
180
|
+
|
181
|
+
|
182
|
+
### Screenshot just before teardown
|
183
|
+
|
184
|
+
In addition to `Capybara::Session#save_screenshot`, capybara-playwright-driver have another method for storing last screen state just before teardown.
|
185
|
+
|
186
|
+
For example, we can attach the screenshot for [Allure report](https://github.com/allure-framework/allure-ruby) as below:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
before do |example|
|
190
|
+
Capybara.current_session.driver.on_save_raw_screenshot_before_reset do |raw_screenshot|
|
191
|
+
Allure.add_attachment(
|
192
|
+
name: "screenshot - #{example.description}",
|
193
|
+
source: raw_screenshot,
|
194
|
+
type: Allure::ContentType::PNG,
|
195
|
+
test_case: true,
|
196
|
+
)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
158
201
|
### Limitations
|
159
202
|
|
160
203
|
* Playwright doesn't allow clicking invisible DOM elements or moving elements. `click` sometimes doesn't work as Selenium does. See the detail in https://playwright.dev/docs/actionability/
|
161
204
|
* `current_window.maximize` and `current_window.fullscreen` work only on headful (non-headless) mode, as selenium driver does.
|
162
|
-
* `Capybara::Node::Element#drag_to` does not accept `html5` parameter
|
205
|
+
* `Capybara::Node::Element#drag_to` does not accept `html5` parameter. HTML5 drag and drop is not fully supported in Playwright.
|