playwright-ruby-client 1.37.2.alpha1 → 1.38.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/README.md +13 -7
- data/documentation/docs/api/download.md +17 -7
- data/documentation/docs/api/element_handle.md +1 -14
- data/documentation/docs/api/frame.md +1 -6
- data/documentation/docs/api/keyboard.md +4 -0
- data/documentation/docs/api/locator.md +31 -16
- data/documentation/docs/api/page.md +1 -6
- data/documentation/docs/api/request.md +17 -0
- data/documentation/docs/include/api_coverage.md +1 -0
- data/lib/playwright/channel_owners/browser_context.rb +15 -0
- data/lib/playwright/channel_owners/page.rb +2 -0
- data/lib/playwright/channel_owners/request.rb +17 -1
- data/lib/playwright/channel_owners/route.rb +5 -1
- data/lib/playwright/connection.rb +0 -3
- data/lib/playwright/errors.rb +13 -2
- data/lib/playwright/events.rb +1 -0
- data/lib/playwright/javascript/value_parser.rb +8 -0
- data/lib/playwright/javascript/value_serializer.rb +10 -4
- data/lib/playwright/locator_impl.rb +4 -0
- data/lib/playwright/transport.rb +0 -6
- data/lib/playwright/utils.rb +4 -0
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/web_socket_transport.rb +0 -8
- data/lib/playwright_api/download.rb +12 -3
- data/lib/playwright_api/element_handle.rb +1 -14
- data/lib/playwright_api/frame.rb +1 -6
- data/lib/playwright_api/keyboard.rb +4 -0
- data/lib/playwright_api/locator.rb +26 -16
- data/lib/playwright_api/page.rb +1 -6
- data/lib/playwright_api/request.rb +17 -0
- data/sig/playwright.rbs +1 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 421d718c0a7b5e649fe2632e9f193ef66722149f63a52ba0c1baa63252a0b99d
|
4
|
+
data.tar.gz: 0fb410e0d38bff1cd589afa3499ac3938c1897220be2a7c9ebcf7bddfa4c157c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da207f741063627b79efb045adff0af67c935926f30cc5086da9fcf2ccf80555c2f449dc57b2cd953d939c0117ed4f6050c93c8ad35a3d9e654b0141d75e1c53
|
7
|
+
data.tar.gz: eac5d5f995949b5e6e925016e2f0ab3ad4dd6c92766e8204023fa84f1a2b50d157659f9bdbb1fcac6500fae64752632b3ed3dfcd6fb042c07706f3ce30c00b48
|
data/README.md
CHANGED
@@ -51,18 +51,24 @@ Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwrigh
|
|
51
51
|
page = browser.new_page
|
52
52
|
page.goto('https://github.com/')
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
page.get_by_placeholder("Search or jump to...").click
|
55
|
+
page.locator('input[name="query-builder-test"]').click
|
56
|
+
|
57
|
+
expect(page.keyboard).to be_a(::Playwright::Keyboard)
|
58
|
+
|
57
59
|
page.keyboard.type("playwright")
|
58
60
|
page.expect_navigation {
|
59
61
|
page.keyboard.press("Enter")
|
60
62
|
}
|
61
63
|
|
62
|
-
list = page.
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
list = page.get_by_test_id('results-list').locator('.search-title')
|
65
|
+
|
66
|
+
# wait for item to appear
|
67
|
+
list.first.wait_for
|
68
|
+
|
69
|
+
# list them
|
70
|
+
list.locator('.search-title').all.each do |item|
|
71
|
+
title = item.text_content
|
66
72
|
puts("==> #{title}")
|
67
73
|
end
|
68
74
|
end
|
@@ -10,15 +10,18 @@ sidebar_position: 10
|
|
10
10
|
All the downloaded files belonging to the browser context are deleted when the
|
11
11
|
browser context is closed.
|
12
12
|
|
13
|
-
Download event is emitted once the download starts. Download path becomes available once download completes
|
13
|
+
Download event is emitted once the download starts. Download path becomes available once download completes.
|
14
14
|
|
15
|
-
```
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
```python sync title=example_c247767083cf193df26a39a61a3a8bc19d63ed5c24db91b88c50b7d37975005d.py
|
16
|
+
# Start waiting for the download
|
17
|
+
with page.expect_download() as download_info:
|
18
|
+
# Perform the action that initiates download
|
19
|
+
page.get_by_text("Download file").click()
|
20
|
+
download = download_info.value
|
21
|
+
|
22
|
+
# Wait for the download process to complete and save the downloaded file somewhere
|
23
|
+
download.save_as("/path/to/save/at/" + download.suggested_filename)
|
19
24
|
|
20
|
-
# wait for download to complete
|
21
|
-
path = download.path
|
22
25
|
```
|
23
26
|
|
24
27
|
## cancel
|
@@ -81,6 +84,13 @@ def save_as(path)
|
|
81
84
|
Copy the download to a user-specified path. It is safe to call this method while the download
|
82
85
|
is still in progress. Will wait for the download to finish if necessary.
|
83
86
|
|
87
|
+
**Usage**
|
88
|
+
|
89
|
+
```python sync title=example_66ffd4ef7286957e4294d84b8f660ff852c87af27a56b3e4dd9f84562b5ece02.py
|
90
|
+
download.save_as("/path/to/save/at/" + download.suggested_filename)
|
91
|
+
|
92
|
+
```
|
93
|
+
|
84
94
|
## suggested_filename
|
85
95
|
|
86
96
|
```
|
@@ -259,7 +259,7 @@ This method waits for [actionability](https://playwright.dev/python/docs/actiona
|
|
259
259
|
|
260
260
|
If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
261
261
|
|
262
|
-
To send fine-grained keyboard events, use [
|
262
|
+
To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
|
263
263
|
|
264
264
|
## focus
|
265
265
|
|
@@ -614,19 +614,6 @@ To press a special key, like `Control` or `ArrowDown`, use [ElementHandle#press]
|
|
614
614
|
|
615
615
|
**Usage**
|
616
616
|
|
617
|
-
```ruby
|
618
|
-
element_handle.type("hello") # types instantly
|
619
|
-
element_handle.type("world", delay: 100) # types slower, like a user
|
620
|
-
```
|
621
|
-
|
622
|
-
An example of typing into a text field and then submitting the form:
|
623
|
-
|
624
|
-
```ruby
|
625
|
-
element_handle = page.query_selector("input")
|
626
|
-
element_handle.type("some text")
|
627
|
-
element_handle.press("Enter")
|
628
|
-
```
|
629
|
-
|
630
617
|
## uncheck
|
631
618
|
|
632
619
|
```
|
@@ -349,7 +349,7 @@ This method waits for an element matching `selector`, waits for [actionability](
|
|
349
349
|
|
350
350
|
If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
351
351
|
|
352
|
-
To send fine-grained keyboard events, use [
|
352
|
+
To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
|
353
353
|
|
354
354
|
## focus
|
355
355
|
|
@@ -1041,11 +1041,6 @@ To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./ke
|
|
1041
1041
|
|
1042
1042
|
**Usage**
|
1043
1043
|
|
1044
|
-
```ruby
|
1045
|
-
frame.type("#mytextarea", "hello") # types instantly
|
1046
|
-
frame.type("#mytextarea", "world", delay: 100) # types slower, like a user
|
1047
|
-
```
|
1048
|
-
|
1049
1044
|
## uncheck
|
1050
1045
|
|
1051
1046
|
```
|
@@ -97,6 +97,8 @@ def press(key, delay: nil)
|
|
97
97
|
```
|
98
98
|
|
99
99
|
|
100
|
+
**NOTE**: In most cases, you should use [Locator#press](./locator#press) instead.
|
101
|
+
|
100
102
|
`key` can specify the intended
|
101
103
|
[keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
|
102
104
|
generate the text for. A superset of the `key` values can be found
|
@@ -136,6 +138,8 @@ def type(text, delay: nil)
|
|
136
138
|
```
|
137
139
|
|
138
140
|
|
141
|
+
**NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator#press_sequentially](./locator#press_sequentially).
|
142
|
+
|
139
143
|
Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
140
144
|
|
141
145
|
To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
|
@@ -458,7 +458,7 @@ This method waits for [actionability](https://playwright.dev/python/docs/actiona
|
|
458
458
|
|
459
459
|
If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
460
460
|
|
461
|
-
To send fine-grained keyboard events, use [Locator#
|
461
|
+
To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
|
462
462
|
|
463
463
|
## filter
|
464
464
|
|
@@ -1032,6 +1032,36 @@ respective texts.
|
|
1032
1032
|
Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When specified with the
|
1033
1033
|
modifier, modifier is pressed and being held while the subsequent key is being pressed.
|
1034
1034
|
|
1035
|
+
## press_sequentially
|
1036
|
+
|
1037
|
+
```
|
1038
|
+
def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
1039
|
+
```
|
1040
|
+
|
1041
|
+
|
1042
|
+
**NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to press keys one by one if there is special keyboard handling on the page.
|
1043
|
+
|
1044
|
+
Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
1045
|
+
|
1046
|
+
To press a special key, like `Control` or `ArrowDown`, use [Locator#press](./locator#press).
|
1047
|
+
|
1048
|
+
**Usage**
|
1049
|
+
|
1050
|
+
```python sync title=example_1b7781d5527574a18d4b9812e3461203d2acc9ba7e09cbfd0ffbc4154e3f5971.py
|
1051
|
+
locator.press_sequentially("hello") # types instantly
|
1052
|
+
locator.press_sequentially("world", delay=100) # types slower, like a user
|
1053
|
+
|
1054
|
+
```
|
1055
|
+
|
1056
|
+
An example of typing into a text field and then submitting the form:
|
1057
|
+
|
1058
|
+
```python sync title=example_cc0a6b9aa95b97e5c17c4b114da10a29c7f6f793e99aee1ea2703636af6e24f9.py
|
1059
|
+
locator = page.get_by_label("Password")
|
1060
|
+
locator.press_sequentially("my password")
|
1061
|
+
locator.press("Enter")
|
1062
|
+
|
1063
|
+
```
|
1064
|
+
|
1035
1065
|
## screenshot
|
1036
1066
|
|
1037
1067
|
```
|
@@ -1254,27 +1284,12 @@ def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
|
1254
1284
|
```
|
1255
1285
|
|
1256
1286
|
|
1257
|
-
**NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to type characters if there is special keyboard handling on the page.
|
1258
|
-
|
1259
1287
|
Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
1260
1288
|
|
1261
1289
|
To press a special key, like `Control` or `ArrowDown`, use [Locator#press](./locator#press).
|
1262
1290
|
|
1263
1291
|
**Usage**
|
1264
1292
|
|
1265
|
-
```ruby
|
1266
|
-
element.type("hello") # types instantly
|
1267
|
-
element.type("world", delay: 100) # types slower, like a user
|
1268
|
-
```
|
1269
|
-
|
1270
|
-
An example of typing into a text field and then submitting the form:
|
1271
|
-
|
1272
|
-
```ruby
|
1273
|
-
element = page.get_by_label("Password")
|
1274
|
-
element.type("my password")
|
1275
|
-
element.press("Enter")
|
1276
|
-
```
|
1277
|
-
|
1278
1293
|
## uncheck
|
1279
1294
|
|
1280
1295
|
```
|
@@ -554,7 +554,7 @@ This method waits for an element matching `selector`, waits for [actionability](
|
|
554
554
|
|
555
555
|
If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
556
556
|
|
557
|
-
To send fine-grained keyboard events, use [
|
557
|
+
To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
|
558
558
|
|
559
559
|
## focus
|
560
560
|
|
@@ -1519,11 +1519,6 @@ To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./ke
|
|
1519
1519
|
|
1520
1520
|
**Usage**
|
1521
1521
|
|
1522
|
-
```ruby
|
1523
|
-
page.type("#mytextarea", "hello") # types instantly
|
1524
|
-
page.type("#mytextarea", "world", delay: 100) # types slower, like a user
|
1525
|
-
```
|
1526
|
-
|
1527
1522
|
## uncheck
|
1528
1523
|
|
1529
1524
|
```
|
@@ -54,6 +54,20 @@ def frame
|
|
54
54
|
|
55
55
|
Returns the [Frame](./frame) that initiated this request.
|
56
56
|
|
57
|
+
**Usage**
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
frame_url = request.frame.url
|
61
|
+
```
|
62
|
+
|
63
|
+
**Details**
|
64
|
+
|
65
|
+
Note that in some cases the frame is not available, and this method will throw.
|
66
|
+
- When request originates in the Service Worker. You can use `request.serviceWorker()` to check that.
|
67
|
+
- When navigation request is issued before the corresponding frame is created. You can use [Request#navigation_request?](./request#navigation_request?) to check that.
|
68
|
+
|
69
|
+
Here is an example that handles all the cases:
|
70
|
+
|
57
71
|
## headers
|
58
72
|
|
59
73
|
```
|
@@ -93,6 +107,9 @@ def navigation_request?
|
|
93
107
|
|
94
108
|
Whether this request is driving frame's navigation.
|
95
109
|
|
110
|
+
Some navigation requests are issued before the corresponding frame is created, and therefore
|
111
|
+
do not have [Request#frame](./request#frame) available.
|
112
|
+
|
96
113
|
## method
|
97
114
|
|
98
115
|
```
|
@@ -38,6 +38,12 @@ module Playwright
|
|
38
38
|
@channel.on('console', ->(params) {
|
39
39
|
on_console_message(ChannelOwners::ConsoleMessage.from(params['message']))
|
40
40
|
})
|
41
|
+
@channel.on('pageError', ->(params) {
|
42
|
+
on_page_error(
|
43
|
+
Error.parse(params['error']['error']),
|
44
|
+
ChannelOwners::Page.from_nullable(params['page']),
|
45
|
+
)
|
46
|
+
})
|
41
47
|
@channel.on('dialog', ->(params) {
|
42
48
|
on_dialog(ChannelOwners::Dialog.from(params['dialog']))
|
43
49
|
})
|
@@ -97,6 +103,8 @@ module Playwright
|
|
97
103
|
end
|
98
104
|
|
99
105
|
private def on_route(route)
|
106
|
+
route.send(:update_context, self)
|
107
|
+
|
100
108
|
# It is not desired to use PlaywrightApi.wrap directly.
|
101
109
|
# However it is a little difficult to define wrapper for `handler` parameter in generate_api.
|
102
110
|
# Just a workaround...
|
@@ -177,6 +185,13 @@ module Playwright
|
|
177
185
|
end
|
178
186
|
end
|
179
187
|
|
188
|
+
private def on_page_error(error, page)
|
189
|
+
emit(Events::BrowserContext::WebError, WebError.new(error, page))
|
190
|
+
if page
|
191
|
+
page.emit(Events::Page::PageError, error)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
180
195
|
private def on_request(request, page)
|
181
196
|
emit(Events::BrowserContext::Request, request)
|
182
197
|
page&.emit(Events::Page::Request, request)
|
@@ -96,6 +96,8 @@ module Playwright
|
|
96
96
|
end
|
97
97
|
|
98
98
|
private def on_route(route)
|
99
|
+
route.send(:update_context, self)
|
100
|
+
|
99
101
|
# It is not desired to use PlaywrightApi.wrap directly.
|
100
102
|
# However it is a little difficult to define wrapper for `handler` parameter in generate_api.
|
101
103
|
# Just a workaround...
|
@@ -86,8 +86,24 @@ module Playwright
|
|
86
86
|
ChannelOwners::Response.from_nullable(resp)
|
87
87
|
end
|
88
88
|
|
89
|
+
class FramePageNotReadyError < StandardError
|
90
|
+
MESSAGE = [
|
91
|
+
'Frame for this navigation request is not available, because the request',
|
92
|
+
'was issued before the frame is created. You can check whether the request',
|
93
|
+
'is a navigation request by calling isNavigationRequest() method.',
|
94
|
+
].join('\n').freeze
|
95
|
+
|
96
|
+
def initialize
|
97
|
+
super(MESSAGE)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
89
101
|
def frame
|
90
|
-
ChannelOwners::Frame.from(@initializer['frame'])
|
102
|
+
ChannelOwners::Frame.from(@initializer['frame']).tap do |result|
|
103
|
+
unless result.page
|
104
|
+
raise FramePageNotReadyError.new
|
105
|
+
end
|
106
|
+
end
|
91
107
|
end
|
92
108
|
|
93
109
|
def navigation_request?
|
@@ -111,7 +111,7 @@ module Playwright
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def fetch(headers: nil, method: nil, postData: nil, url: nil, maxRedirects: nil, timeout: nil)
|
114
|
-
api_request_context =
|
114
|
+
api_request_context = @context.request
|
115
115
|
api_request_context.send(:_inner_fetch,
|
116
116
|
request,
|
117
117
|
url,
|
@@ -172,5 +172,9 @@ module Playwright
|
|
172
172
|
mime_types = MIME::Types.type_for(filepath)
|
173
173
|
mime_types.first.to_s || 'application/octet-stream'
|
174
174
|
end
|
175
|
+
|
176
|
+
private def update_context(context)
|
177
|
+
@context = context
|
178
|
+
end
|
175
179
|
end
|
176
180
|
end
|
data/lib/playwright/errors.rb
CHANGED
@@ -5,13 +5,13 @@ module Playwright
|
|
5
5
|
if error_payload['name'] == 'TimeoutError'
|
6
6
|
TimeoutError.new(
|
7
7
|
message: error_payload['message'],
|
8
|
-
stack: error_payload['stack']
|
8
|
+
stack: error_payload['stack'],
|
9
9
|
)
|
10
10
|
else
|
11
11
|
new(
|
12
12
|
name: error_payload['name'],
|
13
13
|
message: error_payload['message'],
|
14
|
-
stack: error_payload['stack']
|
14
|
+
stack: error_payload['stack'],
|
15
15
|
)
|
16
16
|
end
|
17
17
|
end
|
@@ -25,6 +25,8 @@ module Playwright
|
|
25
25
|
@message = message
|
26
26
|
@stack = stack
|
27
27
|
end
|
28
|
+
|
29
|
+
attr_reader :name, :message, :stack
|
28
30
|
end
|
29
31
|
|
30
32
|
class DriverCrashedError < StandardError
|
@@ -38,4 +40,13 @@ module Playwright
|
|
38
40
|
super(name: 'TimeoutError', message: message, stack: stack)
|
39
41
|
end
|
40
42
|
end
|
43
|
+
|
44
|
+
class WebError
|
45
|
+
def initialize(error, page)
|
46
|
+
@error = error
|
47
|
+
@page = PlaywrightApi.wrap(page)
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_reader :error, :page
|
51
|
+
end
|
41
52
|
end
|
data/lib/playwright/events.rb
CHANGED
@@ -56,6 +56,14 @@ module Playwright
|
|
56
56
|
return hash['bi'].to_i
|
57
57
|
end
|
58
58
|
|
59
|
+
if hash.key?('m')
|
60
|
+
return parse_hash(hash['m']).to_h
|
61
|
+
end
|
62
|
+
|
63
|
+
if hash.key?('se')
|
64
|
+
return Set.new(parse_hash(hash['se']))
|
65
|
+
end
|
66
|
+
|
59
67
|
if hash.key?('r')
|
60
68
|
# @see https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
61
69
|
# @see https://docs.ruby-lang.org/ja/latest/class/Regexp.html
|
@@ -56,11 +56,17 @@ module Playwright
|
|
56
56
|
result = []
|
57
57
|
value.each { |v| result << serialize_value(v) }
|
58
58
|
{ a: result, id: id }
|
59
|
+
when Set
|
60
|
+
{ se: serialize_value(value.to_a) }
|
59
61
|
when Hash
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
if value.any? { |k, v| !k.is_a?(String) && !k.is_a?(Symbol) } # Map
|
63
|
+
{ m: serialize_value(value.to_a) }
|
64
|
+
else
|
65
|
+
id = @visited.log(value)
|
66
|
+
result = []
|
67
|
+
value.each { |key, v| result << { k: key, v: serialize_value(v) } }
|
68
|
+
{ o: result, id: id }
|
69
|
+
end
|
64
70
|
else
|
65
71
|
raise ArgumentError.new("Unexpected value: #{value}")
|
66
72
|
end
|
@@ -446,6 +446,10 @@ module Playwright
|
|
446
446
|
@frame.type(@selector, text, strict: true, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
|
447
447
|
end
|
448
448
|
|
449
|
+
def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
450
|
+
type(text, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
|
451
|
+
end
|
452
|
+
|
449
453
|
def uncheck(
|
450
454
|
force: nil,
|
451
455
|
noWaitAfter: nil,
|
data/lib/playwright/transport.rb
CHANGED
@@ -18,10 +18,6 @@ module Playwright
|
|
18
18
|
@on_message = block
|
19
19
|
end
|
20
20
|
|
21
|
-
def on_driver_closed(&block)
|
22
|
-
@on_driver_closed = block
|
23
|
-
end
|
24
|
-
|
25
21
|
def on_driver_crashed(&block)
|
26
22
|
@on_driver_crashed = block
|
27
23
|
end
|
@@ -87,7 +83,6 @@ module Playwright
|
|
87
83
|
end
|
88
84
|
rescue IOError
|
89
85
|
# disconnected by remote.
|
90
|
-
@on_driver_closed&.call
|
91
86
|
end
|
92
87
|
|
93
88
|
def handle_stderr
|
@@ -111,7 +106,6 @@ module Playwright
|
|
111
106
|
end
|
112
107
|
rescue IOError
|
113
108
|
# disconnected by remote.
|
114
|
-
@on_driver_closed&.call
|
115
109
|
end
|
116
110
|
|
117
111
|
def debug_send_message(message)
|
data/lib/playwright/utils.rb
CHANGED
data/lib/playwright/version.rb
CHANGED
@@ -15,10 +15,6 @@ module Playwright
|
|
15
15
|
@on_message = block
|
16
16
|
end
|
17
17
|
|
18
|
-
def on_driver_closed(&block)
|
19
|
-
@on_driver_closed = block
|
20
|
-
end
|
21
|
-
|
22
18
|
def on_driver_crashed(&block)
|
23
19
|
@on_driver_crashed = block
|
24
20
|
end
|
@@ -80,10 +76,6 @@ module Playwright
|
|
80
76
|
|
81
77
|
ws.start
|
82
78
|
@ws = promise.value!
|
83
|
-
@ws.on_close do |reason, code|
|
84
|
-
puts "[WebSocketTransport] closed with code: #{code}, reason: #{reason}"
|
85
|
-
@on_driver_closed&.call(reason, code)
|
86
|
-
end
|
87
79
|
@ws.on_error do |error|
|
88
80
|
puts "[WebSocketTransport] error: #{error}"
|
89
81
|
@on_driver_crashed&.call
|
@@ -5,14 +5,17 @@ module Playwright
|
|
5
5
|
# All the downloaded files belonging to the browser context are deleted when the
|
6
6
|
# browser context is closed.
|
7
7
|
#
|
8
|
-
# Download event is emitted once the download starts. Download path becomes available once download completes
|
8
|
+
# Download event is emitted once the download starts. Download path becomes available once download completes.
|
9
9
|
#
|
10
10
|
# ```python sync
|
11
|
+
# # Start waiting for the download
|
11
12
|
# with page.expect_download() as download_info:
|
13
|
+
# # Perform the action that initiates download
|
12
14
|
# page.get_by_text("Download file").click()
|
13
15
|
# download = download_info.value
|
14
|
-
#
|
15
|
-
#
|
16
|
+
#
|
17
|
+
# # Wait for the download process to complete and save the downloaded file somewhere
|
18
|
+
# download.save_as("/path/to/save/at/" + download.suggested_filename)
|
16
19
|
# ```
|
17
20
|
class Download < PlaywrightApi
|
18
21
|
|
@@ -54,6 +57,12 @@ module Playwright
|
|
54
57
|
#
|
55
58
|
# Copy the download to a user-specified path. It is safe to call this method while the download
|
56
59
|
# is still in progress. Will wait for the download to finish if necessary.
|
60
|
+
#
|
61
|
+
# **Usage**
|
62
|
+
#
|
63
|
+
# ```python sync
|
64
|
+
# download.save_as("/path/to/save/at/" + download.suggested_filename)
|
65
|
+
# ```
|
57
66
|
def save_as(path)
|
58
67
|
wrap_impl(@impl.save_as(unwrap_impl(path)))
|
59
68
|
end
|
@@ -224,7 +224,7 @@ module Playwright
|
|
224
224
|
#
|
225
225
|
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
226
226
|
#
|
227
|
-
# To send fine-grained keyboard events, use [`method:
|
227
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
228
228
|
def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
|
229
229
|
wrap_impl(@impl.fill(unwrap_impl(value), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
230
230
|
end
|
@@ -503,19 +503,6 @@ module Playwright
|
|
503
503
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: ElementHandle.press`].
|
504
504
|
#
|
505
505
|
# **Usage**
|
506
|
-
#
|
507
|
-
# ```python sync
|
508
|
-
# element_handle.type("hello") # types instantly
|
509
|
-
# element_handle.type("world", delay=100) # types slower, like a user
|
510
|
-
# ```
|
511
|
-
#
|
512
|
-
# An example of typing into a text field and then submitting the form:
|
513
|
-
#
|
514
|
-
# ```python sync
|
515
|
-
# element_handle = page.query_selector("input")
|
516
|
-
# element_handle.type("some text")
|
517
|
-
# element_handle.press("Enter")
|
518
|
-
# ```
|
519
506
|
def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
520
507
|
wrap_impl(@impl.type(unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
521
508
|
end
|
data/lib/playwright_api/frame.rb
CHANGED
@@ -300,7 +300,7 @@ module Playwright
|
|
300
300
|
#
|
301
301
|
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
302
302
|
#
|
303
|
-
# To send fine-grained keyboard events, use [`method:
|
303
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
304
304
|
def fill(
|
305
305
|
selector,
|
306
306
|
value,
|
@@ -867,11 +867,6 @@ module Playwright
|
|
867
867
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.press`].
|
868
868
|
#
|
869
869
|
# **Usage**
|
870
|
-
#
|
871
|
-
# ```python sync
|
872
|
-
# frame.type("#mytextarea", "hello") # types instantly
|
873
|
-
# frame.type("#mytextarea", "world", delay=100) # types slower, like a user
|
874
|
-
# ```
|
875
870
|
def type(
|
876
871
|
selector,
|
877
872
|
text,
|
@@ -81,6 +81,8 @@ module Playwright
|
|
81
81
|
wrap_impl(@impl.insert_text(unwrap_impl(text)))
|
82
82
|
end
|
83
83
|
|
84
|
+
#
|
85
|
+
# **NOTE**: In most cases, you should use [`method: Locator.press`] instead.
|
84
86
|
#
|
85
87
|
# `key` can specify the intended
|
86
88
|
# [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
|
@@ -119,6 +121,8 @@ module Playwright
|
|
119
121
|
wrap_impl(@impl.press(unwrap_impl(key), delay: unwrap_impl(delay)))
|
120
122
|
end
|
121
123
|
|
124
|
+
#
|
125
|
+
# **NOTE**: In most cases, you should use [`method: Locator.fill`] instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [`method: Locator.pressSequentially`].
|
122
126
|
#
|
123
127
|
# Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
124
128
|
#
|
@@ -391,7 +391,7 @@ module Playwright
|
|
391
391
|
#
|
392
392
|
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
393
393
|
#
|
394
|
-
# To send fine-grained keyboard events, use [`method: Locator.
|
394
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
395
395
|
def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
|
396
396
|
wrap_impl(@impl.fill(unwrap_impl(value), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
397
397
|
end
|
@@ -869,6 +869,31 @@ module Playwright
|
|
869
869
|
wrap_impl(@impl.press(unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
870
870
|
end
|
871
871
|
|
872
|
+
#
|
873
|
+
# **NOTE**: In most cases, you should use [`method: Locator.fill`] instead. You only need to press keys one by one if there is special keyboard handling on the page.
|
874
|
+
#
|
875
|
+
# Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
876
|
+
#
|
877
|
+
# To press a special key, like `Control` or `ArrowDown`, use [`method: Locator.press`].
|
878
|
+
#
|
879
|
+
# **Usage**
|
880
|
+
#
|
881
|
+
# ```python sync
|
882
|
+
# locator.press_sequentially("hello") # types instantly
|
883
|
+
# locator.press_sequentially("world", delay=100) # types slower, like a user
|
884
|
+
# ```
|
885
|
+
#
|
886
|
+
# An example of typing into a text field and then submitting the form:
|
887
|
+
#
|
888
|
+
# ```python sync
|
889
|
+
# locator = page.get_by_label("Password")
|
890
|
+
# locator.press_sequentially("my password")
|
891
|
+
# locator.press("Enter")
|
892
|
+
# ```
|
893
|
+
def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
894
|
+
wrap_impl(@impl.press_sequentially(unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
895
|
+
end
|
896
|
+
|
872
897
|
#
|
873
898
|
# Take a screenshot of the element matching the locator.
|
874
899
|
#
|
@@ -1066,27 +1091,12 @@ module Playwright
|
|
1066
1091
|
wrap_impl(@impl.text_content(timeout: unwrap_impl(timeout)))
|
1067
1092
|
end
|
1068
1093
|
|
1069
|
-
#
|
1070
|
-
# **NOTE**: In most cases, you should use [`method: Locator.fill`] instead. You only need to type characters if there is special keyboard handling on the page.
|
1071
1094
|
#
|
1072
1095
|
# Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
1073
1096
|
#
|
1074
1097
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: Locator.press`].
|
1075
1098
|
#
|
1076
1099
|
# **Usage**
|
1077
|
-
#
|
1078
|
-
# ```python sync
|
1079
|
-
# element.type("hello") # types instantly
|
1080
|
-
# element.type("world", delay=100) # types slower, like a user
|
1081
|
-
# ```
|
1082
|
-
#
|
1083
|
-
# An example of typing into a text field and then submitting the form:
|
1084
|
-
#
|
1085
|
-
# ```python sync
|
1086
|
-
# element = page.get_by_label("Password")
|
1087
|
-
# element.type("my password")
|
1088
|
-
# element.press("Enter")
|
1089
|
-
# ```
|
1090
1100
|
def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
1091
1101
|
wrap_impl(@impl.type(unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
1092
1102
|
end
|
data/lib/playwright_api/page.rb
CHANGED
@@ -532,7 +532,7 @@ module Playwright
|
|
532
532
|
#
|
533
533
|
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
534
534
|
#
|
535
|
-
# To send fine-grained keyboard events, use [`method:
|
535
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
536
536
|
def fill(
|
537
537
|
selector,
|
538
538
|
value,
|
@@ -1340,11 +1340,6 @@ module Playwright
|
|
1340
1340
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.press`].
|
1341
1341
|
#
|
1342
1342
|
# **Usage**
|
1343
|
-
#
|
1344
|
-
# ```python sync
|
1345
|
-
# page.type("#mytextarea", "hello") # types instantly
|
1346
|
-
# page.type("#mytextarea", "world", delay=100) # types slower, like a user
|
1347
|
-
# ```
|
1348
1343
|
def type(
|
1349
1344
|
selector,
|
1350
1345
|
text,
|
@@ -37,6 +37,20 @@ module Playwright
|
|
37
37
|
|
38
38
|
#
|
39
39
|
# Returns the `Frame` that initiated this request.
|
40
|
+
#
|
41
|
+
# **Usage**
|
42
|
+
#
|
43
|
+
# ```py
|
44
|
+
# frame_url = request.frame.url
|
45
|
+
# ```
|
46
|
+
#
|
47
|
+
# **Details**
|
48
|
+
#
|
49
|
+
# Note that in some cases the frame is not available, and this method will throw.
|
50
|
+
# - When request originates in the Service Worker. You can use `request.serviceWorker()` to check that.
|
51
|
+
# - When navigation request is issued before the corresponding frame is created. You can use [`method: Request.isNavigationRequest`] to check that.
|
52
|
+
#
|
53
|
+
# Here is an example that handles all the cases:
|
40
54
|
def frame
|
41
55
|
wrap_impl(@impl.frame)
|
42
56
|
end
|
@@ -64,6 +78,9 @@ module Playwright
|
|
64
78
|
|
65
79
|
#
|
66
80
|
# Whether this request is driving frame's navigation.
|
81
|
+
#
|
82
|
+
# Some navigation requests are issued before the corresponding frame is created, and therefore
|
83
|
+
# do not have [`method: Request.frame`] available.
|
67
84
|
def navigation_request?
|
68
85
|
wrap_impl(@impl.navigation_request?)
|
69
86
|
end
|
data/sig/playwright.rbs
CHANGED
@@ -483,6 +483,7 @@ module Playwright
|
|
483
483
|
def or: (Locator locator) -> Locator
|
484
484
|
def page: -> Page
|
485
485
|
def press: (String key, ?delay: Float, ?noWaitAfter: bool, ?timeout: Float) -> void
|
486
|
+
def press_sequentially: (String text, ?delay: Float, ?noWaitAfter: bool, ?timeout: Float) -> void
|
486
487
|
def screenshot: (?animations: ("disabled" | "allow"), ?caret: ("hide" | "initial"), ?mask: Array[untyped], ?maskColor: String, ?omitBackground: bool, ?path: (String | File), ?quality: Integer, ?scale: ("css" | "device"), ?timeout: Float, ?type: ("png" | "jpeg")) -> String
|
487
488
|
def scroll_into_view_if_needed: (?timeout: Float) -> void
|
488
489
|
def select_option: (?element: (ElementHandle | Array[untyped]), ?index: (Integer | Array[untyped]), ?value: (String | Array[untyped]), ?label: (String | Array[untyped]), ?force: bool, ?noWaitAfter: bool, ?timeout: Float) -> Array[untyped]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playwright-ruby-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.38.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -394,12 +394,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
394
394
|
version: '2.4'
|
395
395
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
396
396
|
requirements:
|
397
|
-
- - "
|
397
|
+
- - ">="
|
398
398
|
- !ruby/object:Gem::Version
|
399
|
-
version:
|
399
|
+
version: '0'
|
400
400
|
requirements: []
|
401
401
|
rubygems_version: 3.3.26
|
402
402
|
signing_key:
|
403
403
|
specification_version: 4
|
404
|
-
summary: The Ruby binding of playwright driver 1.
|
404
|
+
summary: The Ruby binding of playwright driver 1.38.0
|
405
405
|
test_files: []
|