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
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
|
+
![sceenrecord](https://user-images.githubusercontent.com/11763113/121126629-71b5f600-c863-11eb-8f88-7924ab669946.gif)
|
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.
|