playwright-ruby-client 1.39.0 → 1.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/documentation/docs/api/browser.md +9 -13
- data/documentation/docs/api/browser_context.md +32 -51
- data/documentation/docs/api/browser_type.md +7 -12
- data/documentation/docs/api/dialog.md +15 -18
- data/documentation/docs/api/download.md +9 -10
- data/documentation/docs/api/element_handle.md +5 -6
- data/documentation/docs/api/frame.md +24 -54
- data/documentation/docs/api/locator.md +20 -22
- data/documentation/docs/api/locator_assertions.md +642 -0
- data/documentation/docs/api/page.md +48 -101
- data/documentation/docs/api/playwright.md +20 -23
- data/documentation/docs/api/selectors.md +29 -34
- data/documentation/docs/include/api_coverage.md +43 -0
- data/lib/playwright/channel.rb +1 -1
- data/lib/playwright/errors.rb +2 -0
- data/lib/playwright/javascript/value_serializer.rb +1 -1
- data/lib/playwright/locator_assertions_impl.rb +417 -0
- data/lib/playwright/locator_impl.rb +24 -5
- data/lib/playwright/test.rb +68 -0
- data/lib/playwright/version.rb +1 -1
- data/lib/playwright_api/locator.rb +5 -0
- data/lib/playwright_api/locator_assertions.rb +551 -0
- data/sig/playwright.rbs +43 -0
- metadata +6 -2
@@ -0,0 +1,642 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 10
|
3
|
+
---
|
4
|
+
|
5
|
+
# LocatorAssertions
|
6
|
+
|
7
|
+
|
8
|
+
The LocatorAssertions class provides assertion methods for RSpec like `expect(locator).to have_text("Something")`. Note that we have to explicitly include `playwright/test` and `Playwright::Test::Matchers` for using RSpec matchers.
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
require 'playwright/test'
|
12
|
+
|
13
|
+
describe 'your system testing' do
|
14
|
+
include Playwright::Test::Matchers
|
15
|
+
```
|
16
|
+
|
17
|
+
Since the matcher comes with auto-waiting feature, we don't have to describe trivial codes waiting for elements any more :)
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
page.content = <<~HTML
|
21
|
+
<div id="my_status" class="status">Pending</div>
|
22
|
+
<button onClick="setTimeout(() => { document.getElementById('my_status').innerText='Something Submitted!!' }, 2000)">Click me</button>
|
23
|
+
HTML
|
24
|
+
|
25
|
+
page.get_by_role("button").click
|
26
|
+
expect(page.locator(".status")).to have_text("Submitted") # auto-waiting
|
27
|
+
```
|
28
|
+
|
29
|
+
## not_to_be_attached
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
expect(locator).not_to be_attached(attached: nil, timeout: nil)
|
33
|
+
```
|
34
|
+
|
35
|
+
|
36
|
+
The opposite of [LocatorAssertions#to_be_attached](./locator_assertions#to_be_attached).
|
37
|
+
|
38
|
+
## not_to_be_checked
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
expect(locator).not_to be_checked(timeout: nil)
|
42
|
+
```
|
43
|
+
|
44
|
+
|
45
|
+
The opposite of [LocatorAssertions#to_be_checked](./locator_assertions#to_be_checked).
|
46
|
+
|
47
|
+
## not_to_be_disabled
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
expect(locator).not_to be_disabled(timeout: nil)
|
51
|
+
```
|
52
|
+
|
53
|
+
|
54
|
+
The opposite of [LocatorAssertions#to_be_disabled](./locator_assertions#to_be_disabled).
|
55
|
+
|
56
|
+
## not_to_be_editable
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
expect(locator).not_to be_editable(editable: nil, timeout: nil)
|
60
|
+
```
|
61
|
+
|
62
|
+
|
63
|
+
The opposite of [LocatorAssertions#to_be_editable](./locator_assertions#to_be_editable).
|
64
|
+
|
65
|
+
## not_to_be_empty
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
expect(locator).not_to be_empty(timeout: nil)
|
69
|
+
```
|
70
|
+
|
71
|
+
|
72
|
+
The opposite of [LocatorAssertions#to_be_empty](./locator_assertions#to_be_empty).
|
73
|
+
|
74
|
+
## not_to_be_enabled
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
expect(locator).not_to be_enabled(enabled: nil, timeout: nil)
|
78
|
+
```
|
79
|
+
|
80
|
+
|
81
|
+
The opposite of [LocatorAssertions#to_be_enabled](./locator_assertions#to_be_enabled).
|
82
|
+
|
83
|
+
## not_to_be_focused
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
expect(locator).not_to be_focused(timeout: nil)
|
87
|
+
```
|
88
|
+
|
89
|
+
|
90
|
+
The opposite of [LocatorAssertions#to_be_focused](./locator_assertions#to_be_focused).
|
91
|
+
|
92
|
+
## not_to_be_hidden
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
expect(locator).not_to be_hidden(timeout: nil)
|
96
|
+
```
|
97
|
+
|
98
|
+
|
99
|
+
The opposite of [LocatorAssertions#to_be_hidden](./locator_assertions#to_be_hidden).
|
100
|
+
|
101
|
+
## not_to_be_in_viewport
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
expect(locator).not_to be_in_viewport(ratio: nil, timeout: nil)
|
105
|
+
```
|
106
|
+
|
107
|
+
|
108
|
+
The opposite of [LocatorAssertions#to_be_in_viewport](./locator_assertions#to_be_in_viewport).
|
109
|
+
|
110
|
+
## not_to_be_visible
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
expect(locator).not_to be_visible(timeout: nil, visible: nil)
|
114
|
+
```
|
115
|
+
|
116
|
+
|
117
|
+
The opposite of [LocatorAssertions#to_be_visible](./locator_assertions#to_be_visible).
|
118
|
+
|
119
|
+
## not_to_contain_text
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
expect(locator).not_to contain_text(expected, ignoreCase: nil, timeout: nil, useInnerText: nil)
|
123
|
+
```
|
124
|
+
|
125
|
+
|
126
|
+
The opposite of [LocatorAssertions#to_contain_text](./locator_assertions#to_contain_text).
|
127
|
+
|
128
|
+
## not_to_have_attribute
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
expect(locator).not_to have_attribute(name, value, timeout: nil)
|
132
|
+
```
|
133
|
+
|
134
|
+
|
135
|
+
The opposite of [LocatorAssertions#to_have_attribute](./locator_assertions#to_have_attribute).
|
136
|
+
|
137
|
+
## not_to_have_class
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
expect(locator).not_to have_class(expected, timeout: nil)
|
141
|
+
```
|
142
|
+
|
143
|
+
|
144
|
+
The opposite of [LocatorAssertions#to_have_class](./locator_assertions#to_have_class).
|
145
|
+
|
146
|
+
## not_to_have_count
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
expect(locator).not_to have_count(count, timeout: nil)
|
150
|
+
```
|
151
|
+
|
152
|
+
|
153
|
+
The opposite of [LocatorAssertions#to_have_count](./locator_assertions#to_have_count).
|
154
|
+
|
155
|
+
## not_to_have_css
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
expect(locator).not_to have_css(name, value, timeout: nil)
|
159
|
+
```
|
160
|
+
|
161
|
+
|
162
|
+
The opposite of [LocatorAssertions#to_have_css](./locator_assertions#to_have_css).
|
163
|
+
|
164
|
+
## not_to_have_id
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
expect(locator).not_to have_id(id, timeout: nil)
|
168
|
+
```
|
169
|
+
|
170
|
+
|
171
|
+
The opposite of [LocatorAssertions#to_have_id](./locator_assertions#to_have_id).
|
172
|
+
|
173
|
+
## not_to_have_js_property
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
expect(locator).not_to have_js_property(name, value, timeout: nil)
|
177
|
+
```
|
178
|
+
|
179
|
+
|
180
|
+
The opposite of [LocatorAssertions#to_have_js_property](./locator_assertions#to_have_js_property).
|
181
|
+
|
182
|
+
## not_to_have_text
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
expect(locator).not_to have_text(expected, ignoreCase: nil, timeout: nil, useInnerText: nil)
|
186
|
+
```
|
187
|
+
|
188
|
+
|
189
|
+
The opposite of [LocatorAssertions#to_have_text](./locator_assertions#to_have_text).
|
190
|
+
|
191
|
+
## not_to_have_value
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
expect(locator).not_to have_value(value, timeout: nil)
|
195
|
+
```
|
196
|
+
|
197
|
+
|
198
|
+
The opposite of [LocatorAssertions#to_have_value](./locator_assertions#to_have_value).
|
199
|
+
|
200
|
+
## not_to_have_values
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
expect(locator).not_to have_values(values, timeout: nil)
|
204
|
+
```
|
205
|
+
|
206
|
+
|
207
|
+
The opposite of [LocatorAssertions#to_have_values](./locator_assertions#to_have_values).
|
208
|
+
|
209
|
+
## to_be_attached
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
expect(locator).to be_attached(attached: nil, timeout: nil)
|
213
|
+
```
|
214
|
+
|
215
|
+
|
216
|
+
Ensures that [Locator](./locator) points to an [attached](https://playwright.dev/python/docs/actionability#attached) DOM node.
|
217
|
+
|
218
|
+
**Usage**
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
page.content = <<~HTML
|
222
|
+
<div id="hidden_status" style="display: none">Pending</div>
|
223
|
+
<button onClick="document.getElementById('hidden_status').innerText='Hidden text'">Click me</button>
|
224
|
+
HTML
|
225
|
+
|
226
|
+
page.get_by_role("button").click
|
227
|
+
expect(page.get_by_text("Hidden text")).to be_attached
|
228
|
+
```
|
229
|
+
|
230
|
+
## to_be_checked
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
expect(locator).to be_checked(checked: nil, timeout: nil)
|
234
|
+
```
|
235
|
+
|
236
|
+
|
237
|
+
Ensures the [Locator](./locator) points to a checked input.
|
238
|
+
|
239
|
+
**Usage**
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
locator = page.get_by_label("Subscribe to newsletter")
|
243
|
+
expect(locator).to be_checked
|
244
|
+
```
|
245
|
+
|
246
|
+
## to_be_disabled
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
expect(locator).to be_disabled(timeout: nil)
|
250
|
+
```
|
251
|
+
|
252
|
+
|
253
|
+
Ensures the [Locator](./locator) points to a disabled element. Element is disabled if it has "disabled" attribute
|
254
|
+
or is disabled via ['aria-disabled'](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-disabled).
|
255
|
+
Note that only native control elements such as HTML `button`, `input`, `select`, `textarea`, `option`, `optgroup`
|
256
|
+
can be disabled by setting "disabled" attribute. "disabled" attribute on other elements is ignored
|
257
|
+
by the browser.
|
258
|
+
|
259
|
+
**Usage**
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
locator = page.locator("button.submit")
|
263
|
+
locator.click
|
264
|
+
expect(locator).to be_disabled
|
265
|
+
```
|
266
|
+
|
267
|
+
## to_be_editable
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
expect(locator).to be_editable(editable: nil, timeout: nil)
|
271
|
+
```
|
272
|
+
|
273
|
+
|
274
|
+
Ensures the [Locator](./locator) points to an editable element.
|
275
|
+
|
276
|
+
**Usage**
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
locator = page.get_by_role("textbox")
|
280
|
+
expect(locator).to be_editable
|
281
|
+
```
|
282
|
+
|
283
|
+
## to_be_empty
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
expect(locator).to be_empty(timeout: nil)
|
287
|
+
```
|
288
|
+
|
289
|
+
|
290
|
+
Ensures the [Locator](./locator) points to an empty editable element or to a DOM node that has no text.
|
291
|
+
|
292
|
+
**Usage**
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
locator = page.locator("div.warning")
|
296
|
+
expect(locator).to be_empty
|
297
|
+
```
|
298
|
+
|
299
|
+
## to_be_enabled
|
300
|
+
|
301
|
+
```ruby
|
302
|
+
expect(locator).to be_enabled(enabled: nil, timeout: nil)
|
303
|
+
```
|
304
|
+
|
305
|
+
|
306
|
+
Ensures the [Locator](./locator) points to an enabled element.
|
307
|
+
|
308
|
+
**Usage**
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
locator = page.locator("button.submit")
|
312
|
+
expect(locator).to be_enabled
|
313
|
+
```
|
314
|
+
|
315
|
+
## to_be_focused
|
316
|
+
|
317
|
+
```ruby
|
318
|
+
expect(locator).to be_focused(timeout: nil)
|
319
|
+
```
|
320
|
+
|
321
|
+
|
322
|
+
Ensures the [Locator](./locator) points to a focused DOM node.
|
323
|
+
|
324
|
+
**Usage**
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
locator = page.get_by_role("textbox")
|
328
|
+
expect(locator).to be_focused
|
329
|
+
```
|
330
|
+
|
331
|
+
## to_be_hidden
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
expect(locator).to be_hidden(timeout: nil)
|
335
|
+
```
|
336
|
+
|
337
|
+
|
338
|
+
Ensures that [Locator](./locator) either does not resolve to any DOM node, or resolves to a [non-visible](https://playwright.dev/python/docs/actionability#visible) one.
|
339
|
+
|
340
|
+
**Usage**
|
341
|
+
|
342
|
+
```ruby
|
343
|
+
locator = page.locator(".my-element")
|
344
|
+
expect(locator).to be_hidden
|
345
|
+
```
|
346
|
+
|
347
|
+
## to_be_in_viewport
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
expect(locator).to be_in_viewport(ratio: nil, timeout: nil)
|
351
|
+
```
|
352
|
+
|
353
|
+
|
354
|
+
Ensures the [Locator](./locator) points to an element that intersects viewport, according to the [intersection observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).
|
355
|
+
|
356
|
+
**Usage**
|
357
|
+
|
358
|
+
```ruby
|
359
|
+
locator = page.get_by_role("button")
|
360
|
+
# Make sure at least some part of element intersects viewport.
|
361
|
+
expect(locator).to be_in_viewport
|
362
|
+
# Make sure element is fully outside of viewport.
|
363
|
+
expect(locator).not_to be_in_viewport
|
364
|
+
# Make sure that at least half of the element intersects viewport.
|
365
|
+
expect(locator).to be_in_viewport(ratio: 0.5)
|
366
|
+
```
|
367
|
+
|
368
|
+
## to_be_visible
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
expect(locator).to be_visible(timeout: nil, visible: nil)
|
372
|
+
```
|
373
|
+
|
374
|
+
|
375
|
+
Ensures that [Locator](./locator) points to an [attached](https://playwright.dev/python/docs/actionability#attached) and [visible](https://playwright.dev/python/docs/actionability#visible) DOM node.
|
376
|
+
|
377
|
+
To check that at least one element from the list is visible, use [Locator#first](./locator#first).
|
378
|
+
|
379
|
+
**Usage**
|
380
|
+
|
381
|
+
```ruby
|
382
|
+
# A specific element is visible.
|
383
|
+
expect(page.get_by_text("Welcome")).to be_visible
|
384
|
+
|
385
|
+
# At least one item in the list is visible.
|
386
|
+
expect(page.get_by_test_id("todo-item").first).to be_visible
|
387
|
+
|
388
|
+
# At least one of the two elements is visible, possibly both.
|
389
|
+
expect(
|
390
|
+
page.get_by_role('button', name: 'Sign in').or(page.get_by_role('button', name: 'Sign up')).first
|
391
|
+
).to be_visible
|
392
|
+
```
|
393
|
+
|
394
|
+
## to_contain_text
|
395
|
+
|
396
|
+
```ruby
|
397
|
+
expect(locator).to contain_text(expected, ignoreCase: nil, timeout: nil, useInnerText: nil)
|
398
|
+
```
|
399
|
+
|
400
|
+
|
401
|
+
Ensures the [Locator](./locator) points to an element that contains the given text. You can use regular expressions for the value as well.
|
402
|
+
|
403
|
+
**Usage**
|
404
|
+
|
405
|
+
```ruby
|
406
|
+
locator = page.locator('.title')
|
407
|
+
expect(locator).to contain_text("substring")
|
408
|
+
expect(locator).to contain_text(/\d messages/)
|
409
|
+
```
|
410
|
+
|
411
|
+
If you pass an array as an expected value, the expectations are:
|
412
|
+
1. Locator resolves to a list of elements.
|
413
|
+
1. Elements from a **subset** of this list contain text from the expected array, respectively.
|
414
|
+
1. The matching subset of elements has the same order as the expected array.
|
415
|
+
1. Each text value from the expected array is matched by some element from the list.
|
416
|
+
|
417
|
+
For example, consider the following list:
|
418
|
+
|
419
|
+
```html
|
420
|
+
<ul>
|
421
|
+
<li>Item Text 1</li>
|
422
|
+
<li>Item Text 2</li>
|
423
|
+
<li>Item Text 3</li>
|
424
|
+
</ul>
|
425
|
+
```
|
426
|
+
|
427
|
+
Let's see how we can use the assertion:
|
428
|
+
|
429
|
+
```ruby
|
430
|
+
# ✓ Contains the right items in the right order
|
431
|
+
expect(page.locator("ul > li")).to contain_text(["Text 1", "Text 3", "Text 4"])
|
432
|
+
|
433
|
+
# ✖ Wrong order
|
434
|
+
expect(page.locator("ul > li")).to contain_text(["Text 3", "Text 2"])
|
435
|
+
|
436
|
+
# ✖ No item contains this text
|
437
|
+
expect(page.locator("ul > li")).to contain_text(["Some 33"])
|
438
|
+
|
439
|
+
# ✖ Locator points to the outer list element, not to the list items
|
440
|
+
expect(page.locator("ul")).to contain_text(["Text 3"])
|
441
|
+
```
|
442
|
+
|
443
|
+
## to_have_attribute
|
444
|
+
|
445
|
+
```ruby
|
446
|
+
expect(locator).to have_attribute(name, value, timeout: nil)
|
447
|
+
```
|
448
|
+
|
449
|
+
|
450
|
+
Ensures the [Locator](./locator) points to an element with given attribute.
|
451
|
+
|
452
|
+
**Usage**
|
453
|
+
|
454
|
+
```ruby
|
455
|
+
locator = page.locator("input")
|
456
|
+
expect(locator).to have_attribute("type", "text")
|
457
|
+
```
|
458
|
+
|
459
|
+
## to_have_class
|
460
|
+
|
461
|
+
```ruby
|
462
|
+
expect(locator).to have_class(expected, timeout: nil)
|
463
|
+
```
|
464
|
+
|
465
|
+
|
466
|
+
Ensures the [Locator](./locator) points to an element with given CSS classes. This needs to be a full match
|
467
|
+
or using a relaxed regular expression.
|
468
|
+
|
469
|
+
**Usage**
|
470
|
+
|
471
|
+
```html
|
472
|
+
<div class='selected row' id='component'></div>
|
473
|
+
```
|
474
|
+
|
475
|
+
```ruby
|
476
|
+
locator = page.locator("#component")
|
477
|
+
expect(locator).to have_class(/selected/)
|
478
|
+
expect(locator).to have_class("selected row")
|
479
|
+
```
|
480
|
+
|
481
|
+
Note that if array is passed as an expected value, entire lists of elements can be asserted:
|
482
|
+
|
483
|
+
```ruby
|
484
|
+
locator = page.locator("list > .component")
|
485
|
+
expect(locator).to have_class(["component", "component selected", "component"])
|
486
|
+
```
|
487
|
+
|
488
|
+
## to_have_count
|
489
|
+
|
490
|
+
```ruby
|
491
|
+
expect(locator).to have_count(count, timeout: nil)
|
492
|
+
```
|
493
|
+
|
494
|
+
|
495
|
+
Ensures the [Locator](./locator) resolves to an exact number of DOM nodes.
|
496
|
+
|
497
|
+
**Usage**
|
498
|
+
|
499
|
+
```ruby
|
500
|
+
locator = page.locator("list > .component")
|
501
|
+
expect(locator).to have_count(3)
|
502
|
+
```
|
503
|
+
|
504
|
+
## to_have_css
|
505
|
+
|
506
|
+
```ruby
|
507
|
+
expect(locator).to have_css(name, value, timeout: nil)
|
508
|
+
```
|
509
|
+
|
510
|
+
|
511
|
+
Ensures the [Locator](./locator) resolves to an element with the given computed CSS style.
|
512
|
+
|
513
|
+
**Usage**
|
514
|
+
|
515
|
+
```ruby
|
516
|
+
locator = page.get_by_role("button")
|
517
|
+
expect(locator).to have_css("display", "flex")
|
518
|
+
```
|
519
|
+
|
520
|
+
## to_have_id
|
521
|
+
|
522
|
+
```ruby
|
523
|
+
expect(locator).to have_id(id, timeout: nil)
|
524
|
+
```
|
525
|
+
|
526
|
+
|
527
|
+
Ensures the [Locator](./locator) points to an element with the given DOM Node ID.
|
528
|
+
|
529
|
+
**Usage**
|
530
|
+
|
531
|
+
```ruby
|
532
|
+
locator = page.get_by_role("textbox")
|
533
|
+
expect(locator).to have_id("lastname")
|
534
|
+
```
|
535
|
+
|
536
|
+
## to_have_js_property
|
537
|
+
|
538
|
+
```ruby
|
539
|
+
expect(locator).to have_js_property(name, value, timeout: nil)
|
540
|
+
```
|
541
|
+
|
542
|
+
|
543
|
+
Ensures the [Locator](./locator) points to an element with given JavaScript property. Note that this property can be
|
544
|
+
of a primitive type as well as a plain serializable JavaScript object.
|
545
|
+
|
546
|
+
**Usage**
|
547
|
+
|
548
|
+
```ruby
|
549
|
+
locator = page.locator(".component")
|
550
|
+
expect(locator).to have_js_property("loaded", true)
|
551
|
+
```
|
552
|
+
|
553
|
+
## to_have_text
|
554
|
+
|
555
|
+
```ruby
|
556
|
+
expect(locator).to have_text(expected, ignoreCase: nil, timeout: nil, useInnerText: nil)
|
557
|
+
```
|
558
|
+
|
559
|
+
|
560
|
+
Ensures the [Locator](./locator) points to an element with the given text. You can use regular expressions for the value as well.
|
561
|
+
|
562
|
+
**Usage**
|
563
|
+
|
564
|
+
```ruby
|
565
|
+
locator = page.locator(".title")
|
566
|
+
expect(locator).to have_text(/Welcome, Test User/)
|
567
|
+
expect(locator).to have_text(/Welcome, .*/)
|
568
|
+
```
|
569
|
+
|
570
|
+
If you pass an array as an expected value, the expectations are:
|
571
|
+
1. Locator resolves to a list of elements.
|
572
|
+
1. The number of elements equals the number of expected values in the array.
|
573
|
+
1. Elements from the list have text matching expected array values, one by one, in order.
|
574
|
+
|
575
|
+
For example, consider the following list:
|
576
|
+
|
577
|
+
```html
|
578
|
+
<ul>
|
579
|
+
<li>Text 1</li>
|
580
|
+
<li>Text 2</li>
|
581
|
+
<li>Text 3</li>
|
582
|
+
</ul>
|
583
|
+
```
|
584
|
+
|
585
|
+
Let's see how we can use the assertion:
|
586
|
+
|
587
|
+
```ruby
|
588
|
+
# ✓ Has the right items in the right order
|
589
|
+
expect(page.locator("ul > li")).to have_text(["Text 1", "Text 2", "Text 3"])
|
590
|
+
|
591
|
+
# ✖ Wrong order
|
592
|
+
expect(page.locator("ul > li")).to have_text(["Text 3", "Text 2", "Text 1"])
|
593
|
+
|
594
|
+
# ✖ Last item does not match
|
595
|
+
expect(page.locator("ul > li")).to have_text(["Text 1", "Text 2", "Text"])
|
596
|
+
|
597
|
+
# ✖ Locator points to the outer list element, not to the list items
|
598
|
+
expect(page.locator("ul")).to have_text(["Text 1", "Text 2", "Text 3"])
|
599
|
+
```
|
600
|
+
|
601
|
+
## to_have_value
|
602
|
+
|
603
|
+
```ruby
|
604
|
+
expect(locator).to have_value(value, timeout: nil)
|
605
|
+
```
|
606
|
+
|
607
|
+
|
608
|
+
Ensures the [Locator](./locator) points to an element with the given input value. You can use regular expressions for the value as well.
|
609
|
+
|
610
|
+
**Usage**
|
611
|
+
|
612
|
+
```ruby
|
613
|
+
locator = page.locator("input[type=number]")
|
614
|
+
expect(locator).to have_value(/^[0-9]$/)
|
615
|
+
```
|
616
|
+
|
617
|
+
## to_have_values
|
618
|
+
|
619
|
+
```ruby
|
620
|
+
expect(locator).to have_values(values, timeout: nil)
|
621
|
+
```
|
622
|
+
|
623
|
+
|
624
|
+
Ensures the [Locator](./locator) points to multi-select/combobox (i.e. a `select` with the `multiple` attribute) and the specified values are selected.
|
625
|
+
|
626
|
+
**Usage**
|
627
|
+
|
628
|
+
For example, given the following element:
|
629
|
+
|
630
|
+
```html
|
631
|
+
<select id="favorite-colors" multiple>
|
632
|
+
<option value="R">Red</option>
|
633
|
+
<option value="G">Green</option>
|
634
|
+
<option value="B">Blue</option>
|
635
|
+
</select>
|
636
|
+
```
|
637
|
+
|
638
|
+
```ruby
|
639
|
+
locator = page.locator("id=favorite-colors")
|
640
|
+
locator.select_option(["R", "G"])
|
641
|
+
expect(locator).to have_values([/R/, /G/])
|
642
|
+
```
|