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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9342eb9d31cb69d5eee5734d2143505672336cb630599f5d92a3e07559b76421
|
4
|
+
data.tar.gz: 66a5f38c686c7477037740cddf2d6572b63b21dd791f92a0c179fd292ee0b8e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9adc1be3cbef06c38bcb1080e26c8b816311dc81573b6d089f55fd286e9e29d9a29831f1655a2d8189d1c20ed6bea0fd108a98ed347d4c1c1281753d64cddd2b
|
7
|
+
data.tar.gz: f65e5ff953e8b1f6ef54a031cda1a53819bdb0c62caa44b5dc34a2011bc1d72d867a838de98bc7e2cbc8b0d34899cf19b6b89c4d008aa7a98f60871e91b3021e
|
@@ -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,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
|
|
@@ -1393,6 +1393,14 @@ page.wait_for_url("**/target.html")
|
|
1393
1393
|
|
1394
1394
|
Shortcut for main frame's [Frame#wait_for_url](./frame#wait_for_url).
|
1395
1395
|
|
1396
|
+
## expect_websocket
|
1397
|
+
|
1398
|
+
```
|
1399
|
+
def expect_websocket(predicate: nil, timeout: nil, &block)
|
1400
|
+
```
|
1401
|
+
|
1402
|
+
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.
|
1403
|
+
|
1396
1404
|
## accessibility
|
1397
1405
|
|
1398
1406
|
## 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,11 +41,165 @@ 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
|
48
48
|
Capybara.javascript_driver = :playwright
|
49
49
|
```
|
50
50
|
|
51
|
-
It is not mandatry. Without changing the default driver, you can still use Playwright driver by specifying `Capybara.current_driver = :
|
51
|
+
It is not mandatry. Without changing the default driver, you can still use Playwright driver by specifying `Capybara.current_driver = :playwright` (or `driven_by :playwright` in system spec) explicitly.
|
52
|
+
|
53
|
+
### (reference) Available driver options
|
54
|
+
|
55
|
+
These parameters can be passed into `Capybara::Playwright::Driver.new`
|
56
|
+
|
57
|
+
* `playwright_cli_executable_path`
|
58
|
+
* Refer [this article](./download_playwright_driver) to understand what to specify.
|
59
|
+
* `browser_type`
|
60
|
+
* `:chromium` (default), `:firefox`, or `:webkit`
|
61
|
+
* Parameters for [Playwright::BrowserType#launch](/docs/api/browser_type#launch)
|
62
|
+
* args
|
63
|
+
* channel
|
64
|
+
* `chrome`, `msedge`, `chrome-beta`, `chrome-dev`, `chrome-canary`, `msedge-beta`, `msedge-dev` Browser distribution channel. Read more about using [Google Chrome & Microsoft Edge](https://playwright.dev/docs/browsers#google-chrome--microsoft-edge)
|
65
|
+
* devtools
|
66
|
+
* downloadsPath
|
67
|
+
* env
|
68
|
+
* executablePath
|
69
|
+
* firefoxUserPrefs
|
70
|
+
* headless
|
71
|
+
* ignoreDefaultArgs
|
72
|
+
* proxy
|
73
|
+
* slowMo
|
74
|
+
* timeout
|
75
|
+
* Parameters for [Playwright::Browser#new_context](/docs/api/browser#new_context)
|
76
|
+
* bypassCSP
|
77
|
+
* colorScheme
|
78
|
+
* deviceScaleFactor
|
79
|
+
* extraHTTPHeaders
|
80
|
+
* geolocation
|
81
|
+
* hasTouch
|
82
|
+
* httpCredentials
|
83
|
+
* ignoreHTTPSErrors
|
84
|
+
* isMobile
|
85
|
+
* javaScriptEnabled
|
86
|
+
* locale
|
87
|
+
* noViewport
|
88
|
+
* offline
|
89
|
+
* permissions
|
90
|
+
* proxy
|
91
|
+
* record_har_omit_content
|
92
|
+
* record_har_path
|
93
|
+
* record_video_dir
|
94
|
+
* record_video_size
|
95
|
+
* screen
|
96
|
+
* storageState
|
97
|
+
* timezoneId
|
98
|
+
* userAgent
|
99
|
+
* viewport
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
driver_opts = {
|
103
|
+
# `playwright` command path.
|
104
|
+
playwright_cli_executable_path: './node_modules/.bin/playwright',
|
105
|
+
|
106
|
+
# Use firefox for testing.
|
107
|
+
browser_type: :firefox,
|
108
|
+
|
109
|
+
# Headful mode.
|
110
|
+
headless: false,
|
111
|
+
|
112
|
+
# Slower operation
|
113
|
+
slowMo: 50, # integer. (50-100 would be good for most cases)
|
114
|
+
}
|
115
|
+
|
116
|
+
Capybara::Playwright::Driver.new(app, driver_opts)
|
117
|
+
```
|
118
|
+
|
119
|
+
|
120
|
+
## Available functions and Limitations
|
121
|
+
|
122
|
+
### Capybara DSL
|
123
|
+
|
124
|
+
Most of the methods of `Capybara::Session` and `Capybara::Node::Element` are available. However the following method is not yet implemented.
|
125
|
+
|
126
|
+
* `Capybara::Node::Element#drop`
|
127
|
+
|
128
|
+
### Playwright-native scripting
|
129
|
+
|
130
|
+
We can also describe Playwright-native automation script using `with_playwright_page` and `with_playwright_element_handle`.
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
# With Capybara DSL
|
134
|
+
find('a[data-item-type="global_search"]').click
|
135
|
+
|
136
|
+
# With Playwright-native Page
|
137
|
+
Capybara.current_session.driver.with_playwright_page do |page|
|
138
|
+
# `page` is an instance of Playwright::Page.
|
139
|
+
page.click('a[data-item-type="global_search"]')
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
all('.list-item').each do |li|
|
145
|
+
# With Capybara::Node::Element method
|
146
|
+
puts li.all('a').first.text
|
147
|
+
|
148
|
+
# With Playwright-native ElementHandle
|
149
|
+
puts li.with_playwright_element_handle do |handle|
|
150
|
+
# `handle` is an instance of Playwright::ElementHandle
|
151
|
+
handle.query_selector('a').text_content
|
152
|
+
end
|
153
|
+
end
|
154
|
+
```
|
155
|
+
|
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
|
+
|
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
|
+
|
201
|
+
### Limitations
|
202
|
+
|
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/
|
204
|
+
* `current_window.maximize` and `current_window.fullscreen` work only on headful (non-headless) mode, as selenium driver does.
|
205
|
+
* `Capybara::Node::Element#drag_to` does not accept `html5` parameter.
|