playwright-ruby-client 1.51.0 → 1.53.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/experimental/android.md +10 -0
  3. data/documentation/docs/api/locator.md +23 -0
  4. data/documentation/docs/api/locator_assertions.md +47 -1
  5. data/documentation/docs/api/page.md +1 -1
  6. data/documentation/docs/api/route.md +2 -0
  7. data/documentation/docs/api/selectors.md +10 -0
  8. data/documentation/docs/api/tracing.md +8 -0
  9. data/documentation/docs/include/api_coverage.md +5 -2
  10. data/lib/playwright/channel.rb +6 -3
  11. data/lib/playwright/channel_owners/android.rb +12 -0
  12. data/lib/playwright/channel_owners/android_device.rb +6 -5
  13. data/lib/playwright/channel_owners/api_request_context.rb +6 -1
  14. data/lib/playwright/channel_owners/browser.rb +37 -6
  15. data/lib/playwright/channel_owners/browser_context.rb +44 -23
  16. data/lib/playwright/channel_owners/browser_type.rb +45 -12
  17. data/lib/playwright/channel_owners/element_handle.rb +22 -17
  18. data/lib/playwright/channel_owners/frame.rb +40 -33
  19. data/lib/playwright/channel_owners/page.rb +19 -8
  20. data/lib/playwright/channel_owners/playwright.rb +10 -4
  21. data/lib/playwright/channel_owners/web_socket.rb +1 -1
  22. data/lib/playwright/connection.rb +3 -0
  23. data/lib/playwright/file_chooser_impl.rb +3 -2
  24. data/lib/playwright/frame_locator_impl.rb +5 -8
  25. data/lib/playwright/javascript/value_parser.rb +54 -2
  26. data/lib/playwright/locator_assertions_impl.rb +95 -32
  27. data/lib/playwright/locator_impl.rb +30 -18
  28. data/lib/playwright/page_assertions_impl.rb +10 -8
  29. data/lib/playwright/selectors_impl.rb +45 -0
  30. data/lib/playwright/test.rb +21 -3
  31. data/lib/playwright/timeout_settings.rb +5 -0
  32. data/lib/playwright/utils.rb +0 -33
  33. data/lib/playwright/version.rb +2 -2
  34. data/lib/playwright_api/android.rb +12 -7
  35. data/lib/playwright_api/android_device.rb +8 -8
  36. data/lib/playwright_api/api_request.rb +1 -0
  37. data/lib/playwright_api/api_request_context.rb +6 -6
  38. data/lib/playwright_api/browser.rb +6 -6
  39. data/lib/playwright_api/browser_context.rb +14 -14
  40. data/lib/playwright_api/browser_type.rb +6 -6
  41. data/lib/playwright_api/cdp_session.rb +6 -6
  42. data/lib/playwright_api/dialog.rb +6 -6
  43. data/lib/playwright_api/element_handle.rb +6 -6
  44. data/lib/playwright_api/frame.rb +6 -6
  45. data/lib/playwright_api/js_handle.rb +6 -6
  46. data/lib/playwright_api/locator.rb +28 -2
  47. data/lib/playwright_api/locator_assertions.rb +47 -3
  48. data/lib/playwright_api/page.rb +15 -10
  49. data/lib/playwright_api/playwright.rb +6 -6
  50. data/lib/playwright_api/request.rb +6 -6
  51. data/lib/playwright_api/response.rb +6 -6
  52. data/lib/playwright_api/route.rb +8 -6
  53. data/lib/playwright_api/selectors.rb +1 -28
  54. data/lib/playwright_api/tracing.rb +14 -6
  55. data/lib/playwright_api/web_socket.rb +6 -6
  56. data/lib/playwright_api/worker.rb +6 -6
  57. data/sig/playwright.rbs +7 -0
  58. metadata +5 -5
  59. data/lib/playwright/channel_owners/selectors.rb +0 -26
@@ -1,4 +1,5 @@
1
- require 'date'
1
+ require 'base64'
2
+ require 'time'
2
3
 
3
4
  module Playwright
4
5
  module JavaScript
@@ -45,7 +46,7 @@ module Playwright
45
46
  end
46
47
 
47
48
  if hash.key?('d')
48
- return DateTime.parse(hash['d'])
49
+ return Time.parse(hash['d'])
49
50
  end
