playwright-ruby-client 1.26.0 → 1.28.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/api_request_context.md +86 -0
- data/documentation/docs/api/browser_context.md +3 -3
- data/documentation/docs/api/download.md +1 -1
- data/documentation/docs/api/element_handle.md +2 -1
- data/documentation/docs/api/file_chooser.md +1 -1
- data/documentation/docs/api/frame.md +151 -4
- data/documentation/docs/api/frame_locator.md +151 -4
- data/documentation/docs/api/js_handle.md +5 -3
- data/documentation/docs/api/keyboard.md +1 -1
- data/documentation/docs/api/locator.md +191 -6
- data/documentation/docs/api/page.md +166 -9
- data/documentation/docs/api/request.md +1 -1
- data/documentation/docs/api/tracing.md +1 -1
- data/documentation/docs/article/guides/rails_integration.md +1 -0
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +59 -0
- data/documentation/docs/include/api_coverage.md +32 -0
- data/lib/playwright/channel_owner.rb +41 -0
- data/lib/playwright/channel_owners/browser_context.rb +6 -0
- data/lib/playwright/channel_owners/element_handle.rb +8 -1
- data/lib/playwright/channel_owners/frame.rb +6 -0
- data/lib/playwright/channel_owners/page.rb +25 -28
- data/lib/playwright/channel_owners/selectors.rb +4 -0
- data/lib/playwright/connection.rb +4 -1
- data/lib/playwright/frame_locator_impl.rb +6 -2
- data/lib/playwright/locator_impl.rb +21 -31
- data/lib/playwright/locator_utils.rb +136 -0
- data/lib/playwright/utils.rb +6 -0
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/android.rb +12 -6
- data/lib/playwright_api/android_device.rb +6 -6
- data/lib/playwright_api/api_request_context.rb +86 -8
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +9 -9
- data/lib/playwright_api/browser_type.rb +6 -6
- data/lib/playwright_api/cdp_session.rb +6 -6
- data/lib/playwright_api/console_message.rb +6 -6
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/download.rb +1 -1
- data/lib/playwright_api/element_handle.rb +9 -8
- data/lib/playwright_api/file_chooser.rb +1 -1
- data/lib/playwright_api/frame.rb +119 -11
- data/lib/playwright_api/frame_locator.rb +113 -5
- data/lib/playwright_api/js_handle.rb +7 -7
- data/lib/playwright_api/keyboard.rb +1 -1
- data/lib/playwright_api/locator.rb +145 -6
- data/lib/playwright_api/page.rb +133 -16
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +9 -9
- data/lib/playwright_api/response.rb +8 -8
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/selectors.rb +14 -3
- data/lib/playwright_api/tracing.rb +7 -7
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +8 -8
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d96f4cf4c170f020d8b73571e23f61e994e535708759b0148aec799110f3d72
|
4
|
+
data.tar.gz: cc6471e1da4e8f02d8b98b960a84feb67251bafd7781dec9c0d103385474f098
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 953724a4d98d278b2bcd63a580f433b1defb630534023ae2c3c2df426ef4717a89c6c0e546fb76df5df7ae0b16cfd01d494be36c277d890f1774d65551932fdc
|
7
|
+
data.tar.gz: 92be169ac6c6adeac4ac7346df21dd929de1021e38f99f01eba73a74c4327d0436b97e6ea074560f49520eada9a6cd29f399ae144a7baa93fd64cec1c63c9cd4
|
@@ -106,15 +106,47 @@ def fetch(
|
|
106
106
|
Sends HTTP(S) request and returns its response. The method will populate request cookies from the context and update
|
107
107
|
context cookies from the response. The method will automatically follow redirects.
|
108
108
|
|
109
|
+
JSON objects can be passed directly to the request:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
data = {
|
113
|
+
title: "Book Title",
|
114
|
+
body: "John Doe",
|
115
|
+
}
|
116
|
+
api_request_context.fetch("https://example.com/api/create_book", method: 'post', data: data)
|
117
|
+
```
|
118
|
+
|
119
|
+
The common way to send file(s) in the body of a request is to encode it as form fields with `multipart/form-data`
|
120
|
+
encoding. You can achieve that with Playwright API like this:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
api_request_context.fetch(
|
124
|
+
"https://example.com/api/upload_script",
|
125
|
+
method: 'post',
|
126
|
+
multipart: {
|
127
|
+
fileField: {
|
128
|
+
name: "f.js",
|
129
|
+
mimeType: "text/javascript",
|
130
|
+
buffer: "console.log(2022);",
|
131
|
+
},
|
132
|
+
},
|
133
|
+
)
|
134
|
+
```
|
135
|
+
|
136
|
+
|
137
|
+
|
109
138
|
## get
|
110
139
|
|
111
140
|
```
|
112
141
|
def get(
|
113
142
|
url,
|
143
|
+
data: nil,
|
114
144
|
failOnStatusCode: nil,
|
145
|
+
form: nil,
|
115
146
|
headers: nil,
|
116
147
|
ignoreHTTPSErrors: nil,
|
117
148
|
maxRedirects: nil,
|
149
|
+
multipart: nil,
|
118
150
|
params: nil,
|
119
151
|
timeout: nil)
|
120
152
|
```
|
@@ -123,15 +155,30 @@ Sends HTTP(S) [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GE
|
|
123
155
|
method will populate request cookies from the context and update context cookies from the response. The method will
|
124
156
|
automatically follow redirects.
|
125
157
|
|
158
|
+
Request parameters can be configured with `params` option, they will be serialized into the URL search parameters:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
query_params = {
|
162
|
+
isbn: "1234",
|
163
|
+
page: "23"
|
164
|
+
}
|
165
|
+
api_request_context.get("https://example.com/api/get_text", params: query_params)
|
166
|
+
```
|
167
|
+
|
168
|
+
|
169
|
+
|
126
170
|
## head
|
127
171
|
|
128
172
|
```
|
129
173
|
def head(
|
130
174
|
url,
|
175
|
+
data: nil,
|
131
176
|
failOnStatusCode: nil,
|
177
|
+
form: nil,
|
132
178
|
headers: nil,
|
133
179
|
ignoreHTTPSErrors: nil,
|
134
180
|
maxRedirects: nil,
|
181
|
+
multipart: nil,
|
135
182
|
params: nil,
|
136
183
|
timeout: nil)
|
137
184
|
```
|
@@ -180,6 +227,45 @@ Sends HTTP(S) [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/P
|
|
180
227
|
The method will populate request cookies from the context and update context cookies from the response. The method will
|
181
228
|
automatically follow redirects.
|
182
229
|
|
230
|
+
JSON objects can be passed directly to the request:
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
data = {
|
234
|
+
title: "Book Title",
|
235
|
+
body: "John Doe",
|
236
|
+
}
|
237
|
+
api_request_context.post("https://example.com/api/create_book", data: data)
|
238
|
+
```
|
239
|
+
|
240
|
+
To send form data to the server use `form` option. Its value will be encoded into the request body with
|
241
|
+
`application/x-www-form-urlencoded` encoding (see below how to use `multipart/form-data` form encoding to send files):
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
form_data = {
|
245
|
+
title: "Book Title",
|
246
|
+
body: "John Doe",
|
247
|
+
}
|
248
|
+
api_request_context.post("https://example.com/api/find_book", form: form_data)
|
249
|
+
```
|
250
|
+
|
251
|
+
The common way to send file(s) in the body of a request is to upload them as form fields with `multipart/form-data`
|
252
|
+
encoding. You can achieve that with Playwright API like this:
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
api_request_context.post(
|
256
|
+
"https://example.com/api/upload_script",
|
257
|
+
multipart: {
|
258
|
+
fileField: {
|
259
|
+
name: "f.js",
|
260
|
+
mimeType: "text/javascript",
|
261
|
+
buffer: "console.log(2022);",
|
262
|
+
},
|
263
|
+
},
|
264
|
+
)
|
265
|
+
```
|
266
|
+
|
267
|
+
|
268
|
+
|
183
269
|
## put
|
184
270
|
|
185
271
|
```
|
@@ -161,7 +161,7 @@ page.content = <<~HTML
|
|
161
161
|
<div></div>
|
162
162
|
HTML
|
163
163
|
|
164
|
-
page.
|
164
|
+
page.get_by_role("button").click
|
165
165
|
```
|
166
166
|
|
167
167
|
An example of passing an element handle:
|
@@ -222,7 +222,7 @@ page.content = <<~HTML
|
|
222
222
|
<button onclick="onClick()">Click me</button>
|
223
223
|
<div></div>
|
224
224
|
HTML
|
225
|
-
page.
|
225
|
+
page.get_by_role("button").click
|
226
226
|
```
|
227
227
|
|
228
228
|
|
@@ -434,7 +434,7 @@ value. Will throw an error if the context closes before the event is fired. Retu
|
|
434
434
|
|
435
435
|
```ruby
|
436
436
|
new_page = browser_context.expect_event('page') do
|
437
|
-
page.
|
437
|
+
page.get_by_role("button").click
|
438
438
|
end
|
439
439
|
```
|
440
440
|
|
@@ -39,7 +39,7 @@ With the locator, every time the `element` is used, up-to-date DOM element is lo
|
|
39
39
|
in the snippet below, underlying DOM element is going to be located twice.
|
40
40
|
|
41
41
|
```ruby
|
42
|
-
locator = page.
|
42
|
+
locator = page.get_by_text("Submit")
|
43
43
|
locator.hover
|
44
44
|
locator.click
|
45
45
|
```
|
@@ -292,6 +292,7 @@ Returns element attribute value.
|
|
292
292
|
def hover(
|
293
293
|
force: nil,
|
294
294
|
modifiers: nil,
|
295
|
+
noWaitAfter: nil,
|
295
296
|
position: nil,
|
296
297
|
timeout: nil,
|
297
298
|
trial: nil)
|
@@ -8,7 +8,7 @@ sidebar_position: 10
|
|
8
8
|
|
9
9
|
```ruby
|
10
10
|
file_chooser = page.expect_file_chooser do
|
11
|
-
page.
|
11
|
+
page.get_by_text("Upload").click # action to trigger file uploading
|
12
12
|
end
|
13
13
|
file_chooser.set_files("myfile.pdf")
|
14
14
|
```
|
@@ -401,7 +401,7 @@ that iframe. Following snippet locates element with text "Submit" in the iframe
|
|
401
401
|
id="my-frame">`:
|
402
402
|
|
403
403
|
```ruby
|
404
|
-
locator = frame.frame_locator("#my-iframe").
|
404
|
+
locator = frame.frame_locator("#my-iframe").get_by_text("Submit")
|
405
405
|
locator.click
|
406
406
|
```
|
407
407
|
|
@@ -415,6 +415,150 @@ def get_attribute(selector, name, strict: nil, timeout: nil)
|
|
415
415
|
|
416
416
|
Returns element attribute value.
|
417
417
|
|
418
|
+
## get_by_alt_text
|
419
|
+
|
420
|
+
```
|
421
|
+
def get_by_alt_text(text, exact: nil)
|
422
|
+
```
|
423
|
+
|
424
|
+
Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
|
425
|
+
|
426
|
+
```html
|
427
|
+
<img alt='Castle'>
|
428
|
+
```
|
429
|
+
|
430
|
+
|
431
|
+
## get_by_label
|
432
|
+
|
433
|
+
```
|
434
|
+
def get_by_label(text, exact: nil)
|
435
|
+
```
|
436
|
+
|
437
|
+
Allows locating input elements by the text of the associated label. For example, this method will find the input by
|
438
|
+
label text "Password" in the following DOM:
|
439
|
+
|
440
|
+
```html
|
441
|
+
<label for="password-input">Password:</label>
|
442
|
+
<input id="password-input">
|
443
|
+
```
|
444
|
+
|
445
|
+
|
446
|
+
## get_by_placeholder
|
447
|
+
|
448
|
+
```
|
449
|
+
def get_by_placeholder(text, exact: nil)
|
450
|
+
```
|
451
|
+
|
452
|
+
Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
|
453
|
+
"Country":
|
454
|
+
|
455
|
+
```html
|
456
|
+
<input placeholder="Country">
|
457
|
+
```
|
458
|
+
|
459
|
+
|
460
|
+
## get_by_role
|
461
|
+
|
462
|
+
```
|
463
|
+
def get_by_role(
|
464
|
+
role,
|
465
|
+
checked: nil,
|
466
|
+
disabled: nil,
|
467
|
+
exact: nil,
|
468
|
+
expanded: nil,
|
469
|
+
includeHidden: nil,
|
470
|
+
level: nil,
|
471
|
+
name: nil,
|
472
|
+
pressed: nil,
|
473
|
+
selected: nil)
|
474
|
+
```
|
475
|
+
|
476
|
+
Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
|
477
|
+
[ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
|
478
|
+
[accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
|
479
|
+
accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
|
480
|
+
|
481
|
+
Note that many html elements have an implicitly
|
482
|
+
[defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
|
483
|
+
can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
|
484
|
+
recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
|
485
|
+
|
486
|
+
## get_by_test_id
|
487
|
+
|
488
|
+
```
|
489
|
+
def get_by_test_id(testId)
|
490
|
+
```
|
491
|
+
|
492
|
+
Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
|
493
|
+
[Selectors#set_test_id_attribute](./selectors#set_test_id_attribute) to configure a different test id attribute if necessary.
|
494
|
+
|
495
|
+
|
496
|
+
|
497
|
+
## get_by_text
|
498
|
+
|
499
|
+
```
|
500
|
+
def get_by_text(text, exact: nil)
|
501
|
+
```
|
502
|
+
|
503
|
+
Allows locating elements that contain given text. Consider the following DOM structure:
|
504
|
+
|
505
|
+
```html
|
506
|
+
<div>Hello <span>world</span></div>
|
507
|
+
<div>Hello</div>
|
508
|
+
```
|
509
|
+
|
510
|
+
You can locate by text substring, exact string, or a regular expression:
|
511
|
+
|
512
|
+
```ruby
|
513
|
+
page.content = <<~HTML
|
514
|
+
<div>Hello <span>world</span></div>
|
515
|
+
<div>Hello</div>
|
516
|
+
HTML
|
517
|
+
|
518
|
+
# Matches <span>
|
519
|
+
locator = page.get_by_text("world")
|
520
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<span>world</span>')
|
521
|
+
|
522
|
+
# Matches first <div>
|
523
|
+
locator = page.get_by_text("Hello world")
|
524
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
|
525
|
+
|
526
|
+
# Matches second <div>
|
527
|
+
locator = page.get_by_text("Hello", exact: true)
|
528
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
|
529
|
+
|
530
|
+
# Matches both <div>s
|
531
|
+
locator = page.get_by_text(/Hello/)
|
532
|
+
expect(locator.count).to eq(2)
|
533
|
+
expect(locator.first.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
|
534
|
+
expect(locator.last.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
|
535
|
+
|
536
|
+
# Matches second <div>
|
537
|
+
locator = page.get_by_text(/^hello$/i)
|
538
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
|
539
|
+
```
|
540
|
+
|
541
|
+
See also [Locator#filter](./locator#filter) that allows to match by another criteria, like an accessible role, and then filter
|
542
|
+
by the text content.
|
543
|
+
|
544
|
+
> NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
|
545
|
+
one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
546
|
+
> NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
|
547
|
+
example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
548
|
+
|
549
|
+
## get_by_title
|
550
|
+
|
551
|
+
```
|
552
|
+
def get_by_title(text, exact: nil)
|
553
|
+
```
|
554
|
+
|
555
|
+
Allows locating elements by their title. For example, this method will find the button by its title "Place the order":
|
556
|
+
|
557
|
+
```html
|
558
|
+
<button title='Place the order'>Order Now</button>
|
559
|
+
```
|
560
|
+
|
561
|
+
|
418
562
|
## goto
|
419
563
|
|
420
564
|
```
|
@@ -447,6 +591,7 @@ def hover(
|
|
447
591
|
selector,
|
448
592
|
force: nil,
|
449
593
|
modifiers: nil,
|
594
|
+
noWaitAfter: nil,
|
450
595
|
position: nil,
|
451
596
|
strict: nil,
|
452
597
|
timeout: nil,
|
@@ -555,9 +700,11 @@ considered not visible.
|
|
555
700
|
def locator(selector, has: nil, hasText: nil)
|
556
701
|
```
|
557
702
|
|
558
|
-
The method returns an element locator that can be used to perform actions
|
559
|
-
element immediately before performing an action, so a series of actions on the same locator can in fact be performed
|
560
|
-
different DOM elements. That would happen if the DOM structure between those actions has changed.
|
703
|
+
The method returns an element locator that can be used to perform actions on this page / frame. Locator is resolved to
|
704
|
+
the element immediately before performing an action, so a series of actions on the same locator can in fact be performed
|
705
|
+
on different DOM elements. That would happen if the DOM structure between those actions has changed.
|
706
|
+
|
707
|
+
[Learn more about locators](https://playwright.dev/python/docs/locators).
|
561
708
|
|
562
709
|
[Learn more about locators](https://playwright.dev/python/docs/locators).
|
563
710
|
|
@@ -9,7 +9,7 @@ and locate elements in that iframe. FrameLocator can be created with either [Pag
|
|
9
9
|
[Locator#frame_locator](./locator#frame_locator) method.
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
locator = page.frame_locator("my-frame").
|
12
|
+
locator = page.frame_locator("my-frame").get_by_text("Submit")
|
13
13
|
locator.click
|
14
14
|
```
|
15
15
|
|
@@ -20,10 +20,10 @@ a given selector.
|
|
20
20
|
|
21
21
|
```ruby
|
22
22
|
# Throws if there are several frames in DOM:
|
23
|
-
page.frame_locator('.result-frame').
|
23
|
+
page.frame_locator('.result-frame').get_by_role('button').click
|
24
24
|
|
25
25
|
# Works because we explicitly tell locator to pick the first frame:
|
26
|
-
page.frame_locator('.result-frame').first.
|
26
|
+
page.frame_locator('.result-frame').first.get_by_role('button').click
|
27
27
|
```
|
28
28
|
|
29
29
|
**Converting Locator to FrameLocator**
|
@@ -54,6 +54,150 @@ def frame_locator(selector)
|
|
54
54
|
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
55
55
|
that iframe.
|
56
56
|
|
57
|
+
## get_by_alt_text
|
58
|
+
|
59
|
+
```
|
60
|
+
def get_by_alt_text(text, exact: nil)
|
61
|
+
```
|
62
|
+
|
63
|
+
Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
|
64
|
+
|
65
|
+
```html
|
66
|
+
<img alt='Castle'>
|
67
|
+
```
|
68
|
+
|
69
|
+
|
70
|
+
## get_by_label
|
71
|
+
|
72
|
+
```
|
73
|
+
def get_by_label(text, exact: nil)
|
74
|
+
```
|
75
|
+
|
76
|
+
Allows locating input elements by the text of the associated label. For example, this method will find the input by
|
77
|
+
label text "Password" in the following DOM:
|
78
|
+
|
79
|
+
```html
|
80
|
+
<label for="password-input">Password:</label>
|
81
|
+
<input id="password-input">
|
82
|
+
```
|
83
|
+
|
84
|
+
|
85
|
+
## get_by_placeholder
|
86
|
+
|
87
|
+
```
|
88
|
+
def get_by_placeholder(text, exact: nil)
|
89
|
+
```
|
90
|
+
|
91
|
+
Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
|
92
|
+
"Country":
|
93
|
+
|
94
|
+
```html
|
95
|
+
<input placeholder="Country">
|
96
|
+
```
|
97
|
+
|
98
|
+
|
99
|
+
## get_by_role
|
100
|
+
|
101
|
+
```
|
102
|
+
def get_by_role(
|
103
|
+
role,
|
104
|
+
checked: nil,
|
105
|
+
disabled: nil,
|
106
|
+
exact: nil,
|
107
|
+
expanded: nil,
|
108
|
+
includeHidden: nil,
|
109
|
+
level: nil,
|
110
|
+
name: nil,
|
111
|
+
pressed: nil,
|
112
|
+
selected: nil)
|
113
|
+
```
|
114
|
+
|
115
|
+
Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
|
116
|
+
[ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
|
117
|
+
[accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
|
118
|
+
accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
|
119
|
+
|
120
|
+
Note that many html elements have an implicitly
|
121
|
+
[defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
|
122
|
+
can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
|
123
|
+
recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
|
124
|
+
|
125
|
+
## get_by_test_id
|
126
|
+
|
127
|
+
```
|
128
|
+
def get_by_test_id(testId)
|
129
|
+
```
|
130
|
+
|
131
|
+
Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
|
132
|
+
[Selectors#set_test_id_attribute](./selectors#set_test_id_attribute) to configure a different test id attribute if necessary.
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
## get_by_text
|
137
|
+
|
138
|
+
```
|
139
|
+
def get_by_text(text, exact: nil)
|
140
|
+
```
|
141
|
+
|
142
|
+
Allows locating elements that contain given text. Consider the following DOM structure:
|
143
|
+
|
144
|
+
```html
|
145
|
+
<div>Hello <span>world</span></div>
|
146
|
+
<div>Hello</div>
|
147
|
+
```
|
148
|
+
|
149
|
+
You can locate by text substring, exact string, or a regular expression:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
page.content = <<~HTML
|
153
|
+
<div>Hello <span>world</span></div>
|
154
|
+
<div>Hello</div>
|
155
|
+
HTML
|
156
|
+
|
157
|
+
# Matches <span>
|
158
|
+
locator = page.get_by_text("world")
|
159
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<span>world</span>')
|
160
|
+
|
161
|
+
# Matches first <div>
|
162
|
+
locator = page.get_by_text("Hello world")
|
163
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
|
164
|
+
|
165
|
+
# Matches second <div>
|
166
|
+
locator = page.get_by_text("Hello", exact: true)
|
167
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
|
168
|
+
|
169
|
+
# Matches both <div>s
|
170
|
+
locator = page.get_by_text(/Hello/)
|
171
|
+
expect(locator.count).to eq(2)
|
172
|
+
expect(locator.first.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
|
173
|
+
expect(locator.last.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
|
174
|
+
|
175
|
+
# Matches second <div>
|
176
|
+
locator = page.get_by_text(/^hello$/i)
|
177
|
+
expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
|
178
|
+
```
|
179
|
+
|
180
|
+
See also [Locator#filter](./locator#filter) that allows to match by another criteria, like an accessible role, and then filter
|
181
|
+
by the text content.
|
182
|
+
|
183
|
+
> NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
|
184
|
+
one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
185
|
+
> NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
|
186
|
+
example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
187
|
+
|
188
|
+
## get_by_title
|
189
|
+
|
190
|
+
```
|
191
|
+
def get_by_title(text, exact: nil)
|
192
|
+
```
|
193
|
+
|
194
|
+
Allows locating elements by their title. For example, this method will find the button by its title "Place the order":
|
195
|
+
|
196
|
+
```html
|
197
|
+
<button title='Place the order'>Order Now</button>
|
198
|
+
```
|
199
|
+
|
200
|
+
|
57
201
|
## last
|
58
202
|
|
59
203
|
```
|
@@ -68,7 +212,10 @@ Returns locator to the last matching frame.
|
|
68
212
|
def locator(selector, has: nil, hasText: nil)
|
69
213
|
```
|
70
214
|
|
71
|
-
The method finds an element matching the specified selector in the
|
215
|
+
The method finds an element matching the specified selector in the locator's subtree. It also accepts filter options,
|
216
|
+
similar to [Locator#filter](./locator#filter) method.
|
217
|
+
|
218
|
+
[Learn more about locators](https://playwright.dev/python/docs/locators).
|
72
219
|
|
73
220
|
## nth
|
74
221
|
|
@@ -85,10 +85,12 @@ The method returns a map with **own property names** as keys and JSHandle instan
|
|
85
85
|
|
86
86
|
```ruby
|
87
87
|
page.goto('https://example.com/')
|
88
|
-
|
89
|
-
properties =
|
88
|
+
handle = page.evaluate_handle("({window, document})")
|
89
|
+
properties = handle.properties
|
90
90
|
puts properties
|
91
|
-
window_handle
|
91
|
+
window_handle = properties["window"]
|
92
|
+
document_handle = properties["document"]
|
93
|
+
handle.dispose
|
92
94
|
```
|
93
95
|
|
94
96
|
|
@@ -5,7 +5,7 @@ sidebar_position: 10
|
|
5
5
|
# Keyboard
|
6
6
|
|
7
7
|
Keyboard provides an api for managing a virtual keyboard. The high level api is [Keyboard#type](./keyboard#type), which takes
|
8
|
-
raw characters and generates proper keydown
|
8
|
+
raw characters and generates proper `keydown`, `keypress`/`input`, and `keyup` events on your page.
|
9
9
|
|
10
10
|
For finer control, you can use [Keyboard#down](./keyboard#down), [Keyboard#up](./keyboard#up), and [Keyboard#insert_text](./keyboard#insert_text)
|
11
11
|
to manually fire events as if they were generated from a real keyboard.
|