playwright-ruby-client 1.44.0 → 1.45.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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request_context.md +1 -1
  3. data/documentation/docs/api/browser_context.md +5 -23
  4. data/documentation/docs/api/clock.md +142 -0
  5. data/documentation/docs/api/console_message.md +1 -1
  6. data/documentation/docs/api/element_handle.md +3 -0
  7. data/documentation/docs/api/locator.md +6 -0
  8. data/documentation/docs/api/locator_assertions.md +1 -1
  9. data/documentation/docs/api/mouse.md +1 -1
  10. data/documentation/docs/api/page.md +6 -21
  11. data/documentation/docs/api/page_assertions.md +1 -1
  12. data/documentation/docs/include/api_coverage.md +12 -0
  13. data/lib/playwright/channel_owners/api_request_context.rb +5 -1
  14. data/lib/playwright/channel_owners/browser_context.rb +62 -10
  15. data/lib/playwright/channel_owners/page.rb +4 -1
  16. data/lib/playwright/clock_impl.rb +65 -0
  17. data/lib/playwright/input_files.rb +64 -23
  18. data/lib/playwright/version.rb +2 -2
  19. data/lib/playwright_api/api_request_context.rb +2 -2
  20. data/lib/playwright_api/browser.rb +2 -2
  21. data/lib/playwright_api/browser_context.rb +6 -16
  22. data/lib/playwright_api/clock.rb +109 -0
  23. data/lib/playwright_api/console_message.rb +1 -1
  24. data/lib/playwright_api/element_handle.rb +3 -0
  25. data/lib/playwright_api/locator.rb +6 -0
  26. data/lib/playwright_api/locator_assertions.rb +2 -2
  27. data/lib/playwright_api/mouse.rb +1 -1
  28. data/lib/playwright_api/page.rb +8 -17
  29. data/lib/playwright_api/page_assertions.rb +2 -2
  30. data/lib/playwright_api/playwright.rb +4 -4
  31. data/lib/playwright_api/worker.rb +4 -4
  32. data/sig/playwright.rbs +17 -3
  33. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c83d71803d132d79217392a22bcbad5de47673f738badf76692ff178e4ddd27
4
- data.tar.gz: 4d25cd84f28d6028f6335b89e4c0324847b3077004e6b21ffb6ed9740cd6ec91
3
+ metadata.gz: 61d1fe5862b1d039cee887b00ac4f561c4d1158d21e582262738bcabe6c5614b
4
+ data.tar.gz: 5041a590c2d79d0b6885b140be6ef581e7d50f52ca44cb7b975999cb70c4eacb
5
5
  SHA512:
6
- metadata.gz: 899c0d792c8021c4560240d9b61ca57b300519f5b2786f58406d65fcb44eb70301d474217c85ec710036c3eeff3119388bbe7255d5f3e6bdbe3debcc0ef425a0
7
- data.tar.gz: 0ca7408e7e43818d7afb4660fb6c8df219eeb386f244c9cde5895cad7fa2c3f9ef26d90f99b86c7c937071cb7c66be6db631ecd883186c43064be6501e793fe6
6
+ metadata.gz: c4bed1453a41a06716fa4df121cdbbec291bd9a0338993c90a2961745fdebb0c3ba09a160179a4b649b8342adbd83f95193639764ac75600cf0dc7be11ff833b
7
+ data.tar.gz: f2ed6829ad907d3a9862ba0be498348e834c46fa7ab352b50da81ef29d68ce6a2ecac7f6e003b20a58abae6d69e14a2391d7825326ad17c614032f118b7a8410
@@ -81,7 +81,7 @@ context cookies from the response. The method will automatically follow redirect
81
81
  ## dispose
82
82
 
83
83
  ```
84
- def dispose
84
+ def dispose(reason: nil)
85
85
  ```
86
86
 
87
87
 
@@ -185,29 +185,6 @@ HTML
185
185
  page.get_by_role("button").click
186
186
  ```
187
187
 
188
- An example of passing an element handle:
189
-
190
- ```ruby
191
- def print_text(source, element)
192
- element.text_content
193
- end
194
-
195
- browser_context.expose_binding("clicked", method(:print_text), handle: true)
196
- page = browser_context.new_page
197
-
198
- page.content = <<~HTML
199
- <script>
200
- document.addEventListener('click', async (event) => {
201
- alert(await window.clicked(event.target));
202
- })
203
- </script>
204
- <div>Click me</div>
205
- <div>Or click me</div>
206
- HTML
207
-
208
- page.locator('div').first.click
209
- ```
210
-
211
188
  ## expose_function
212
189
 
213
190
  ```
@@ -510,6 +487,11 @@ Performs action and waits for a new [Page](./page) to be created in the context.
510
487
  [Page](./page) value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
511
488
  Will throw an error if the context closes before new [Page](./page) is created.
512
489
 
490
+ ## clock
491
+
492
+
493
+ Playwright has ability to mock clock and passage of time.
494
+
513
495
  ## request
514
496
 
515
497
 