50
51
 
51
52
  if hash.key?('u')
@@ -105,6 +106,57 @@ module Playwright
105
106
  return @handles[hash['h']]
106
107
  end
107
108
 
109
+ if hash.key?('ta')
110
+ encoded_bytes = hash['ta']['b']
111
+ decoded_bytes = Base64.strict_decode64(encoded_bytes)
112
+ array_type = hash['ta']['k']
113
+
114
+ if array_type == 'i8'
115
+ word_size = 1
116
+ unpack_format = 'c*' # signed char
117
+ elsif array_type == 'ui8' || array_type == 'ui8c'
118
+ word_size = 1
119
+ unpack_format = 'C*' # unsigned char
120
+ elsif array_type == 'i16'
121
+ word_size = 2
122
+ unpack_format = 's<*' # signed short, little-endian
123
+ elsif array_type == 'ui16'
124
+ word_size = 2
125
+ unpack_format = 'S<*' # unsigned short, little-endian
126
+ elsif array_type == 'i32'
127
+ word_size = 4
128
+ unpack_format = 'l<*' # signed long, little-endian
129
+ elsif array_type == 'ui32'
130
+ word_size = 4
131
+ unpack_format = 'L<*' # unsigned long, little-endian
132
+ elsif array_type == 'f32'
133
+ word_size = 4
134
+ unpack_format = 'e*' # float, little-endian
135
+ elsif array_type == 'f64'
136
+ word_size = 8
137
+ unpack_format = 'E*' # double, little-endian
138
+ elsif array_type == 'bi64'
139
+ word_size = 8
140
+ unpack_format = 'q<*' # signed long long, little-endian
141
+ elsif array_type == 'bui64'
142
+ word_size = 8
143
+ unpack_format = 'Q<*' # unsigned long long, little-endian
144
+ else
145
+ raise ArgumentError, "Unsupported array type: #{array_type}"
146
+ end
147
+
148
+ byte_len = decoded_bytes.bytesize
149
+ if byte_len.zero?
150
+ return []
151
+ end
152
+
153
+ if byte_len % word_size != 0
154
+ raise ArgumentError, "Decoded bytes length #{byte_len} is not a multiple of word size #{word_size} for type #{array_type}"
155
+ end
156
+
157
+ return decoded_bytes.unpack(unpack_format)
158
+ end
159
+
108
160
  raise ArgumentError.new("Unexpected value: #{hash}")
109
161
  end
110
162
  end
@@ -11,20 +11,20 @@ module Playwright
11
11
  end
12
12
  end
13
13
 
14
- def initialize(locator, timeout, is_not, message)
14
+ def initialize(locator, default_expect_timeout, is_not, message)
15
15
  @locator = locator
16
- @timeout = timeout
16
+ @default_expect_timeout = default_expect_timeout
17
17
  @is_not = is_not
18
18
  @custom_message = message
19
19
  end
20
20
 
21
- private def expect_impl(expression, expect_options, expected, message)
22
- expect_options[:timeout] ||= 5000
21
+ private def expect_impl(expression, expect_options, expected, message, title)
22
+ expect_options[:timeout] ||= @default_expect_timeout
23
23
  expect_options[:isNot] = @is_not
24
24
  message.gsub!("expected to", "not expected to") if @is_not
25
25
  expect_options.delete(:useInnerText) if expect_options.key?(:useInnerText) && expect_options[:useInnerText].nil?
26
26
 
27
- result = @locator.expect(expression, expect_options)
27
+ result = @locator.expect(expression, expect_options, title)
28
28
 
29
29
  if result["matches"] == @is_not
30
30
  actual = result["received"]
@@ -59,7 +59,7 @@ module Playwright
59
59
  private def _not # "not" is reserved in Ruby
60
60
  LocatorAssertionsImpl.new(
61
61
  @locator,
62
- @timeout,
62
+ @default_expect_timeout,
63
63
  !@is_not,
64
64
  @message
65
65
  )
@@ -124,7 +124,8 @@ module Playwright
124
124
  timeout: timeout,
125
125
  },
126
126
  expected,
127
- "Locator expected to contain text"
127
+ "Locator expected to contain text",
128
+ 'Expect "to_contain_text"',
128
129
  )
