playwright-ruby-client 1.37.2.alpha1 → 1.38.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|