playwright-ruby-client 1.31.1 → 1.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/browser_context.md +7 -1
  3. data/documentation/docs/api/frame.md +10 -3
  4. data/documentation/docs/api/frame_locator.md +10 -3
  5. data/documentation/docs/api/locator.md +40 -4
  6. data/documentation/docs/api/page.md +17 -4
  7. data/documentation/docs/api/route.md +1 -0
  8. data/documentation/docs/api/tracing.md +1 -1
  9. data/documentation/docs/include/api_coverage.md +1 -0
  10. data/lib/playwright/channel.rb +1 -0
  11. data/lib/playwright/channel_owners/browser.rb +2 -8
  12. data/lib/playwright/channel_owners/browser_context.rb +12 -7
  13. data/lib/playwright/channel_owners/browser_type.rb +13 -6
  14. data/lib/playwright/channel_owners/frame.rb +14 -2
  15. data/lib/playwright/channel_owners/local_utils.rb +18 -6
  16. data/lib/playwright/channel_owners/page.rb +14 -4
  17. data/lib/playwright/channel_owners/request.rb +6 -1
  18. data/lib/playwright/channel_owners/route.rb +5 -2
  19. data/lib/playwright/channel_owners/tracing.rb +61 -15
  20. data/lib/playwright/connection.rb +23 -1
  21. data/lib/playwright/frame_locator_impl.rb +9 -3
  22. data/lib/playwright/locator_impl.rb +39 -10
  23. data/lib/playwright/version.rb +2 -2
  24. data/lib/playwright.rb +1 -1
  25. data/lib/playwright_api/android_device.rb +4 -4
  26. data/lib/playwright_api/browser_context.rb +13 -7
  27. data/lib/playwright_api/frame.rb +15 -8
  28. data/lib/playwright_api/frame_locator.rb +11 -4
  29. data/lib/playwright_api/locator.rb +38 -6
  30. data/lib/playwright_api/page.rb +24 -11
  31. data/lib/playwright_api/request.rb +4 -4
  32. data/lib/playwright_api/route.rb +2 -1
  33. data/lib/playwright_api/tracing.rb +2 -2
  34. data/sig/playwright.rbs +10 -9
  35. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 409785017cb92188415f2e06c7ed8f369cd95723a60b70dcf86b1e4e110ff07b
4
- data.tar.gz: 79a75b15a818e32ec1cb2f6dda2f64b0eb0f18316373ec8c84cab208efae6593
3
+ metadata.gz: ebc7a6ffab254ce53486bcaf8ad642a42fbadd77f33f48598ee721935f795c98
4
+ data.tar.gz: bf6473ce5c3ea31bdcca4f072b68aeb4b1b49b0ffb24cc39a7d17955e5de49cf
5
5
  SHA512:
6
- metadata.gz: 26e88e610f09aba2993c26866e5927ce972a9c63f50dda6b00f91d221d1925a70ee8820ecddcfa69579d29346a53e9a150e5dfa81d36f19f6c9da74d8135bb48
7
- data.tar.gz: 8e25217e4425a3d3376710a872748d6acd966a1e941dbc5728bd8e63f05dd08cb04a1487fdda96cc5879db1b1e0ad2b5c8730bb0e057ca7ac416748ace60cea7
6
+ metadata.gz: 1e36fed96c70031d7b78ffffe1b3408251fb86b64afb634304d8fe3434b263de696e99b42cb330bb75b2f68a80683caf56e050dddf1b9ead61d97f2dd885b270
7
+ data.tar.gz: eb7607a301b420b0c3c587dfa562eccf459a943e425da930c7739a2faccb46888dbfeb84bd83953ef8eb1446322cdc8cd4c4e58f3ca71515999e11dfcd3ba121
@@ -333,7 +333,13 @@ To remove a route with its handler you can use [BrowserContext#unroute](./browse
333
333
  ## route_from_har
334
334
 
335
335
  ```
336
- def route_from_har(har, notFound: nil, update: nil, url: nil)
336
+ def route_from_har(
337
+ har,
338
+ notFound: nil,
339
+ update: nil,
340
+ updateContent: nil,
341
+ updateMode: nil,
342
+ url: nil)
337
343
  ```
338
344
 
339
345
 
@@ -439,18 +439,20 @@ def get_by_label(text, exact: nil)
439
439
  ```
440
440
 
441
441
 
442
- Allows locating input elements by the text of the associated label.
442
+ Allows locating input elements by the text of the associated `<label>` or `aria-labelledby` element, or by the `aria-label` attribute.
443
443
 
444
444
  **Usage**
445
445
 
446
- For example, this method will find the input by label text "Password" in the following DOM:
446
+ For example, this method will find inputs by label "Username" and "Password" in the following DOM:
447
447
 
448
448
  ```html
449
+ <input aria-label="Username">
449
450
  <label for="password-input">Password:</label>
450
451
  <input id="password-input">
451
452
  ```
452
453
 
453
454
  ```ruby
455
+ page.get_by_label("Username").fill("john")
454
456
  page.get_by_label("Password").fill("secret")
455
457
  ```
456
458
 
@@ -777,7 +779,12 @@ Returns whether the element is [visible](https://playwright.dev/python/docs/acti
777
779
  ## locator
778
780
 
779
781
  ```
780
- def locator(selector, has: nil, hasText: nil)
782
+ def locator(
783
+ selector,
784
+ has: nil,
785
+ hasNot: nil,
786
+ hasNotText: nil,
787
+ hasText: nil)
781
788
  ```
782
789
 
783
790
 
@@ -79,18 +79,20 @@ def get_by_label(text, exact: nil)
79
79
  ```
80
80
 
81
81
 
82
- Allows locating input elements by the text of the associated label.
82
+ Allows locating input elements by the text of the associated `<label>` or `aria-labelledby` element, or by the `aria-label` attribute.
83
83
 
84
84
  **Usage**
85
85
 
86
- For example, this method will find the input by label text "Password" in the following DOM:
86
+ For example, this method will find inputs by label "Username" and "Password" in the following DOM:
87
87
 
88
88
  ```html
89
+ <input aria-label="Username">
89
90
  <label for="password-input">Password:</label>
90
91
  <input id="password-input">
91
92
  ```
92
93
 
93
94
  ```ruby
95
+ page.get_by_label("Username").fill("john")
94
96
  page.get_by_label("Password").fill("secret")
95
97
  ```
96
98
 
@@ -282,7 +284,12 @@ Returns locator to the last matching frame.
282
284
  ## locator
283
285
 
284
286
  ```
285
- def locator(selector, has: nil, hasText: nil)
287
+ def locator(
288
+ selectorOrLocator,
289
+ has: nil,
290
+ hasNot: nil,
291
+ hasNotText: nil,
292
+ hasText: nil)
286
293
  ```
287
294
 
288
295
 
@@ -20,6 +20,12 @@ def all
20
20
  When locator points to a list of elements, returns array of locators, pointing
21
21
  to respective elements.
22
22
 
23
+ **NOTE**: [Locator#all](./locator#all) does not wait for elements to match the locator, and instead immediately returns whatever is present in the page.
24
+
25
+ When the list of elements changes dynamically, [Locator#all](./locator#all) will produce unpredictable and flaky results.
26
+
27
+ When the list of elements is stable, but loaded dynamically, wait for the full list to finish loading before calling [Locator#all](./locator#all).
28
+
23
29
  **Usage**
24
30
 
25
31
  ```ruby
@@ -441,7 +447,7 @@ To send fine-grained keyboard events, use [Locator#type](./locator#type).
441
447
  ## filter
442
448
 
443
449
  ```
444
- def filter(has: nil, hasText: nil)
450
+ def filter(has: nil, hasNot: nil, hasNotText: nil, hasText: nil)
445
451
  ```
446
452
 
447
453
 
@@ -532,18 +538,20 @@ def get_by_label(text, exact: nil)
532
538
  ```
533
539
 
534
540
 
535
- Allows locating input elements by the text of the associated label.
541
+ Allows locating input elements by the text of the associated `<label>` or `aria-labelledby` element, or by the `aria-label` attribute.
536
542
 
537
543
  **Usage**
538
544
 
539
- For example, this method will find the input by label text "Password" in the following DOM:
545
+ For example, this method will find inputs by label "Username" and "Password" in the following DOM:
540
546
 
541
547
  ```html
548
+ <input aria-label="Username">
542
549
  <label for="password-input">Password:</label>
543
550
  <input id="password-input">
544
551
  ```
545
552
 
546
553
  ```ruby
554
+ page.get_by_label("Username").fill("john")
547
555
  page.get_by_label("Password").fill("secret")
548
556
  ```
549
557
 
@@ -911,7 +919,12 @@ banana = page.get_by_role("listitem").last
911
919
  ## locator
912
920
 
913
921
  ```
914
- def locator(selector, has: nil, hasText: nil)
922
+ def locator(
923
+ selectorOrLocator,
924
+ has: nil,
925
+ hasNot: nil,
926
+ hasNotText: nil,
927
+ hasText: nil)
915
928
  ```
916
929
 
917
930
 
@@ -934,6 +947,29 @@ Returns locator to the n-th matching element. It's zero based, `nth(0)` selects
934
947
  banana = page.get_by_role("listitem").nth(2)
935
948
  ```
936
949
 
950
+ ## or
951
+
952
+ ```
953
+ def or(locator)
954
+ ```
955
+
956
+
957
+ Creates a locator that matches either of the two locators.
958
+
959
+ **Usage**
960
+
961
+ Consider a scenario where you'd like to click on a "New email" button, but sometimes a security settings dialog shows up instead. In this case, you can wait for either a "New email" button, or a dialog and act accordingly.
962
+
963
+ ```ruby
964
+ new_email = page.get_by_role("button", name: "New")
965
+ dialog = page.get_by_text("Confirm security settings")
966
+ new_email.or(dialog).wait_for(state: 'visible')
967
+ if dialog.visible?
968
+ page.get_by_role("button", name: "Dismiss").click
969
+ end
970
+ new_email.click
971
+ ```
972
+
937
973
  ## page
938
974
 
939
975
  ```
@@ -651,18 +651,20 @@ def get_by_label(text, exact: nil)
651
651
  ```
652
652
 
653
653
 
654
- Allows locating input elements by the text of the associated label.
654
+ Allows locating input elements by the text of the associated `<label>` or `aria-labelledby` element, or by the `aria-label` attribute.
655
655
 
656
656
  **Usage**
657
657
 
658
- For example, this method will find the input by label text "Password" in the following DOM:
658
+ For example, this method will find inputs by label "Username" and "Password" in the following DOM:
659
659
 
660
660
  ```html
661
+ <input aria-label="Username">
661
662
  <label for="password-input">Password:</label>
662
663
  <input id="password-input">
663
664
  ```
664
665
 
665
666
  ```ruby
667
+ page.get_by_label("Username").fill("john")
666
668
  page.get_by_label("Password").fill("secret")
667
669
  ```
668
670
 
@@ -1013,7 +1015,12 @@ Returns whether the element is [visible](https://playwright.dev/python/docs/acti
1013
1015
  ## locator
1014
1016
 
1015
1017
  ```
1016
- def locator(selector, has: nil, hasText: nil)
1018
+ def locator(
1019
+ selector,
1020
+ has: nil,
1021
+ hasNot: nil,
1022
+ hasNotText: nil,
1023
+ hasText: nil)
1017
1024
  ```
1018
1025
 
1019
1026
 
@@ -1256,7 +1263,13 @@ To remove a route with its handler you can use [Page#unroute](./page#unroute).
1256
1263
  ## route_from_har
1257
1264
 
1258
1265
  ```
1259
- def route_from_har(har, notFound: nil, update: nil, url: nil)
1266
+ def route_from_har(
1267
+ har,
1268
+ notFound: nil,
1269
+ update: nil,
1270
+ updateContent: nil,
1271
+ updateMode: nil,
1272
+ url: nil)
1260
1273
  ```
1261
1274
 
1262
1275
 
@@ -122,6 +122,7 @@ def fetch(
122
122
  maxRedirects: nil,
123
123
  method: nil,
124
124
  postData: nil,
125
+ timeout: nil,
125
126
  url: nil)
126
127
  ```
127
128
 
@@ -44,7 +44,7 @@ context.tracing.stop(path: 'trace.zip')
44
44
  ## start_chunk
45
45
 
46
46
  ```
47
- def start_chunk(title: nil)
47
+ def start_chunk(name: nil, title: nil)
48
48
  ```
49
49
 
50
50
 
@@ -463,6 +463,7 @@
463
463
  * last
464
464
  * locator
465
465
  * nth
466
+ * or
466
467
  * page
467
468
  * press
468
469
  * screenshot
@@ -67,6 +67,7 @@ module Playwright
67
67
 
68
68
  private def build_metadata_payload_from(api_name, stacks)
69
69
  {
70
+ wallTime: (Time.now.to_f * 1000).to_i,
70
71
  apiName: api_name,
71
72
  stack: stacks.map do |loc|
72
73
  { file: loc.absolute_path || '', line: loc.lineno, function: loc.label }
@@ -32,10 +32,7 @@ module Playwright
32
32
 
33
33
  resp = @channel.send_message_to_server('newContext', params.compact)
34
34
  context = ChannelOwners::BrowserContext.from(resp)
35
- @contexts << context
36
- context.browser = self
37
- context.options = params
38
- context.send(:update_browser_type, @browser_type)
35
+ @browser_type.send(:did_create_context, context, params)
39
36
  return context unless block
40
37
 
41
38
  begin
@@ -62,9 +59,6 @@ module Playwright
62
59
 
63
60
  private def update_browser_type(browser_type)
64
61
  @browser_type = browser_type
65
- @contexts.each do |context|
66
- context.send(:update_browser_type, browser_type)
67
- end
68
62
  end
69
63
 
70
64
  def close
@@ -110,7 +104,7 @@ module Playwright
110
104
  @closed_or_closing = true
111
105
  end
112
106
 
113
- # called from BrowserType#connectOverCDP
107
+ # called from BrowserContext#initialize, BrowserType#connectOverCDP
114
108
  private def add_context(context)
115
109
  @contexts << context
116
110
  end
@@ -9,6 +9,10 @@ module Playwright
9
9
  attr_reader :tracing, :request
10
10
 
11
11
  private def after_initialize
12
+ if @parent.is_a?(ChannelOwners::Browser)
13
+ @browser = @parent
14
+ @browser.send(:add_context, self)
15
+ end
12
16
  @pages = Set.new
13
17
  @routes = []
14
18
  @bindings = {}
@@ -62,14 +66,15 @@ module Playwright
62
66
  @closed_promise = Concurrent::Promises.resolvable_future
63
67
  end
64
68
 
65
- private def update_browser_type(browser_type)
66
- @browser_type = browser_type
69
+ private def update_options(context_options:, browser_options:)
70
+ @options = context_options
67
71
  if @options[:recordHar]
68
72
  @har_recorders[''] = {
69
73
  path: @options[:recordHar][:path],
70
74
  content: @options[:recordHar][:content]
71
75
  }
72
76
  end
77
+ @tracing.send(:update_traces_dir, browser_options[:tracesDir])
73
78
  end
74
79
 
75
80
  private def on_page(page)
@@ -290,12 +295,12 @@ module Playwright
290
295
  update_interception_patterns
291
296
  end
292
297
 
293
- private def record_into_har(har, page, notFound:, url:)
298
+ private def record_into_har(har, page, notFound:, url:, updateContent:, updateMode:)
294
299
  params = {
295
300
  options: prepare_record_har_options(
296
301
  record_har_path: har,
297
- record_har_content: "attach",
298
- record_har_mode: "minimal",
302
+ record_har_content: updateContent || 'attach',
303
+ record_har_mode: updateMode || 'minimal',
299
304
  record_har_url_filter: url,
300
305
  )
301
306
  }
@@ -306,9 +311,9 @@ module Playwright
306
311
  @har_recorders[har_id] = { path: har, content: 'attach' }
307
312
  end
308
313
 
309
- def route_from_har(har, notFound: nil, update: nil, url: nil)
314
+ def route_from_har(har, notFound: nil, update: nil, updateContent: nil, updateMode: nil, url: nil)
310
315
  if update
311
- record_into_har(har, nil, notFound: notFound, url: url)
316
+ record_into_har(har, nil, notFound: notFound, url: url, updateContent: updateContent, updateMode: updateMode)
312
317
  return
313
318
  end
314
319
 
@@ -13,7 +13,7 @@ module Playwright
13
13
  def launch(options, &block)
14
14
  resp = @channel.send_message_to_server('launch', options.compact)
15
15
  browser = ChannelOwners::Browser.from(resp)
16
- browser.send(:update_browser_type, self)
16
+ did_launch_browser(browser)
17
17
  return browser unless block
18
18
 
19
19
  begin
@@ -30,8 +30,7 @@ module Playwright
30
30
 
31
31
  resp = @channel.send_message_to_server('launchPersistentContext', params.compact)
32
32
  context = ChannelOwners::Browser.from(resp)
33
- context.options = params
34
- context.send(:update_browser_type, self)
33
+ did_create_context(context, params, params)
35
34
  return context unless block
36
35
 
37
36
  begin
@@ -57,11 +56,11 @@ module Playwright
57
56
 
58
57
  result = @channel.send_message_to_server_result('connectOverCDP', params)
59
58
  browser = ChannelOwners::Browser.from(result['browser'])
60
- browser.send(:update_browser_type, self)
59
+ did_launch_browser(browser)
61
60
 
62
61
  if result['defaultContext']
63
- context = ChannelOwners::BrowserContext.from(result['defaultContext'])
64
- browser.send(:add_context, context)
62
+ default_context = ChannelOwners::BrowserContext.from(result['defaultContext'])
63
+ did_create_context(default_context)
65
64
  end
66
65
 
67
66
  if block
@@ -74,5 +73,13 @@ module Playwright
74
73
  browser
75
74
  end
76
75
  end
76
+
77
+ private def did_create_context(context, context_options = {}, browser_options = {})
78
+ context.send(:update_options, context_options: context_options, browser_options: browser_options)
79
+ end
80
+
81
+ private def did_launch_browser(browser)
82
+ browser.send(:update_browser_type, self)
83
+ end
77
84
  end
78
85
  end
@@ -418,8 +418,20 @@ module Playwright
418
418
  nil
419
419
  end
420
420
 
421
- def locator(selector, hasText: nil, has: nil)
422
- LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector, hasText: hasText, has: has)
421
+ def locator(
422
+ selector,
423
+ has: nil,
424
+ hasNot: nil,
425
+ hasNotText: nil,
426
+ hasText: nil)
427
+ LocatorImpl.new(
428
+ frame: self,
429
+ timeout_settings: @page.send(:timeout_settings),
430
+ selector: selector,
431
+ has: has,
432
+ hasNot: hasNot,
433
+ hasNotText: hasNotText,
434
+ hasText: hasText)
423
435
  end
424
436
 
425
437
  def frame_locator(selector)
@@ -1,12 +1,7 @@
1
1
  module Playwright
2
2
  define_channel_owner :LocalUtils do
3
3
  # @param zip_file [String]
4
- # @param name_value_array [Array<Hash<{name: string, value: string}>>]
5
- def zip(zip_file, name_value_array)
6
- params = {
7
- zipFile: zip_file,
8
- entries: name_value_array,
9
- }
4
+ def zip(params)
10
5
  @channel.send_message_to_server('zip', params)
11
6
  nil
12
7
  end
@@ -39,5 +34,22 @@ module Playwright
39
34
  def har_unzip(zip_file, har_file)
40
35
  @channel.send_message_to_server('harUnzip', zipFile: zip_file, harFile: har_file)
41
36
  end
37
+
38
+ def tracing_started(traces_dir, trace_name)
39
+ params = {
40
+ tracesDir: traces_dir,
41
+ traceName: trace_name,
42
+ }.compact
43
+ @channel.send_message_to_server('tracingStarted', params)
44
+ end
45
+
46
+ def tracing_discarded(stacks_id)
47
+ @channel.send_message_to_server('traceDiscarded', stacksId: stacks_id)
48
+ end
49
+
50
+ def add_stack_to_tracing_no_reply(id, stack)
51
+ @channel.async_send_message_to_server('addStackToTracingNoReply', callData: { id: id, stack: stack })
52
+ nil
53
+ end
42
54
  end
43
55
  end
@@ -417,9 +417,9 @@ module Playwright
417
417
  update_interception_patterns
418
418
  end
419
419
 
420
- def route_from_har(har, notFound: nil, update: nil, url: nil)
420
+ def route_from_har(har, notFound: nil, update: nil, url: nil, updateContent: nil, updateMode: nil)
421
421
  if update
422
- @browser_context.send(:record_into_har, har, self, notFound: notFound, url: url)
422
+ @browser_context.send(:record_into_har, har, self, notFound: notFound, url: url, updateContent: updateContent, updateMode: updateMode)
423
423
  return
424
424
  end
425
425
 
@@ -614,8 +614,18 @@ module Playwright
614
614
  timeout: timeout)
615
615
  end
616
616
 
617
- def locator(selector, hasText: nil, has: nil)
618
- @main_frame.locator(selector, hasText: hasText, has: has)
617
+ def locator(
618
+ selector,
619
+ has: nil,
620
+ hasNot: nil,
621
+ hasNotText: nil,
622
+ hasText: nil)
623
+ @main_frame.locator(
624
+ selector,
625
+ has: has,
626
+ hasNot: hasNot,
627
+ hasNotText: hasNotText,
628
+ hasText: hasText)
619
629
  end
620
630
 
621
631
  def frame_locator(selector)
@@ -19,6 +19,7 @@ module Playwright
19
19
  responseEnd: -1,
20
20
  }
21
21
  @fallback_overrides = {}
22
+ @url = @initializer['url']
22
23
  end
23
24
 
24
25
  private def fallback_overrides
@@ -35,7 +36,11 @@ module Playwright
35
36
  end
36
37
 
37
38
  def url
38
- @fallback_overrides[:url] || @initializer['url']
39
+ @fallback_overrides[:url] || @url
40
+ end
41
+
42
+ private def internal_url
43
+ @url
39
44
  end
40
45
 
41
46
  def resource_type
@@ -21,7 +21,7 @@ module Playwright
21
21
 
22
22
  def abort(errorCode: nil)
23
23
  handling_with_result(true) do
24
- params = { errorCode: errorCode }.compact
24
+ params = { requestUrl: request.send(:internal_url), errorCode: errorCode }.compact
25
25
  # TODO _race_with_page_close
26
26
  @channel.async_send_message_to_server('abort', params)
27
27
  end
@@ -91,6 +91,7 @@ module Playwright
91
91
 
92
92
  params[:status] = option_status || 200
93
93
  params[:headers] = HttpHeaders.new(param_headers).as_serialized
94
+ params[:requestUrl] = request.send(:internal_url)
94
95
 
95
96
  @channel.async_send_message_to_server('fulfill', params)
96
97
  end
@@ -109,7 +110,7 @@ module Playwright
109
110
  end
110
111
  end
111
112
 
112
- def fetch(headers: nil, method: nil, postData: nil, url: nil, maxRedirects: nil)
113
+ def fetch(headers: nil, method: nil, postData: nil, url: nil, maxRedirects: nil, timeout: nil)
113
114
  api_request_context = request.frame.page.context.request
114
115
  api_request_context.send(:_inner_fetch,
115
116
  request,
@@ -118,6 +119,7 @@ module Playwright
118
119
  method: method,
119
120
  data: postData,
120
121
  maxRedirects: maxRedirects,
122
+ timeout: timeout,
121
123
  )
122
124
  end
123
125
 
@@ -152,6 +154,7 @@ module Playwright
152
154
  if post_data_for_wire
153
155
  params[:postData] = post_data_for_wire
154
156
  end
157
+ params[:requestUrl] = request.send(:internal_url)
155
158
 
156
159
  # TODO _race_with_page_close
157
160
  @channel.async_send_message_to_server('continue', params)
@@ -7,12 +7,23 @@ module Playwright
7
7
  snapshots: snapshots,
8
8
  sources: sources,
9
9
  }.compact
10
+ @include_sources = params[:sources] || false
10
11
  @channel.send_message_to_server('tracingStart', params)
11
- @channel.send_message_to_server('tracingStartChunk', { title: title }.compact)
12
+ trace_name = @channel.send_message_to_server('tracingStartChunk', { title: title, name: name }.compact)
13
+ start_collecting_stacks(trace_name)
12
14
  end
13
15
 
14
- def start_chunk(title: nil)
15
- @channel.send_message_to_server('tracingStartChunk', { title: title }.compact)
16
+ def start_chunk(title: nil, name: nil)
17
+ trace_name = @channel.send_message_to_server('tracingStartChunk', { title: title, name: name }.compact)
18
+ start_collecting_stacks(trace_name)
19
+ end
20
+
21
+ private def start_collecting_stacks(trace_name)
22
+ unless @is_tracing
23
+ @is_tracing = true
24
+ @connection.set_in_tracing(true)
25
+ end
26
+ @stacks_id = @connection.local_utils.tracing_started(@traces_dir, trace_name)
16
27
  end
17
28
 
18
29
  def stop_chunk(path: nil)
@@ -25,26 +36,61 @@ module Playwright
25
36
  end
26
37
 
27
38
  private def do_stop_chunk(file_path:)
28
- mode = 'doNotSave'
29
- if file_path
30
- if @connection.remote?
31
- mode = 'compressTrace'
32
- else
33
- mode = 'compressTraceAndSources'
39
+ if @is_tracing
40
+ @is_tracing = false
41
+ @connection.set_in_tracing(false)
42
+ end
43
+
44
+ unless file_path
45
+ # Not interested in any artifacts
46
+ @channel.send_message_to_server('tracingStopChunk', mode: 'discard')
47
+ if @stacks_id
48
+ @connection.local_utils.trace_discarded(@stacks_id)
34
49
  end
50
+
51
+ return
35
52
  end
36
53
 
37
- result = @channel.send_message_to_server_result('tracingStopChunk', mode: mode)
38
- return unless file_path # Not interested in artifacts.
39
- return unless result['artifact'] # The artifact may be missing if the browser closed while stopping tracing.
54
+ unless @connection.remote?
55
+ result = @channel.send_message_to_server_result('tracingStopChunk', mode: 'entries')
56
+ @connection.local_utils.zip(
57
+ zipFile: file_path,
58
+ entries: result['entries'],
59
+ stacksId: @stacks_id,
60
+ mode: 'write',
61
+ includeSources: @include_sources,
62
+ )
63
+
64
+ return
65
+ end
40
66
 
67
+
68
+ result = @channel.send_message_to_server_result('tracingStopChunk', mode: 'archive')
69
+ # The artifact may be missing if the browser closed while stopping tracing.
70
+ unless result['artifact']
71
+ if @stacks_id
72
+ @connection.local_utils.trace_discarded(@stacks_id)
73
+ end
74
+
75
+ return
76
+ end
77
+
78
+ # Save trace to the final local file.
41
79
  artifact = ChannelOwners::Artifact.from(result['artifact'])
42
80
  artifact.save_as(file_path)
43
81
  artifact.delete
44
82
 
45
- # // Add local sources to the remote trace if necessary.
46
- # if (result.sourceEntries?.length)
47
- # await this._context._localUtils.zip(filePath, result.sourceEntries);
83
+ @connection.local_utils.zip(
84
+ zipFile: file_path,
85
+ entries: [],
86
+ stacksId: @stacks_id,
87
+ mode: 'append',
88
+ includeSources: @include_sources,
89
+ )
90
+ end
91
+
92
+ private def update_traces_dir(traces_dir)
93
+ @traces_dir = traces_dir
48
94
  end
49
95
  end
50
96
  end