129
130
  else
130
131
  expected_text = to_expected_text_values(
@@ -142,7 +143,8 @@ module Playwright
142
143
  timeout: timeout,
143
144
  },
144
145
  expected,
145
- "Locator expected to contain text"
146
+ "Locator expected to contain text",
147
+ 'Expect "to_contain_text"',
146
148
  )
147
149
  end
148
150
  end
@@ -157,7 +159,8 @@ module Playwright
157
159
  timeout: timeout,
158
160
  },
159
161
  name,
160
- "Locator expected to have accessible name"
162
+ "Locator expected to have accessible name",
163
+ 'Expect "to_have_accessible_name"',
161
164
  )
162
165
  end
163
166
  _define_negation :to_have_accessible_name
@@ -171,7 +174,8 @@ module Playwright
171
174
  timeout: timeout,
172
175
  },
173
176
  name,
174
- "Locator expected to have accessible description"
177
+ "Locator expected to have accessible description",
178
+ 'Expect "to_have_accessible_description"',
175
179
  )
176
180
  end
177
181
  _define_negation :to_have_accessible_description
@@ -185,7 +189,8 @@ module Playwright
185
189
  timeout: timeout,
186
190
  },
187
191
  errorMessage,
188
- "Locator expected to have accessible error message"
192
+ "Locator expected to have accessible error message",
193
+ 'Expect "to_have_accessible_error_message"',
189
194
  )
190
195
  end
191
196
  _define_negation :to_have_accessible_error_message
@@ -200,7 +205,8 @@ module Playwright
200
205
  timeout: timeout,
201
206
  },
202
207
  value,
203
- "Locator expected to have attribute"
208
+ "Locator expected to have attribute",
209
+ 'Expect "to_have_attribute"',
204
210
  )
205
211
  end
206
212
  _define_negation :to_have_attribute
@@ -215,7 +221,8 @@ module Playwright
215
221
  timeout: timeout,
216
222
  },
217
223
  expected,
218
- "Locator expected to have class"
224
+ "Locator expected to have class",
225
+ 'Expect "to_have_class"',
219
226
  )
220
227
  else
221
228
  expected_text = to_expected_text_values([expected])
@@ -226,12 +233,48 @@ module Playwright
226
233
  timeout: timeout,
227
234
  },
228
235
  expected,
229
- "Locator expected to have class"
236
+ "Locator expected to have class",
237
+ 'Expect "to_have_class"',
230
238
  )
231
239
  end
232
240
  end
233
241
  _define_negation :to_have_class
234
242
 
243
+ def to_contain_class(expected, timeout: nil)
244
+ if expected.is_a?(Enumerable)
245
+ if expected.any? { |e| e.is_a?(Regexp) }
246
+ raise ArgumentError.new('"expected" argument in toContainClass cannot contain RegExp values')
247
+ end
248
+ expected_text = to_expected_text_values(expected)
249
+ expect_impl(
250
+ "to.contain.class.array",
251
+ {
252
+ expectedText: expected_text,
253
+ timeout: timeout,
254
+ },
255
+ expected,
256
+ "Locator expected to contain class names",
257
+ 'Expect "to_contain_class"',
258
+ )
259
+ else # Single string
260
+ if expected.is_a?(Regexp)
261
+ raise ArgumentError.new('"expected" argument in toContainClass cannot be a RegExp value')
262
+ end
263
+ expected_text = to_expected_text_values([expected])
264
+ expect_impl(
265
+ "to.contain.class",
266
+ {
267
+ expectedText: expected_text,
268
+ timeout: timeout,
269
+ },
270
+ expected,
271
+ "Locator expected to contain class",
272
+ 'Expect "to_contain_class"',
273
+ )
274
+ end
275
+ end
276
+ _define_negation :to_contain_class
277
+
235
278
  def to_have_count(count, timeout: nil)
236
279
  expect_impl(
237
280
  "to.have.count",
@@ -240,7 +283,8 @@ module Playwright
240
283
  timeout: timeout,
241
284
  },
242
285
  count,
243
- "Locator expected to have count"
286
+ "Locator expected to have count",
287
+ 'Expect "to_have_count"',
244
288
  )
245
289
  end
246
290
  _define_negation :to_have_count