@@ -0,0 +1,142 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # Clock
6
+
7
+
8
+ Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Learn more about [clock emulation](https://playwright.dev/python/docs/clock).
9
+
10
+ Note that clock is installed for the entire [BrowserContext](./browser_context), so the time
11
+ in all the pages and iframes is controlled by the same clock.
12
+
13
+ ## fast_forward
14
+
15
+ ```
16
+ def fast_forward(ticks)
17
+ ```
18
+
19
+
20
+ Advance the clock by jumping forward in time. Only fires due timers at most once. This is equivalent to user closing the laptop lid for a while and
21
+ reopening it later, after given time.
22
+
23
+ **Usage**
24
+
25
+ ```ruby
26
+ page.clock.fast_forward(1000)
27
+ page.clock.fast_forward("30:00")
28
+ ```
29
+
30
+ ## install
31
+
32
+ ```
33
+ def install(time: nil)
34
+ ```
35
+
36
+
37
+ Install fake implementations for the following time-related functions:
38
+ - `Date`
39
+ - `setTimeout`
40
+ - `clearTimeout`
41
+ - `setInterval`
42
+ - `clearInterval`
43
+ - `requestAnimationFrame`
44
+ - `cancelAnimationFrame`
45
+ - `requestIdleCallback`
46
+ - `cancelIdleCallback`
47
+ - `performance`
48
+
49
+ Fake timers are used to manually control the flow of time in tests. They allow you to advance time, fire timers, and control the behavior of time-dependent functions. See [Clock#run_for](./clock#run_for) and [Clock#fast_forward](./clock#fast_forward) for more information.
50
+
51
+ ## run_for
52
+
53
+ ```
54
+ def run_for(ticks)
55
+ ```
56
+
57
+
58
+ Advance the clock, firing all the time-related callbacks.
59
+
60
+ **Usage**
61
+
62
+ ```ruby
63
+ page.clock.run_for(1000)
64
+ page.clock.run_for("30:00")
65
+ ```
66
+
67
+ ## pause_at
68
+
69
+ ```
70
+ def pause_at(time)
71
+ ```
72
+
73
+
74
+ Advance the clock by jumping forward in time and pause the time. Once this method is called, no timers
75
+ are fired unless [Clock#run_for](./clock#run_for), [Clock#fast_forward](./clock#fast_forward), [Clock#pause_at](./clock#pause_at) or [Clock#resume](./clock#resume) is called.
76
+
77
+ Only fires due timers at most once.
78
+ This is equivalent to user closing the laptop lid for a while and reopening it at the specified time and
79
+ pausing.
80
+
81
+ **Usage**
82
+
83
+ ```ruby
84
+ page.clock.pause_at(Time.parse("2020-02-02"))
85
+ page.clock.pause_at("2020-02-02")
86
+ ```
87
+
88
+ ## resume
89
+
90
+ ```
91
+ def resume
92
+ ```
93
+
94
+
95
+ Resumes timers. Once this method is called, time resumes flowing, timers are fired as usual.
96
+
97
+ ## set_fixed_time
98
+
99
+ ```
100
+ def set_fixed_time(time)
101
+ ```
102
+ alias: `fixed_time=`
103
+
104
+
105
+ Makes `Date.now` and `new Date()` return fixed fake time at all times,
106
+ keeps all the timers running.
107
+
108
+ **Usage**
109
+
110
+ ```ruby
111
+ page.clock.set_fixed_time(Time.now)
112
+ page.clock.set_fixed_time(Time.parse("2020-02-02"))
113
+ page.clock.set_fixed_time("2020-02-02")
114
+
115
+ # or we can use the alias
116
+ page.clock.fixed_time = Time.now
117
+ page.clock.fixed_time = Time.parse("2020-02-02")
118
+ page.clock.fixed_time = "2020-02-02"
119
+ ```
120
+
121
+ ## set_system_time
122
+
123
+ ```
124
+ def set_system_time(time)
125
+ ```
126
+ alias: `system_time=`
127
+
128
+
129
+ Sets current system time but does not trigger any timers.
130
+
131
+ **Usage**
132
+
133
+ ```ruby
134
+ page.clock.set_system_time(Time.now)
135
+ page.clock.set_system_time(Time.parse("2020-02-02"))
136
+ page.clock.set_system_time("2020-02-02")
137
+
138
+ # or we can use the alias
139
+ page.clock.system_time = Time.now
140
+ page.clock.system_time = Time.parse("2020-02-02")
141
+ page.clock.system_time = "2020-02-02"
142
+ ```
@@ -6,7 +6,7 @@ sidebar_position: 10
6
6
 
7
7
 
8
8
  [ConsoleMessage](./console_message) objects are dispatched by page via the [`event: Page.console`] event.
9
- For each console messages logged in the page there will be corresponding event in the Playwright
9
+ For each console message logged in the page there will be corresponding event in the Playwright
10
10
  context.
11
11
 
12
12
  ```ruby
@@ -485,6 +485,8 @@ completely visible as defined by
485
485
  Throws when `elementHandle` does not point to an element
486
486
  [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
487
487
 
488
+ See [scrolling](https://playwright.dev/python/docs/input#scrolling) for alternative ways to scroll.
489
+
488
490
  ## select_option
489
491
 
490
492
  ```
@@ -566,6 +568,7 @@ alias: `input_files=`
566
568
 
567
569
  Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
568
570
  are resolved relative to the current working directory. For empty array, clears the selected files.
571
+ For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
569
572
 
570
573
  This method expects [ElementHandle](./element_handle) to point to an
571
574
  [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). 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), targets the control instead.
@@ -1162,6 +1162,8 @@ This method waits for [actionability](https://playwright.dev/python/docs/actiona
1162
1162
  completely visible as defined by
1163
1163
  [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s `ratio`.
1164
1164
 
1165
+ See [scrolling](https://playwright.dev/python/docs/input#scrolling) for alternative ways to scroll.
1166
+
1165
1167
  ## select_option
1166
1168
 
1167
1169
  ```
@@ -1265,6 +1267,7 @@ alias: `input_files=`
1265
1267
 
1266
1268
 
1267
1269
  Upload file or multiple files into `<input type=file>`.
1270
+ For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
1268
1271
 
1269
1272
  **Usage**
1270
1273
 
@@ -1275,6 +1278,9 @@ page.get_by_label("Upload file").set_input_files('myfile.pdf')
1275
1278
  # Select multiple files
1276
1279
  page.get_by_label("Upload files").set_input_files(['file1.txt', 'file2.txt'])
1277
1280
 
1281
+ # Select a directory
1282
+ page.get_by_label("Upload directory").set_input_files('mydir')
1283
+
1278
1284
  # Remove all the selected files
1279
1285
  page.get_by_label("Upload file").set_input_files([])
1280
1286
  ```
@@ -200,7 +200,7 @@ The opposite of [LocatorAssertions#to_have_js_property](./locator_assertions#to_
200
200
  ## not_to_have_role
201
201
 
202
202
  ```ruby
203
- expect(locator).not_to have_role(name, timeout: nil)
203
+ expect(locator).not_to have_role(role, timeout: nil)
204
204
  ```
205
205
 
206
206
 
@@ -78,7 +78,7 @@ def wheel(deltaX, deltaY)
78
78
  ```
79
79
 
80
80
 
81
- Dispatches a `wheel` event.
81
+ Dispatches a `wheel` event. This method is usually used to manually scroll the page. See [scrolling](https://playwright.dev/python/docs/input#scrolling) for alternative ways to scroll.
82
82
 
83
83
  **NOTE**: Wheel events may cause scrolling if they are not handled, and this method does not
84
84
  wait for the scrolling to finish before returning.
@@ -479,27 +479,6 @@ HTML
479
479
  page.click("button")
480
480
  ```
481
481
 
482
- An example of passing an element handle:
483
-
484
- ```ruby
485
- def print_text(source, element)
486
- element.text_content
487
- end
488
-
489
- page.expose_binding("clicked", method(:print_text), handle: true)
490
- page.content = <<~HTML
491
- <script>
492
- document.addEventListener('click', async (event) => {
493
- alert(await window.clicked(event.target));
494
- })
495
- </script>
496
- <div>Click me</div>
497
- <div>Or click me</div>
498
- HTML
499
-
500
- page.locator('div').first.click
501
- ```
502
-
503
482
  ## expose_function
504
483
 
505
484
  ```
@@ -1438,6 +1417,7 @@ def set_input_files(
1438
1417
 
1439
1418
  Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
1440
1419
  are resolved relative to the current working directory. For empty array, clears the selected files.
1420
+ For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
1441
1421
 
1442
1422
  This method expects `selector` to point to an
1443
1423
  [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). 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), targets the control instead.
@@ -1910,6 +1890,11 @@ associated with the page.
1910
1890
 
1911
1891
  **NOTE**: This does not contain ServiceWorkers
1912
1892
 
1893
+ ## clock
1894
+
1895
+
1896
+ Playwright has ability to mock clock and passage of time.
1897
+
1913
1898
  ## accessibility
1914
1899
 
1915
1900
  ## keyboard
@@ -28,7 +28,7 @@ The opposite of [PageAssertions#to_have_title](./page_assertions#to_have_title).
28
28
  ## not_to_have_url
29
29
 
30
30
  ```
31
- def not_to_have_url(urlOrRegExp, timeout: nil)
31
+ def not_to_have_url(urlOrRegExp, ignoreCase: nil, timeout: nil)
32
32
  ```
33
33
 
34
34
 
@@ -214,6 +214,16 @@
214
214
  * register
215
215
  * ~~set_test_id_attribute~~
216
216
 
217
+ ## Clock
218
+
219
+ * fast_forward
220
+ * install
221
+ * run_for
222
+ * pause_at
223
+ * resume
224
+ * set_fixed_time
225
+ * set_system_time
226
+
217
227
  ## ConsoleMessage
218
228
 
219
229
  * args
@@ -340,6 +350,7 @@
340
350
  * expect_worker
341
351
  * workers
342
352
  * ~~wait_for_event~~
353
+ * clock
343
354
  * accessibility
344
355
  * keyboard
345
356
  * mouse
@@ -377,6 +388,7 @@
377
388
  * expect_event
378
389
  * expect_page
379
390
  * ~~wait_for_event~~
391
+ * clock
380
392
  * request
381
393
  * tracing
382
394
 
@@ -6,7 +6,8 @@ module Playwright
6
6
  @tracing = ChannelOwners::Tracing.from(@initializer['tracing'])
7
7
  end
8
8
 
9
- def dispose
9
+ def dispose(reason: nil)
10
+ @close_reason = reason
10
11
  @channel.send_message_to_server('dispose')
11
12
  end
12
13
 
@@ -92,6 +93,9 @@ module Playwright
92
93
  multipart: nil,
93
94
  params: nil,
94
95
  timeout: nil)
96
+ if @close_reason
97
+ raise TargetClosedError.new(message: @close_reason)
98
+ end
95
99
  if [data, form, multipart].compact.count > 1
96
100
  raise ArgumentError.new("Only one of 'data', 'form' or 'multipart' can be specified")
97
101
  end
@@ -5,7 +5,7 @@ module Playwright
5
5
 
6
6
  attr_accessor :browser
7
7
  attr_writer :owner_page, :options
8
- attr_reader :tracing, :request
8
+ attr_reader :clock, :tracing, :request
9
9
 
10
10
  private def after_initialize
11
11
  if @parent.is_a?(ChannelOwners::Browser)
@@ -22,6 +22,7 @@ module Playwright
22
22
 
23
23
  @tracing = ChannelOwners::Tracing.from(@initializer['tracing'])
24
24
  @request = ChannelOwners::APIRequestContext.from(@initializer['requestContext'])
25
+ @clock = ClockImpl.new(self)
25
26
  @har_recorders = {}
26
27
 
27
28
  @channel.on('bindingCall', ->(params) { on_binding(ChannelOwners::BindingCall.from(params['binding'])) })
@@ -441,7 +442,7 @@ module Playwright
441
442
  return if @close_was_called
442
443
  @close_was_called = true
443
444
  @close_reason = reason
444
-
445
+ @request.dispose(reason: reason)
445
446
  inner_close
446
447
  @channel.send_message_to_server('close', { reason: reason }.compact)
447
448
  @closed_promise.value!
@@ -553,14 +554,65 @@ module Playwright
553
554
 
554
555
  # called from InputFiles
555
556
  # @param filepath [string]
556
- # @return [WritableStream]
557
- private def create_temp_file(filepath)
558
- result = @channel.send_message_to_server(
559
- 'createTempFile',
560
- name: File.basename(filepath),
561
- lastModifiedMs: File.mtime(filepath).to_i * 1000,
562
- )
563
- ChannelOwners::WritableStream.from(result)
557
+ # @return [WritableStream, Array<WritableStream>]
558
+ private def create_temp_files(local_directory, files)
559
+ if local_directory
560
+ params = {
561
+ rootDirName: File.basename(local_directory),
562
+ items: files.map do |filepath|
563
+ {
564
+ name: Pathname.new(filepath).relative_path_from(Pathname.new(local_directory)).to_s,
565
+ lastModifiedMs: File.mtime(filepath).to_i * 1000,
566
+ }
567
+ end
568
+ }
569
+ else
570
+ params = {
571
+ items: files.map do |filepath|
572
+ {
573
+ name: File.basename(filepath),
574
+ lastModifiedMs: File.mtime(filepath).to_i * 1000,
575
+ }
576
+ end
577
+ }
578
+ end
579
+
580
+ result = @channel.send_message_to_server_result('createTempFiles', params)
581
+
582
+ [
583
+ ChannelOwners::WritableStream.from_nullable(result['rootDir']),
584
+ result['writableStreams'].map do |s|
585
+ ChannelOwners::WritableStream.from(s)
586
+ end,
587
+ ]
588
+ end
589
+
590
+ private def clock_fast_forward(ticks_params)
591
+ @channel.send_message_to_server('clockFastForward', ticks_params)
592
+ end
593
+
594
+ private def clock_install(time_params)
595
+ @channel.send_message_to_server('clockInstall', time_params)
596
+ end
597
+
598
+ private def clock_pause_at(time_params)
599
+ @channel.send_message_to_server('clockPauseAt', time_params)
600
+ end
601
+
602
+ private def clock_resume
603
+ @channel.send_message_to_server('clockResume')
604
+ end
605
+
606
+ private def clock_run_for(ticks_params)
607
+ @channel.send_message_to_server('clockRunFor', ticks_params)
608
+ end
609
+
610
+ private def clock_set_fixed_time(time_params)
611
+ @channel.send_message_to_server('clockSetFixedTime', time_params)
612
+ end
613
+
614
+ private def clock_set_system_time(time_params)
615
+ @channel.send_message_to_server('clockSetSystemTime', time_params)
564
616
  end
565
617
  end
566
618
  end
@@ -8,7 +8,6 @@ module Playwright
8
8
  include LocatorUtils
9
9
  attr_writer :owned_context
10
10
 
11
-
12
11
  private def after_initialize
13
12
  @browser_context = @parent
14
13
  @timeout_settings = TimeoutSettings.new(@browser_context.send(:_timeout_settings))
@@ -196,6 +195,10 @@ module Playwright
196
195
  @browser_context
197
196
  end
198
197
 
198
+ def clock
199
+ @browser_context.clock
200
+ end
201
+
199
202
  def opener
200
203
  if @opener&.closed?
201
204
  nil
@@ -0,0 +1,65 @@
1
+ module Playwright
2
+ define_api_implementation :ClockImpl do
3
+ def initialize(browser_context)
4
+ @browser_context = browser_context
5
+ end
6
+
7
+ def install(time: nil)
8
+ if time
9
+ @browser_context.send(:clock_install, parse_time(time))
10
+ else
11
+ @browser_context.send(:clock_install, {})
12
+ end
13
+ end
14
+
15
+ def fast_forward(ticks)
16
+ @browser_context.send(:clock_fast_forward, parse_ticks(ticks))
17
+ end
18
+
19
+ def pause_at(time)
20
+ @browser_context.send(:clock_pause_at, parse_time(time))
21
+ end
22
+
23
+ def resume
24
+ @browser_context.send(:clock_resume)
25
+ end
26
+
27
+ def run_for(ticks)
28
+ @browser_context.send(:clock_run_for, parse_ticks(ticks))
29
+ end
30
+
31
+ def set_fixed_time(time)
32
+ @browser_context.send(:clock_set_fixed_time, parse_time(time))
33
+ end
34
+
35
+ def set_system_time(time)
36
+ @browser_context.send(:clock_set_system_time, parse_time(time))
37
+ end
38
+
39
+ private def parse_time(time)
40
+ case time
41
+ when Integer
42
+ { timeNumber: time }
43
+ when String
44
+ { timeString: time }
45
+ else
46
+ if time.respond_to?(:utc)
47
+ { timeNumber: time.utc.to_i }
48
+ else
49
+ raise ArgumentError.new('time must be either integer, string or a Time object')
50
+ end
51
+ end
52
+ end
53
+
54
+ private def parse_ticks(ticks)
55
+ case ticks
56
+ when Integer
57
+ { ticksNumber: ticks }
58
+ when String
59
+ { ticksString: ticks }
60
+ else
61
+ raise ArgumentError.new('ticks must be either integer or string')
62
+ end
63
+ end
64
+ end
65
+ end
@@ -5,16 +5,17 @@ module Playwright
5
5
  def initialize(context, files)
6
6
  @context = context
7
7
  if files.is_a?(File)
8
- @files = [files]
8
+ files_to_resolve = [files]
9
9
  elsif files.is_a?(Enumerable)
10
- @files = files
10
+ files_to_resolve = files
11
11
  else
12
- @files = [files]
12
+ files_to_resolve = [files]
13
13
  end
14
+ resolve_paths_and_directory_for_input_files(files_to_resolve)
14
15
  end
15
16
 
16
17
  def as_method_and_params
17
- if has_large_file?
18
+ if @local_directory || has_large_file?
18
19
  ['setInputFiles', params_for_set_input_file_paths]
19
20
  else
20
21
  ['setInputFiles', params_for_set_input_files]
@@ -24,44 +25,86 @@ module Playwright
24
25
  private def has_large_file?
25
26
  max_bufsize = 1024 * 1024 # 1MB
26
27
 
27
- @files.any? do |file|
28
+ @local_files.any? do |file|
28
29
  case file
29
30
  when String
30
31
  File::Stat.new(file).size > max_bufsize
31
32
  when File
32
33
  file.stat.size > max_bufsize
33
- else
34
- raise_argument_error
35
34
  end
36
35
  end
37
36
  end
38
37
 
39
- private def params_for_set_input_file_paths
40
- writable_streams = @files.map do |file|
41
- case file
38
+ private def resolve_paths_and_directory_for_input_files(files)
39
+ # filter_map is not available in Ruby < 2.7
40
+ @local_files = files.map do |item|
41
+ case item
42
42
  when String
43
- writable_stream = @context.send(:create_temp_file, file)
44
-
45
- File.open(file, 'rb') do |file|
46
- writable_stream.write(file)
43
+ if File.directory?(item)
44
+ raise ArgumentError.new('Multiple directories are not supported') if @local_directory
45
+ @local_directory = item
46
+ next
47
47
  end
48
48
 
49
- writable_stream.channel
49
+ item
50
50
  when File
51
- writable_stream = @context.send(:create_temp_file, file.path)
52
- writable_stream.write(file)
51
+ if File.directory?(item.path)
52
+ raise ArgumentError.new('Multiple directories are not supported') if @local_directory
53
+ @local_directory = item
54
+ next
55
+ end
53
56
 
54
- writable_stream.channel
57
+ item
55
58
  else
56
- raise_argument_error
59
+ raise ArgumentError.new('file must be a String or File or Directory.')
57
60
  end
61
+ end.compact
62
+
63
+ if @local_directory && !@local_files.empty?
64
+ raise ArgumentError.new('File paths must be all files or a single directory')
58
65
  end
66
+ end
67
+
68
+ private def params_for_set_input_file_paths
69
+ if @local_directory
70
+ filenames = Dir["#{@local_directory}/**/*"].reject { |file| File.directory?(file) }
71
+ directory_stream, writable_streams = @context.send(:create_temp_files, @local_directory, filenames)
72
+
73
+ filenames.zip(writable_streams).each do |filename, writable_stream|
74
+ File.open(filename, 'rb') do |file|
75
+ writable_stream.write(file)
76
+ end
77
+ end
78
+
79
+ { directoryStream: directory_stream.channel }
80
+ else
81
+ filenames = @local_files.map do |file|
82
+ case file
83
+ when String
84
+ file
85
+ when File
86
+ file.path
87
+ end
88
+ end
59
89
 
60
- { streams: writable_streams }
90
+ _, writable_streams = @context.send(:create_temp_files, nil, filenames)
91
+ @local_files.zip(writable_streams).each do |file, writable_stream|
92
+ case file
93
+ when String
94
+ File.open(file, 'rb') do |file|
95
+ writable_stream.write(file)
96
+ end
97
+ when File
98
+ writable_stream.write(file)
99
+ end
100
+ end
101
+
102
+ { streams: writable_streams.map(&:channel) }
103
+ end
61
104
  end
62
105
 
63
106
  private def params_for_set_input_files
64
- file_payloads = @files.map do |file|
107
+ file_payloads = @local_files.map do |file|
65
108
  case file
66
109
  when String
67
110
  {
@@ -73,8 +116,6 @@ module Playwright
73
116
  name: File.basename(file.path),
74
117
  buffer: Base64.strict_encode64(file.read),
75
118
  }
76
- else
77
- raise_argument_error
78
119
  end
79
120
  end
80
121
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '1.44.0'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.44.0'
4
+ VERSION = '1.45.0'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.45.0'
6
6
  end
@@ -87,8 +87,8 @@ module Playwright
87
87
 
88
88
  #
89
89
  # All responses returned by [`method: APIRequestContext.get`] and similar methods are stored in the memory, so that you can later call [`method: APIResponse.body`].This method discards all its resources, calling any method on disposed `APIRequestContext` will throw an exception.
90
- def dispose
91
- wrap_impl(@impl.dispose)
90
+ def dispose(reason: nil)
91
+ wrap_impl(@impl.dispose(reason: unwrap_impl(reason)))
92
92
  end
93
93
 
94
94
  #
@@ -45,9 +45,9 @@ module Playwright
45
45
  #
46
46
  # ```python sync
47
47
  # browser = pw.webkit.launch()
48
- # print(len(browser.contexts())) # prints `0`
48
+ # print(len(browser.contexts)) # prints `0`
49
49
  # context = browser.new_context()
50
- # print(len(browser.contexts())) # prints `1`
50
+ # print(len(browser.contexts)) # prints `1`
51
51
  # ```
52
52
  def contexts
53
53
  wrap_impl(@impl.contexts)
@@ -20,6 +20,12 @@ module Playwright
20
20
  # ```
21
21
  class BrowserContext < PlaywrightApi
22
22
 
23
+ #
24
+ # Playwright has ability to mock clock and passage of time.
25
+ def clock # property
26
+ wrap_impl(@impl.clock)
27
+ end
28
+
23
29
  #
24
30
  # API testing helper associated with this context. Requests made with this API will use context cookies.
25
31
  def request # property
@@ -163,22 +169,6 @@ module Playwright
163
169
  # with sync_playwright() as playwright:
164
170
  # run(playwright)
165
171
  # ```
166
- #
167
- # An example of passing an element handle:
168
- #
169
- # ```python sync
170
- # def print(source, element):
171
- # print(element.text_content())
172
- #
173
- # context.expose_binding("clicked", print, handle=true)
174
- # page.set_content("""
175
- # <script>
176
- # document.addEventListener('click', event => window.clicked(event.target));
177
- # </script>
178
- # <div>Click me</div>
179
- # <div>Or click me</div>
180
- # """)
181
- # ```
182
172
  def expose_binding(name, callback, handle: nil)
183
173
  wrap_impl(@impl.expose_binding(unwrap_impl(name), unwrap_impl(callback), handle: unwrap_impl(handle)))
184
174
  end
@@ -0,0 +1,109 @@
1
+ module Playwright
2
+ #
3
+ # Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Learn more about [clock emulation](../clock.md).
4
+ #
5
+ # Note that clock is installed for the entire `BrowserContext`, so the time
6
+ # in all the pages and iframes is controlled by the same clock.
7
+ class Clock < PlaywrightApi
8
+
9
+ #
10
+ # Advance the clock by jumping forward in time. Only fires due timers at most once. This is equivalent to user closing the laptop lid for a while and
11
+ # reopening it later, after given time.
12
+ #
13
+ # **Usage**
14
+ #
15
+ # ```python sync
16
+ # page.clock.fast_forward(1000)
17
+ # page.clock.fast_forward("30:00")
18
+ # ```
19
+ def fast_forward(ticks)
20
+ wrap_impl(@impl.fast_forward(unwrap_impl(ticks)))
21
+ end
22
+
23
+ #
24
+ # Install fake implementations for the following time-related functions:
25
+ # - `Date`
26
+ # - `setTimeout`
27
+ # - `clearTimeout`
28
+ # - `setInterval`
29
+ # - `clearInterval`
30
+ # - `requestAnimationFrame`
31
+ # - `cancelAnimationFrame`
32
+ # - `requestIdleCallback`
33
+ # - `cancelIdleCallback`
34
+ # - `performance`
35
+ #
36
+ # Fake timers are used to manually control the flow of time in tests. They allow you to advance time, fire timers, and control the behavior of time-dependent functions. See [`method: Clock.runFor`] and [`method: Clock.fastForward`] for more information.
37
+ def install(time: nil)
38
+ wrap_impl(@impl.install(time: unwrap_impl(time)))
39
+ end
40
+
41
+ #
42
+ # Advance the clock, firing all the time-related callbacks.
43
+ #
44
+ # **Usage**
45
+ #
46
+ # ```python sync
47
+ # page.clock.run_for(1000);
48
+ # page.clock.run_for("30:00")
49
+ # ```
50
+ def run_for(ticks)
51
+ wrap_impl(@impl.run_for(unwrap_impl(ticks)))
52
+ end
53
+
54
+ #
55
+ # Advance the clock by jumping forward in time and pause the time. Once this method is called, no timers
56
+ # are fired unless [`method: Clock.runFor`], [`method: Clock.fastForward`], [`method: Clock.pauseAt`] or [`method: Clock.resume`] is called.
57
+ #
58
+ # Only fires due timers at most once.
59
+ # This is equivalent to user closing the laptop lid for a while and reopening it at the specified time and
60
+ # pausing.
61
+ #
62
+ # **Usage**
63
+ #
64
+ # ```python sync
65
+ # page.clock.pause_at(datetime.datetime(2020, 2, 2))
66
+ # page.clock.pause_at("2020-02-02")
67
+ # ```
68
+ def pause_at(time)
69
+ wrap_impl(@impl.pause_at(unwrap_impl(time)))
70
+ end
71
+
72
+ #
73
+ # Resumes timers. Once this method is called, time resumes flowing, timers are fired as usual.
74
+ def resume
75
+ wrap_impl(@impl.resume)
76
+ end
77
+
78
+ #
79
+ # Makes `Date.now` and `new Date()` return fixed fake time at all times,
80
+ # keeps all the timers running.
81
+ #
82
+ # **Usage**
83
+ #
84
+ # ```python sync
85
+ # page.clock.set_fixed_time(datetime.datetime.now())
86
+ # page.clock.set_fixed_time(datetime.datetime(2020, 2, 2))
87
+ # page.clock.set_fixed_time("2020-02-02")
88
+ # ```
89
+ def set_fixed_time(time)
90
+ wrap_impl(@impl.set_fixed_time(unwrap_impl(time)))
91
+ end
92
+ alias_method :fixed_time=, :set_fixed_time
93
+
94
+ #
95
+ # Sets current system time but does not trigger any timers.
96
+ #
97
+ # **Usage**
98
+ #
99
+ # ```python sync
100
+ # page.clock.set_system_time(datetime.datetime.now())
101
+ # page.clock.set_system_time(datetime.datetime(2020, 2, 2))
102
+ # page.clock.set_system_time("2020-02-02")
103
+ # ```
104
+ def set_system_time(time)
105
+ wrap_impl(@impl.set_system_time(unwrap_impl(time)))
106
+ end
107
+ alias_method :system_time=, :set_system_time
108
+ end
109
+ end
@@ -1,7 +1,7 @@
1
1
  module Playwright
2
2
  #
3
3
  # `ConsoleMessage` objects are dispatched by page via the [`event: Page.console`] event.
4
- # For each console messages logged in the page there will be corresponding event in the Playwright
4
+ # For each console message logged in the page there will be corresponding event in the Playwright
5
5
  # context.
6
6
  #
7
7
  # ```python sync
@@ -395,6 +395,8 @@ module Playwright
395
395
  #
396
396
  # Throws when `elementHandle` does not point to an element
397
397
  # [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
398
+ #
399
+ # See [scrolling](../input.md#scrolling) for alternative ways to scroll.
398
400
  def scroll_into_view_if_needed(timeout: nil)
399
401
  wrap_impl(@impl.scroll_into_view_if_needed(timeout: unwrap_impl(timeout)))
400
402
  end
@@ -464,6 +466,7 @@ module Playwright
464
466
  #
465
467
  # Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
466
468
  # are resolved relative to the current working directory. For empty array, clears the selected files.
469
+ # For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
467
470
  #
468
471
  # This method expects `ElementHandle` to point to an
469
472
  # [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). 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), targets the control instead.
@@ -983,6 +983,8 @@ module Playwright
983
983
  # This method waits for [actionability](../actionability.md) checks, then tries to scroll element into view, unless it is
984
984
  # completely visible as defined by
985
985
  # [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s `ratio`.
986
+ #
987
+ # See [scrolling](../input.md#scrolling) for alternative ways to scroll.
986
988
  def scroll_into_view_if_needed(timeout: nil)
987
989
  wrap_impl(@impl.scroll_into_view_if_needed(timeout: unwrap_impl(timeout)))
988
990
  end
@@ -1073,6 +1075,7 @@ module Playwright
1073
1075
 
1074
1076
  #
1075
1077
  # Upload file or multiple files into `<input type=file>`.
1078
+ # For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
1076
1079
  #
1077
1080
  # **Usage**
1078
1081
  #
@@ -1083,6 +1086,9 @@ module Playwright
1083
1086
  # # Select multiple files
1084
1087
  # page.get_by_label("Upload files").set_input_files(['file1.txt', 'file2.txt'])
1085
1088
  #
1089
+ # # Select a directory
1090
+ # page.get_by_label("Upload directory").set_input_files('mydir')
1091
+ #
1086
1092
  # # Remove all the selected files
1087
1093
  # page.get_by_label("Upload file").set_input_files([])
1088
1094
  #
@@ -128,8 +128,8 @@ module Playwright
128
128
 
129
129
  #
130
130
  # The opposite of [`method: LocatorAssertions.toHaveRole`].
131
- def not_to_have_role(name, timeout: nil)
132
- wrap_impl(@impl.not_to_have_role(unwrap_impl(name), timeout: unwrap_impl(timeout)))
131
+ def not_to_have_role(role, timeout: nil)
132
+ wrap_impl(@impl.not_to_have_role(unwrap_impl(role), timeout: unwrap_impl(timeout)))
133
133
  end
134
134
 
135
135
  #
@@ -53,7 +53,7 @@ module Playwright
53
53
  end
54
54
 
55
55
  #
56
- # Dispatches a `wheel` event.
56
+ # Dispatches a `wheel` event. This method is usually used to manually scroll the page. See [scrolling](../input.md#scrolling) for alternative ways to scroll.
57
57
  #
58
58
  # **NOTE**: Wheel events may cause scrolling if they are not handled, and this method does not
59
59
  # wait for the scrolling to finish before returning.
@@ -44,6 +44,12 @@ module Playwright
44
44
  # ```
45
45
  class Page < PlaywrightApi
46
46
 
47
+ #
48
+ # Playwright has ability to mock clock and passage of time.
49
+ def clock # property
50
+ wrap_impl(@impl.clock)
51
+ end
52
+
47
53
  def accessibility # property
48
54
  wrap_impl(@impl.accessibility)
49
55
  end
@@ -463,22 +469,6 @@ module Playwright
463
469
  # with sync_playwright() as playwright:
464
470
  # run(playwright)
465
471
  # ```
466
- #
467
- # An example of passing an element handle:
468
- #
469
- # ```python sync
470
- # def print(source, element):
471
- # print(element.text_content())
472
- #
473
- # page.expose_binding("clicked", print, handle=true)
474
- # page.set_content("""
475
- # <script>
476
- # document.addEventListener('click', event => window.clicked(event.target));
477
- # </script>
478
- # <div>Click me</div>
479
- # <div>Or click me</div>
480
- # """)
481
- # ```
482
472
  def expose_binding(name, callback, handle: nil)
483
473
  wrap_impl(@impl.expose_binding(unwrap_impl(name), unwrap_impl(callback), handle: unwrap_impl(handle)))
484
474
  end
@@ -1353,6 +1343,7 @@ module Playwright
1353
1343
  #
1354
1344
  # Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
1355
1345
  # are resolved relative to the current working directory. For empty array, clears the selected files.
1346
+ # For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
1356
1347
  #
1357
1348
  # This method expects `selector` to point to an
1358
1349
  # [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). 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), targets the control instead.
@@ -1656,7 +1647,7 @@ module Playwright
1656
1647
  # return response.ok
1657
1648
  #
1658
1649
  # # or with a lambda
1659
- # with page.expect_response(lambda response: response.url == "https://example.com" and response.status == 200) as response_info:
1650
+ # with page.expect_response(lambda response: response.url == "https://example.com" and response.status == 200 and response.request.method == "get") as response_info:
1660
1651
  # page.get_by_text("trigger response").click()
1661
1652
  # response = response_info.value
1662
1653
  # return response.ok
@@ -21,8 +21,8 @@ module Playwright
21
21
 
22
22
  #
23
23
  # The opposite of [`method: PageAssertions.toHaveURL`].
24
- def not_to_have_url(urlOrRegExp, timeout: nil)
25
- wrap_impl(@impl.not_to_have_url(unwrap_impl(urlOrRegExp), timeout: unwrap_impl(timeout)))
24
+ def not_to_have_url(urlOrRegExp, ignoreCase: nil, timeout: nil)
25
+ wrap_impl(@impl.not_to_have_url(unwrap_impl(urlOrRegExp), ignoreCase: unwrap_impl(ignoreCase), timeout: unwrap_impl(timeout)))
26
26
  end
27
27
 
28
28
  #
@@ -94,13 +94,13 @@ module Playwright
94
94
  end
95
95
 
96
96
  # @nodoc
97
- def electron
98
- wrap_impl(@impl.electron)
97
+ def android
98
+ wrap_impl(@impl.android)
99
99
  end
100
100
 
101
101
  # @nodoc
102
- def android
103
- wrap_impl(@impl.android)
102
+ def electron
103
+ wrap_impl(@impl.electron)
104
104
  end
105
105
 
106
106
  # -- inherited from EventEmitter --
@@ -47,13 +47,13 @@ module Playwright
47
47
  end
48
48
 
49
49
  # @nodoc
50
- def page=(req)
51
- wrap_impl(@impl.page=(unwrap_impl(req)))
50
+ def context=(req)
51
+ wrap_impl(@impl.context=(unwrap_impl(req)))
52
52
  end
53
53
 
54
54
  # @nodoc
55
- def context=(req)
56
- wrap_impl(@impl.context=(unwrap_impl(req)))
55
+ def page=(req)
56
+ wrap_impl(@impl.page=(unwrap_impl(req)))
57
57
  end
58
58
 
59
59
  # -- inherited from EventEmitter --
data/sig/playwright.rbs CHANGED
@@ -220,6 +220,18 @@ module Playwright
220
220
  def register: (String name, ?script: String, ?contentScript: bool, ?path: (String | File)) -> void
221
221
  end
222
222
 
223
+ class Clock
224
+ def fast_forward: ((Integer | String) ticks) -> void
225
+ def install: (?time: (Integer | String | Time)) -> void
226
+ def run_for: ((Integer | String) ticks) -> void
227
+ def pause_at: ((Integer | String | Time) time) -> void
228
+ def resume: -> void
229
+ def set_fixed_time: ((Integer | String | Time) time) -> void
230
+ def fixed_time=: ((Integer | String | Time) time) -> void
231
+ def set_system_time: ((Integer | String | Time) time) -> void
232
+ def system_time=: ((Integer | String | Time) time) -> void
233
+ end
234
+
223
235
  class ConsoleMessage
224
236
  def args: -> Array[untyped]
225
237
  def location: -> Hash[untyped, untyped]
@@ -348,6 +360,7 @@ module Playwright
348
360
  def expect_worker: (?predicate: function, ?timeout: Float) { () -> void } -> Worker
349
361
  def workers: -> Array[untyped]
350
362
 
363
+ attr_reader clock: Clock
351
364
  attr_reader accessibility: Accessibility
352
365
  attr_reader keyboard: Keyboard
353
366
  attr_reader mouse: Mouse
@@ -390,6 +403,7 @@ module Playwright
390
403
  def expect_event: (String event, ?predicate: function, ?timeout: Float) { () -> void } -> untyped
391
404
  def expect_page: (?predicate: function, ?timeout: Float) { () -> void } -> Page
392
405
 
406
+ attr_reader clock: Clock
393
407
  attr_reader request: APIRequestContext
394
408
  attr_reader tracing: Tracing
395
409
  end
@@ -533,7 +547,7 @@ module Playwright
533
547
 
534
548
  class APIRequestContext
535
549
  def delete: (String url, ?data: (String | String | untyped), ?failOnStatusCode: bool, ?form: Hash[untyped, untyped], ?headers: Hash[untyped, untyped], ?ignoreHTTPSErrors: bool, ?maxRedirects: Integer, ?multipart: Hash[untyped, untyped], ?params: Hash[untyped, untyped], ?timeout: Float) -> APIResponse
536
- def dispose: -> void
550
+ def dispose: (?reason: String) -> void
537
551
  def fetch: ((String | Request) urlOrRequest, ?data: (String | String | untyped), ?failOnStatusCode: bool, ?form: Hash[untyped, untyped], ?headers: Hash[untyped, untyped], ?ignoreHTTPSErrors: bool, ?maxRedirects: Integer, ?method: String, ?multipart: Hash[untyped, untyped], ?params: Hash[untyped, untyped], ?timeout: Float) -> APIResponse
538
552
  def get: (String url, ?data: (String | String | untyped), ?failOnStatusCode: bool, ?form: Hash[untyped, untyped], ?headers: Hash[untyped, untyped], ?ignoreHTTPSErrors: bool, ?maxRedirects: Integer, ?multipart: Hash[untyped, untyped], ?params: Hash[untyped, untyped], ?timeout: Float) -> APIResponse
539
553
  def head: (String url, ?data: (String | String | untyped), ?failOnStatusCode: bool, ?form: Hash[untyped, untyped], ?headers: Hash[untyped, untyped], ?ignoreHTTPSErrors: bool, ?maxRedirects: Integer, ?multipart: Hash[untyped, untyped], ?params: Hash[untyped, untyped], ?timeout: Float) -> APIResponse
@@ -562,7 +576,7 @@ module Playwright
562
576
  def not_to_have_css: (String name, (String | Regexp) value, ?timeout: Float) -> void
563
577
  def not_to_have_id: ((String | Regexp) id, ?timeout: Float) -> void
564
578
  def not_to_have_js_property: (String name, untyped value, ?timeout: Float) -> void
565
- def not_to_have_role: ((String | Regexp) name, ?timeout: Float) -> void
579
+ def not_to_have_role: (("alert" | "alertdialog" | "application" | "article" | "banner" | "blockquote" | "button" | "caption" | "cell" | "checkbox" | "code" | "columnheader" | "combobox" | "complementary" | "contentinfo" | "definition" | "deletion" | "dialog" | "directory" | "document" | "emphasis" | "feed" | "figure" | "form" | "generic" | "grid" | "gridcell" | "group" | "heading" | "img" | "insertion" | "link" | "list" | "listbox" | "listitem" | "log" | "main" | "marquee" | "math" | "meter" | "menu" | "menubar" | "menuitem" | "menuitemcheckbox" | "menuitemradio" | "navigation" | "none" | "note" | "option" | "paragraph" | "presentation" | "progressbar" | "radio" | "radiogroup" | "region" | "row" | "rowgroup" | "rowheader" | "scrollbar" | "search" | "searchbox" | "separator" | "slider" | "spinbutton" | "status" | "strong" | "subscript" | "superscript" | "switch" | "tab" | "table" | "tablist" | "tabpanel" | "term" | "textbox" | "time" | "timer" | "toolbar" | "tooltip" | "tree" | "treegrid" | "treeitem") role, ?timeout: Float) -> void
566
580
  def not_to_have_text: ((String | Regexp | Array[untyped] | Array[untyped] | Array[untyped]) expected, ?ignoreCase: bool, ?timeout: Float, ?useInnerText: bool) -> void
567
581
  def not_to_have_value: ((String | Regexp) value, ?timeout: Float) -> void
568
582
  def not_to_have_values: ((Array[untyped] | Array[untyped] | Array[untyped]) values, ?timeout: Float) -> void
@@ -593,7 +607,7 @@ module Playwright
593
607
 
594
608
  class PageAssertions
595
609
  def not_to_have_title: ((String | Regexp) titleOrRegExp, ?timeout: Float) -> void
596
- def not_to_have_url: ((String | Regexp) urlOrRegExp, ?timeout: Float) -> void
610
+ def not_to_have_url: ((String | Regexp) urlOrRegExp, ?ignoreCase: bool, ?timeout: Float) -> void
597
611
  def to_have_title: ((String | Regexp) titleOrRegExp, ?timeout: Float) -> void
598
612
  def to_have_url: ((String | Regexp) urlOrRegExp, ?ignoreCase: bool, ?timeout: Float) -> void
599
613
  end
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.44.0
4
+ version: 1.45.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-20 00:00:00.000000000 Z
11
+ date: 2024-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -217,6 +217,7 @@ files:
217
217
  - documentation/docs/api/browser_context.md
218
218
  - documentation/docs/api/browser_type.md
219
219
  - documentation/docs/api/cdp_session.md
220
+ - documentation/docs/api/clock.md
220
221
  - documentation/docs/api/console_message.md
221
222
  - documentation/docs/api/dialog.md
222
223
  - documentation/docs/api/download.md
@@ -310,6 +311,7 @@ files:
310
311
  - lib/playwright/channel_owners/web_socket.rb
311
312
  - lib/playwright/channel_owners/worker.rb
312
313
  - lib/playwright/channel_owners/writable_stream.rb
314
+ - lib/playwright/clock_impl.rb
313
315
  - lib/playwright/connection.rb
314
316
  - lib/playwright/console_message_impl.rb
315
317
  - lib/playwright/download_impl.rb
@@ -363,6 +365,7 @@ files:
363
365
  - lib/playwright_api/browser_context.rb
364
366
  - lib/playwright_api/browser_type.rb
365
367
  - lib/playwright_api/cdp_session.rb
368
+ - lib/playwright_api/clock.rb
366
369
  - lib/playwright_api/console_message.rb
367
370
  - lib/playwright_api/dialog.rb
368
371
  - lib/playwright_api/download.rb
@@ -410,5 +413,5 @@ requirements: []
410
413
  rubygems_version: 3.3.27
411
414
  signing_key:
412
415
  specification_version: 4
413
- summary: The Ruby binding of playwright driver 1.44.0
416
+ summary: The Ruby binding of playwright driver 1.45.0
414
417
  test_files: []