@@ -255,7 +299,8 @@ module Playwright
255
299
  timeout: timeout,
256
300
  },
257
301
  value,
258
- "Locator expected to have CSS"
302
+ "Locator expected to have CSS",
303
+ 'Expect "to_have_css"',
259
304
  )
260
305
  end
261
306
  _define_negation :to_have_css
@@ -269,7 +314,8 @@ module Playwright
269
314
  timeout: timeout,
270
315
  },
271
316
  id,
272
- "Locator expected to have ID"
317
+ "Locator expected to have ID",
318
+ 'Expect "to_have_id"',
273
319
  )
274
320
  end
275
321
  _define_negation :to_have_id
@@ -283,7 +329,8 @@ module Playwright
283
329
  timeout: timeout,
284
330
  },
285
331
  value,
286
- "Locator expected to have JS Property"
332
+ "Locator expected to have JS Property",
333
+ 'Expect "to_have_js_property"',
287
334
  )
288
335
  end
289
336
  _define_negation :to_have_js_property
@@ -302,6 +349,7 @@ module Playwright
302
349
  },
303
350
  role,
304
351
  "Locator expected to have accessible role",
352
+ 'Expect "to_have_role"',
305
353
  )
306
354
  end
307
355
  _define_negation :to_have_role
@@ -316,7 +364,8 @@ module Playwright
316
364
  timeout: timeout,
317
365
  },
318
366
  value,
319
- "Locator expected to have Value"
367
+ "Locator expected to have Value",
368
+ 'Expect "to_have_value"',
320
369
  )
321
370
  end
322
371
  _define_negation :to_have_value
@@ -331,7 +380,8 @@ module Playwright
331
380
  timeout: timeout,
332
381
  },
333
382
  values,
334
- "Locator expected to have Values"
383
+ "Locator expected to have Values",
384
+ 'Expect "to_have_values"',
335
385
  )
336
386
  end
337
387
  _define_negation :to_have_values
@@ -352,7 +402,8 @@ module Playwright
352
402
  timeout: timeout,
353
403
  },
354
404
  expected,
355
- "Locator expected to have text"
405
+ "Locator expected to have text",
406
+ 'Expect "to_have_text"',
356
407
  )
357
408
  else
358
409
  expected_text = to_expected_text_values(
@@ -369,7 +420,8 @@ module Playwright
369
420
  timeout: timeout,
370
421
  },
371
422
  expected,
372
- "Locator expected to have text"
423
+ "Locator expected to have text",
424
+ 'Expect "to_have_text"',
373
425
  )
374
426
  end
375
427
  end
@@ -384,6 +436,7 @@ module Playwright
384
436
  },
385
437
  expected,
386
438
  'Locator expected to match Aria snapshot',
439
+ 'Expect "to_match_aria_snapshot"',
387
440
  )
388
441
  end
389
442
  _define_negation :to_match_aria_snapshot
@@ -393,7 +446,8 @@ module Playwright
393
446
  (attached || attached.nil?) ? "to.be.attached" : "to.be.detached",
394
447
  { timeout: timeout },
395
448
  nil,
396
- "Locator expected to be attached"
449
+ "Locator expected to be attached",
450
+ 'Expect "to_be_attached"',
397
451
  )
398
452
  end
399
453
  _define_negation :to_be_attached
@@ -416,7 +470,8 @@ module Playwright
416
470
  "to.be.checked",
417
471
  { timeout: timeout, expectedValue: expected_value },
418
472
  nil,
419
- "Locator expected to be checked"
473
+ "Locator expected to be checked",
474
+ 'Expect "to_be_checked"',
420
475
  )
421
476
  end
422
477
  _define_negation :to_be_checked
@@ -426,7 +481,8 @@ module Playwright
426
481
  "to.be.disabled",
427
482
  { timeout: timeout },
428
483
  nil,
429
- "Locator expected to be disabled"
484
+ "Locator expected to be disabled",
485
+ 'Expect "to_be_disabled"',
430
486
  )
431
487
  end
432
488
  _define_negation :to_be_disabled
@@ -436,7 +492,8 @@ module Playwright
436
492
  (editable || editable.nil?) ? "to.be.editable" : "to.be.readonly",
437
493
  { timeout: timeout },
438
494
  nil,
439
- "Locator expected to be editable"
495
+ "Locator expected to be editable",
496
+ 'Expect "to_be_editable"',
440
497
  )
441
498
  end
442
499
  _define_negation :to_be_editable
@@ -446,7 +503,8 @@ module Playwright
446
503
  "to.be.empty",
447
504
  { timeout: timeout },
448
505
  nil,
449
- "Locator expected to be empty"
506
+ "Locator expected to be empty",
507
+ 'Expect "to_be_empty"',
450
508
  )
451
509
  end
452
510
  _define_negation :to_be_empty
@@ -456,7 +514,8 @@ module Playwright
456
514
  (enabled || enabled.nil?) ? "to.be.enabled" : "to.be.disabled",
457
515
  { timeout: timeout },
458
516
  nil,
459
- "Locator expected to be enabled"
517
+ "Locator expected to be enabled",
518
+ 'Expect "to_be_enabled"',
460
519
  )
461
520
  end
462
521
  _define_negation :to_be_enabled
@@ -466,7 +525,8 @@ module Playwright
466
525
  "to.be.hidden",
467
526
  { timeout: timeout },
468
527
  nil,
469
- "Locator expected to be hidden"
528
+ "Locator expected to be hidden",
529
+ 'Expect "to_be_hidden"',
470
530
  )
471
531
  end
472
532
  _define_negation :to_be_hidden
@@ -476,7 +536,8 @@ module Playwright
476
536
  (visible || visible.nil?) ? "to.be.visible" : "to.be.hidden",
477
537
  { timeout: timeout },
478
538
  nil,
479
- "Locator expected to be visible"
539
+ "Locator expected to be visible",
540
+ 'Expect "to_be_visible"',
480
541
  )
481
542
  end
482
543
  _define_negation :to_be_visible
@@ -486,7 +547,8 @@ module Playwright
486
547
  "to.be.focused",
487
548
  { timeout: timeout },
488
549
  nil,
489
- "Locator expected to be focused"
550
+ "Locator expected to be focused",
551
+ 'Expect "to_be_focused"',
490
552
  )
491
553
  end
492
554
  _define_negation :to_be_focused
@@ -496,7 +558,8 @@ module Playwright
496
558
  "to.be.in.viewport",
497
559
  { timeout: timeout, expectedNumber: ratio }.compact,
498
560
  nil,
499
- "Locator expected to be in viewport"
561
+ "Locator expected to be in viewport",
562
+ 'Expect "to_be_in_viewport"',
500
563
  )
501
564
  end
502
565
  _define_negation :to_be_in_viewport
@@ -5,9 +5,8 @@ module Playwright
5
5
  define_api_implementation :LocatorImpl do
6
6
  include LocatorUtils
7
7
 
8
- def initialize(frame:, timeout_settings:, selector:, has: nil, hasNot: nil, hasNotText: nil, hasText: nil, visible: nil)
8
+ def initialize(frame:, selector:, has: nil, hasNot: nil, hasNotText: nil, hasText: nil, visible: nil)
9
9
  @frame = frame
10
- @timeout_settings = timeout_settings
11
10
  selector_scopes = [selector]
12
11
 
13
12
  if hasText
@@ -40,7 +39,11 @@ module Playwright
40
39
  end
41
40
 
42
41
  def to_s
43
- "Locator@#{@selector}"
42
+ if @description
43
+ "Locator@#{@selector} (#{@description})"
44
+ else
45
+ "Locator@#{@selector}"
46
+ end
44
47
  end
45
48
 
46
49
  private def to_protocol
@@ -64,8 +67,12 @@ module Playwright
64
67
  @selector.to_json
65
68
  end
66
69
 
70
+ private def _timeout(timeout)
71
+ @frame.send(:_timeout, timeout)
72
+ end
73
+
67
74
  private def with_element(timeout: nil, &block)
68
- timeout_or_default = @timeout_settings.timeout(timeout)
75
+ timeout_or_default = _timeout(timeout)
69
76
  start_time = Time.now
70
77
 
71
78
  handle = @frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout_or_default)
@@ -213,7 +220,6 @@ module Playwright
213
220
  hasText: nil)
214
221
  LocatorImpl.new(
215
222
  frame: @frame,
216
- timeout_settings: @timeout_settings,
217
223
  selector: "#{@selector} >> #{selector}",
218
224
  has: has,
219
225
  hasNot: hasNot,
@@ -224,7 +230,6 @@ module Playwright
224
230
  def frame_locator(selector)
225
231
  FrameLocatorImpl.new(
226
232
  frame: @frame,
227
- timeout_settings: @timeout_settings,
228
233
  frame_selector: "#{@selector} >> #{selector}",
229
234
  )
230
235
  end
@@ -240,15 +245,20 @@ module Playwright
240
245
  def content_frame
241
246
  FrameLocatorImpl.new(
242
247
  frame: @frame,
243
- timeout_settings: @timeout_settings,
244
248
  frame_selector: @selector,
245
249
  )
246
250
  end
247
251
 
252
+ def describe(description)
253
+ LocatorImpl.new(
254
+ frame: @frame,
255
+ selector: "#{@selector} >> internal:describe=#{description.to_json}",
256
+ )
257
+ end
258
+
248
259
  def filter(has: nil, hasNot: nil, hasNotText: nil, hasText: nil, visible: nil)
249
260
  LocatorImpl.new(
250
261
  frame: @frame,
251
- timeout_settings: @timeout_settings,
252
262
  selector: @selector,
253
263
  has: has,
254
264
  hasNot: hasNot,
@@ -261,7 +271,6 @@ module Playwright
261
271
  def first
262
272
  LocatorImpl.new(
263
273
  frame: @frame,
264
- timeout_settings: @timeout_settings,
265
274
  selector: "#{@selector} >> nth=0",
266
275
  )
267
276
  end
@@ -269,7 +278,6 @@ module Playwright
269
278
  def last
270
279
  LocatorImpl.new(
271
280
  frame: @frame,
272
- timeout_settings: @timeout_settings,
273
281
  selector: "#{@selector} >> nth=-1",
274
282
  )
275
283
  end
@@ -277,7 +285,6 @@ module Playwright
277
285
  def nth(index)
278
286
  LocatorImpl.new(
279
287
  frame: @frame,
280
- timeout_settings: @timeout_settings,
281
288
  selector: "#{@selector} >> nth=#{index}",
282
289
  )
283
290
  end
@@ -288,7 +295,6 @@ module Playwright
288
295
  end
289
296
  LocatorImpl.new(
290
297
  frame: @frame,
291
- timeout_settings: @timeout_settings,
292
298
  selector: "#{@selector} >> internal:and=#{locator.send(:selector_json)}",
293
299
  )
294
300
  end
@@ -299,7 +305,6 @@ module Playwright
299
305
  end
300
306
  LocatorImpl.new(
301
307
  frame: @frame,
302
- timeout_settings: @timeout_settings,
303
308
  selector: "#{@selector} >> internal:or=#{locator.send(:selector_json)}",
304
309
  )
305
310
  end
@@ -312,7 +317,7 @@ module Playwright
312
317
  params = {
313
318
  selector: @selector,
314
319
  strict: true,
315
- timeout: timeout,
320
+ timeout: _timeout(timeout),
316
321
  }.compact
317
322
  @frame.channel.send_message_to_server('blur', params)
318
323
  end
@@ -329,6 +334,12 @@ module Playwright
329
334
  @frame.get_attribute(@selector, name, strict: true, timeout: timeout)
330
335
  end
331
336
 
337
+ def generate_locator_string
338
+ with_element(timeout: nil) do |handle, _|
339
+ handle.channel.send_message_to_server('generateLocatorString')
340
+ end
341
+ end
342
+
332
343
  def hover(
333
344
  force: nil,
334
345
  modifiers: nil,
@@ -400,7 +411,7 @@ module Playwright
400
411
  def aria_snapshot(timeout: nil)
401
412
  @frame.channel.send_message_to_server('ariaSnapshot', {
402
413
  selector: @selector,
403
- timeout: timeout,
414
+ timeout: _timeout(timeout),
404
415
  }.compact)
405
416
  end
406
417
 
@@ -508,7 +519,7 @@ module Playwright
508
519
  @frame.highlight(@selector)
509
520
  end
510
521
 
511
- def expect(expression, options)
522
+ def expect(expression, options, title)
512
523
  if options.key?(:expectedValue)
513
524
  options[:expectedValue] = JavaScript::ValueSerializer
514
525
  .new(options[:expectedValue])
@@ -516,8 +527,9 @@ module Playwright
516
527
  end
517
528
 
518
529
  result = @frame.channel.send_message_to_server_result(
519
- "expect",
520
- {
530
+ title, # title
531
+ "expect", # method
532
+ { # params
521
533
  selector: @selector,
522
534
  expression: expression,
523
535
  **options,
@@ -11,21 +11,21 @@ module Playwright
11
11
  end
12
12
  end
13
13
 
14
- def initialize(page, timeout, is_not, message)
14
+ def initialize(page, default_expect_timeout, is_not, message)
15
15
  @page = PlaywrightApi.unwrap(page)
16
16
  @locator = @page.locator(":root")
17
- @timeout = timeout
17
+ @default_expect_timeout = default_expect_timeout
18
18
  @is_not = is_not
19
19
  @custom_message = message
20
20
  end
21
21
 
22
- private def expect_impl(expression, expect_options, expected, message)
23
- expect_options[:timeout] ||= 5000
22
+ private def expect_impl(expression, expect_options, expected, message, title)
23
+ expect_options[:timeout] ||= @default_expect_timeout
24
24
  expect_options[:isNot] = @is_not
25
25
  message.gsub!("expected to", "not expected to") if @is_not
26
26
  expect_options.delete(:useInnerText) if expect_options.key?(:useInnerText) && expect_options[:useInnerText].nil?
27
27
 
28
- result = @locator.expect(expression, expect_options)
28
+ result = @locator.expect(expression, expect_options, title)
29
29
 
30
30
  if result["matches"] == @is_not
31
31
  actual = result["received"]
@@ -60,7 +60,7 @@ module Playwright
60
60
  private def _not # "not" is reserved in Ruby
61
61
  PageAssertionsImpl.new(
62
62
  @page,
63
- @timeout,
63
+ @default_expect_timeout,
64
64
  !@is_not,
65
65
  @message
66
66
  )
@@ -117,7 +117,8 @@ module Playwright
117
117
  timeout: timeout,
118
118
  },
119
119
  title_or_regex,
120
- "Page title expected to be"
120
+ "Page title expected to be",
121
+ 'Expect "to_have_title"',
121
122
  )
122
123
  end
123
124
  _define_negation :to_have_title
@@ -141,7 +142,8 @@ module Playwright
141
142
  timeout: timeout,
142
143
  },
143
144
  expected,
144
- "Page URL expected to be"
145
+ "Page URL expected to be",
146
+ 'Expect "to_have_url"',
145
147
  )
146
148
  end
147
149
  _define_negation :to_have_url
@@ -0,0 +1,45 @@
1
+ module Playwright
2
+ # https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_selectors.py
3
+ define_api_implementation :SelectorsImpl do
4
+ def initialize
5
+ @selector_engines = []
6
+ @contexts_for_selectors = Set.new
7
+ end
8
+
9
+ def register(name, contentScript: nil, path: nil, script: nil)
10
+ source =
11
+ if path
12
+ File.read(path)
13
+ elsif script
14
+ script
15
+ else
16
+ raise ArgumentError.new('Either path or script parameter must be specified')
17
+ end
18
+ selector_engine = { name: name, source: source }
19
+ if contentScript
20
+ selector_engine[:contentScript] = true
21
+ end
22
+ @contexts_for_selectors.each do |context|
23
+ context.send(:register_selector_engine, selector_engine)
24
+ end
25
+ @selector_engines << selector_engine
26
+
27
+ nil
28
+ end
29
+
30
+ def set_test_id_attribute(attribute_name)
31
+ @test_id_attribute_name = attribute_name
32
+ ::Playwright::LocatorUtils.instance_variable_set(:@test_id_attribute_name, attribute_name)
33
+ end
34
+
35
+ private def update_with_selector_options(options)
36
+ options[:selectorEngines] = @selector_engines unless @selector_engines.empty?
37
+ options[:testIdAttributeName] = @test_id_attribute_name if @test_id_attribute_name
38
+ options
39
+ end
40
+
41
+ private def contexts_for_selectors
42
+ @contexts_for_selectors
43
+ end
44
+ end
45
+ end