playwright-ruby-client 1.22.0 → 1.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/browser.md +16 -0
  3. data/documentation/docs/api/browser_context.md +15 -2
  4. data/documentation/docs/api/browser_type.md +4 -0
  5. data/documentation/docs/api/element_handle.md +0 -5
  6. data/documentation/docs/api/experimental/android_device.md +4 -0
  7. data/documentation/docs/api/locator.md +13 -6
  8. data/documentation/docs/api/page.md +14 -1
  9. data/documentation/docs/api/request.md +3 -1
  10. data/documentation/docs/api/response.md +12 -1
  11. data/documentation/docs/api/route.md +65 -0
  12. data/documentation/docs/include/api_coverage.md +5 -3
  13. data/lib/playwright/channel.rb +1 -3
  14. data/lib/playwright/channel_owners/browser.rb +13 -0
  15. data/lib/playwright/channel_owners/browser_context.rb +81 -13
  16. data/lib/playwright/channel_owners/browser_type.rb +4 -0
  17. data/lib/playwright/channel_owners/frame.rb +16 -2
  18. data/lib/playwright/channel_owners/local_utils.rb +29 -0
  19. data/lib/playwright/channel_owners/page.rb +43 -15
  20. data/lib/playwright/channel_owners/request.rb +31 -6
  21. data/lib/playwright/channel_owners/response.rb +6 -0
  22. data/lib/playwright/channel_owners/route.rb +104 -45
  23. data/lib/playwright/connection.rb +6 -1
  24. data/lib/playwright/har_router.rb +82 -0
  25. data/lib/playwright/http_headers.rb +1 -1
  26. data/lib/playwright/javascript/regex.rb +23 -0
  27. data/lib/playwright/javascript/value_serializer.rb +3 -4
  28. data/lib/playwright/javascript.rb +1 -0
  29. data/lib/playwright/locator_impl.rb +3 -5
  30. data/lib/playwright/route_handler.rb +2 -6
  31. data/lib/playwright/utils.rb +31 -6
  32. data/lib/playwright/version.rb +2 -2
  33. data/lib/playwright.rb +2 -0
  34. data/lib/playwright_api/android_device.rb +5 -1
  35. data/lib/playwright_api/browser.rb +15 -2
  36. data/lib/playwright_api/browser_context.rb +16 -6
  37. data/lib/playwright_api/browser_type.rb +5 -1
  38. data/lib/playwright_api/element_handle.rb +0 -11
  39. data/lib/playwright_api/locator.rb +11 -12
  40. data/lib/playwright_api/page.rb +16 -6
  41. data/lib/playwright_api/request.rb +8 -1
  42. data/lib/playwright_api/response.rb +14 -1
  43. data/lib/playwright_api/route.rb +61 -2
  44. data/lib/playwright_api/worker.rb +4 -4
  45. metadata +5 -4
  46. data/lib/playwright_api/local_utils.rb +0 -9
@@ -39,7 +39,6 @@ module Playwright
39
39
  })
40
40
  @channel.on('crash', ->(_) { emit(Events::Page::Crash) })
41
41
  @channel.on('dialog', method(:on_dialog))
42
- @channel.on('domcontentloaded', ->(_) { emit(Events::Page::DOMContentLoaded) })
43
42
  @channel.on('download', method(:on_download))
44
43
  @channel.on('fileChooser', ->(params) {
45
44
  chooser = FileChooserImpl.new(
@@ -54,12 +53,15 @@ module Playwright
54
53
  @channel.on('frameDetached', ->(params) {
55
54
  on_frame_detached(ChannelOwners::Frame.from(params['frame']))
56
55
  })
57
- @channel.on('load', ->(_) { emit(Events::Page::Load) })
58
56
  @channel.on('pageError', ->(params) {
59
57
  emit(Events::Page::PageError, Error.parse(params['error']['error']))
60
58
  })
61
59
  @channel.on('route', ->(params) {
62
- on_route(ChannelOwners::Route.from(params['route']), ChannelOwners::Request.from(params['request']))
60
+ Concurrent::Promises.future {
61
+ on_route(ChannelOwners::Route.from(params['route']), ChannelOwners::Request.from(params['request']))
62
+ }.rescue do |err|
63
+ puts err, err.backtrace
64
+ end
63
65
  })
64
66
  @channel.on('video', method(:on_video))
65
67
  @channel.on('webSocket', ->(params) {
@@ -98,18 +100,26 @@ module Playwright
98
100
  wrapped_route = PlaywrightApi.wrap(route)
99
101
  wrapped_request = PlaywrightApi.wrap(request)
100
102
 
101
- handler_entry = @routes.find do |entry|
102
- entry.match?(request.url)
103
+ handled = @routes.any? do |handler_entry|
104
+ next false unless handler_entry.match?(request.url)
105
+
106
+ promise = Concurrent::Promises.resolvable_future
107
+ route.send(:set_handling_future, promise)
108
+
109
+ promise_handled = Concurrent::Promises.zip(
110
+ promise,
111
+ handler_entry.async_handle(wrapped_route, wrapped_request)
112
+ ).value!.first
113
+
114
+ promise_handled
103
115
  end
104
116
 
105
- if handler_entry
106
- handler_entry.async_handle(wrapped_route, wrapped_request)
117
+ @routes.reject!(&:expired?)
118
+ if @routes.count == 0
119
+ @channel.async_send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
120
+ end
107
121
 
108
- @routes.reject!(&:expired?)
109
- if @routes.count == 0
110
- @channel.async_send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
111
- end
112
- else
122
+ unless handled
113
123
  @browser_context.send(:on_route, route, request)
114
124
  end
115
125
  end
@@ -407,6 +417,21 @@ module Playwright
407
417
  end
408
418
  end
409
419
 
420
+ def route_from_har(har, notFound: nil, update: nil, url: nil)
421
+ if update
422
+ @browser_context.send(:record_into_har, har, self, notFound: notFound, url: url)
423
+ return
424
+ end
425
+
426
+ router = HarRouter.create(
427
+ @connection.local_utils,
428
+ har.to_s,
429
+ notFound || "abort",
430
+ url_match: url,
431
+ )
432
+ router.add_page_route(self)
433
+ end
434
+
410
435
  def screenshot(
411
436
  animations: nil,
412
437
  caret: nil,
@@ -451,9 +476,12 @@ module Playwright
451
476
  end
452
477
 
453
478
  def close(runBeforeUnload: nil)
454
- options = { runBeforeUnload: runBeforeUnload }.compact
455
- @channel.send_message_to_server('close', options)
456
- @owned_context&.close
479
+ if @owned_context
480
+ @owned_context.close
481
+ else
482
+ options = { runBeforeUnload: runBeforeUnload }.compact
483
+ @channel.send_message_to_server('close', options)
484
+ end
457
485
  nil
458
486
  rescue => err
459
487
  raise unless safe_close_error?(err)
@@ -18,10 +18,24 @@ module Playwright
18
18
  responseStart: -1,
19
19
  responseEnd: -1,
20
20
  }
21
+ @fallback_overrides = {}
22
+ end
23
+
24
+ private def fallback_overrides
25
+ @fallback_overrides
26
+ end
27
+
28
+ def apply_fallback_overrides(overrides)
29
+ allowed_key = %i[url method headers postData]
30
+ overrides.each do |key, value|
31
+ raise ArgumentError.new("invalid key: #{key}") unless allowed_key.include?(key)
32
+ @fallback_overrides[key] = value
33
+ end
34
+ @fallback_overrides
21
35
  end
22
36
 
23
37
  def url
24
- @initializer['url']
38
+ @fallback_overrides[:url] || @initializer['url']
25
39
  end
26
40
 
27
41
  def resource_type
@@ -29,7 +43,7 @@ module Playwright
29
43
  end
30
44
 
31
45
  def method
32
- @initializer['method']
46
+ @fallback_overrides[:method] || @initializer['method']
33
47
  end
34
48
 
35
49
  def post_data
@@ -51,8 +65,11 @@ module Playwright
51
65
  end
52
66
 
53
67
  def post_data_buffer
54
- base64_content = @initializer['postData']
55
- if base64_content
68
+ if (override = @fallback_overrides[:postData])
69
+ return override
70
+ end
71
+
72
+ if (base64_content = @initializer['postData'])
56
73
  Base64.strict_decode64(base64_content)
57
74
  else
58
75
  nil
@@ -79,12 +96,20 @@ module Playwright
79
96
  attr_reader :redirected_from, :redirected_to, :timing
80
97
 
81
98
  def headers
82
- @provisional_headers.headers
99
+ if (override = @fallback_overrides[:headers])
100
+ RawHeaders.new(HttpHeaders.new(override).as_serialized).headers
101
+ else
102
+ @provisional_headers.headers
103
+ end
83
104
  end
84
105
 
85
106
  # @return [RawHeaders|nil]
86
107
  private def actual_headers
87
- @actual_headers ||= raw_request_headers
108
+ if (override = @fallback_overrides[:headers])
109
+ RawHeaders.new(HttpHeaders.new(override).as_serialized)
110
+ else
111
+ @actual_headers ||= raw_request_headers
112
+ end
88
113
  end
89
114
 
90
115
  private def raw_request_headers
@@ -52,6 +52,12 @@ module Playwright
52
52
  RawHeaders.new(@channel.send_message_to_server('rawResponseHeaders'))
53
53
  end
54
54
 
55
+ def from_service_worker
56
+ @initializer['fromServiceWorker']
57
+ end
58
+
59
+ alias_method :from_service_worker?, :from_service_worker
60
+
55
61
  def all_headers
56
62
  actual_headers.headers
57
63
  end
@@ -3,13 +3,28 @@ require 'mime/types'
3
3
 
4
4
  module Playwright
5
5
  define_channel_owner :Route do
6
+ private def set_handling_future(future)
7
+ @handling_future = future
8
+ end
9
+
10
+ private def handling_with_result(done, &block)
11
+ chain = @handling_future
12
+ raise 'Route is already handled!' unless chain
13
+ block.call
14
+ @handling_future = nil
15
+ chain.fulfill(done)
16
+ end
17
+
6
18
  def request
7
19
  ChannelOwners::Request.from(@initializer['request'])
8
20
  end
9
21
 
10
22
  def abort(errorCode: nil)
11
- params = { errorCode: errorCode }.compact
12
- @channel.async_send_message_to_server('abort', params)
23
+ handling_with_result(true) do
24
+ params = { errorCode: errorCode }.compact
25
+ # TODO _race_with_page_close
26
+ @channel.async_send_message_to_server('abort', params)
27
+ end
13
28
  end
14
29
 
15
30
  def fulfill(
@@ -19,69 +34,113 @@ module Playwright
19
34
  path: nil,
20
35
  status: nil,
21
36
  response: nil)
22
- params = {
23
- contentType: contentType,
24
- status: status,
25
- }.compact
26
- option_body = body
37
+ handling_with_result(true) do
38
+ params = {
39
+ contentType: contentType,
40
+ status: status,
41
+ }.compact
42
+ option_body = body
27
43
 
28
- if response
29
- params[:status] ||= response.status
30
- params[:headers] ||= response.headers
44
+ if response
45
+ params[:status] ||= response.status
46
+ params[:headers] ||= response.headers
31
47
 
32
- if !body && !path && response.is_a?(APIResponse)
33
- if response.send(:_request).send(:same_connection?, self)
34
- params[:fetchResponseUid] = response.send(:fetch_uid)
35
- else
36
- option_body = response.body
48
+ if !body && !path && response.is_a?(APIResponse)
49
+ if response.send(:_request).send(:same_connection?, self)
50
+ params[:fetchResponseUid] = response.send(:fetch_uid)
51
+ else
52
+ option_body = response.body
53
+ end
37
54
  end
38
55
  end
39
- end
40
56
 
41
- content =
42
- if option_body
43
- option_body
57
+ content =
58
+ if option_body
59
+ option_body
60
+ elsif path
61
+ File.read(path)
62
+ else
63
+ nil
64
+ end
65
+
66
+ param_headers = headers || {}
67
+ if contentType
68
+ param_headers['content-type'] = contentType
44
69
  elsif path
45
- File.read(path)
46
- else
47
- nil
70
+ param_headers['content-type'] = mime_type_for(path)
48
71
  end
49
72
 
50
- param_headers = headers || {}
51
- if contentType
52
- param_headers['content-type'] = contentType
53
- elsif path
54
- param_headers['content-type'] = mime_type_for(path)
55
- end
56
-
57
- if content
58
- if content.is_a?(String)
59
- params[:body] = content
60
- params[:isBase64] = false
61
- else
62
- params[:body] = Base64.strict_encode64(content)
63
- params[:isBase64] = true
73
+ if content
74
+ if content.is_a?(String)
75
+ params[:body] = content
76
+ params[:isBase64] = false
77
+ else
78
+ params[:body] = Base64.strict_encode64(content)
79
+ params[:isBase64] = true
80
+ end
81
+ param_headers['content-length'] ||= content.length.to_s
64
82
  end
65
- param_headers['content-length'] ||= content.length.to_s
83
+
84
+ params[:headers] = HttpHeaders.new(param_headers).as_serialized
85
+
86
+ @channel.async_send_message_to_server('fulfill', params)
66
87
  end
88
+ end
67
89
 
68
- params[:headers] = HttpHeaders.new(param_headers).as_serialized
90
+ def fallback(headers: nil, method: nil, postData: nil, url: nil)
91
+ overrides = {
92
+ headers: headers,
93
+ method: method,
94
+ postData: postData,
95
+ url: url,
96
+ }.compact
69
97
 
70
- @channel.async_send_message_to_server('fulfill', params)
98
+ handling_with_result(false) do
99
+ request.apply_fallback_overrides(overrides)
100
+ end
71
101
  end
72
102
 
73
103
  def continue(headers: nil, method: nil, postData: nil, url: nil)
74
- overrides = { url: url, method: method }.compact
104
+ overrides = {
105
+ headers: headers,
106
+ method: method,
107
+ postData: postData,
108
+ url: url,
109
+ }.compact
75
110
 
76
- if headers
77
- overrides[:headers] = HttpHeaders.new(headers).as_serialized
111
+ handling_with_result(true) do
112
+ request.apply_fallback_overrides(overrides)
113
+ async_continue_route
78
114
  end
115
+ end
79
116
 
80
- if postData
81
- overrides[:postData] = Base64.strict_encode64(postData)
117
+ private def async_continue_route
118
+ post_data_for_wire =
119
+ if (post_data_from_overrides = request.send(:fallback_overrides)[:postData])
120
+ post_data_for_wire = Base64.strict_encode64(post_data_from_overrides)
121
+ else
122
+ nil
123
+ end
124
+
125
+ params = request.send(:fallback_overrides).dup
126
+
127
+ if params[:headers]
128
+ params[:headers] = HttpHeaders.new(params[:headers]).as_serialized
129
+ end
130
+
131
+ if post_data_for_wire
132
+ params[:postData] = post_data_for_wire
82
133
  end
83
134
 
84
- @channel.async_send_message_to_server('continue', overrides)
135
+ # TODO _race_with_page_close
136
+ @channel.async_send_message_to_server('continue', params)
137
+ end
138
+
139
+ def redirect_navigation_request(url)
140
+ handling_with_result(true) do
141
+ # TODO _race_with_page_close
142
+ @channel.send_message_to_server('redirectNavigationRequest', { url: url })
143
+ end
85
144
  end
86
145
 
87
146
  private def mime_type_for(filepath)
@@ -24,6 +24,8 @@ module Playwright
24
24
  @remote = false
25
25
  end
26
26
 
27
+ attr_reader :local_utils
28
+
27
29
  def mark_as_remote
28
30
  @remote = true
29
31
  end
@@ -127,12 +129,15 @@ module Playwright
127
129
  params = msg['params']
128
130
 
129
131
  if method == "__create__"
130
- create_remote_object(
132
+ remote_object = create_remote_object(
131
133
  parent_guid: guid,
132
134
  type: params["type"],
133
135
  guid: params["guid"],
134
136
  initializer: params["initializer"],
135
137
  )
138
+ if remote_object.is_a?(ChannelOwners::LocalUtils)
139
+ @local_utils = remote_object
140
+ end
136
141
  return
137
142
  end
138
143
 
@@ -0,0 +1,82 @@
1
+ module Playwright
2
+ class HarRouter
3
+ # @param local_utils [LocalUtils]
4
+ # @param file [String]
5
+ # @param not_found_action [String] 'abort' or 'fallback'
6
+ # @param url_match [String||Regexp|nil]
7
+ def self.create(local_utils, file, not_found_action, url_match: nil)
8
+ har_id = local_utils.har_open(file)
9
+
10
+ new(
11
+ local_utils: local_utils,
12
+ har_id: har_id,
13
+ not_found_action: not_found_action,
14
+ url_match: url_match,
15
+ )
16
+ end
17
+
18
+ # @param local_utils [LocalUtils]
19
+ # @param har_id [String]
20
+ # @param not_found_action [String] 'abort' or 'fallback'
21
+ # @param url_match [String||Regexp|nil]
22
+ def initialize(local_utils:, har_id:, not_found_action:, url_match: nil)
23
+ unless ['abort', 'fallback'].include?(not_found_action)
24
+ raise ArgumentError.new("not_found_action must be either 'abort' or 'fallback'. '#{not_found_action}' is specified.")
25
+ end
26
+
27
+ @local_utils = local_utils
28
+ @har_id = har_id
29
+ @not_found_action = not_found_action
30
+ @url_match = url_match || '**/*'
31
+ @debug = ENV['DEBUG'].to_s == 'true' || ENV['DEBUG'].to_s == '1'
32
+ end
33
+
34
+ private def handle(route, request)
35
+ response = @local_utils.har_lookup(
36
+ har_id: @har_id,
37
+ url: request.url,
38
+ method: request.method,
39
+ headers: request.headers_array,
40
+ post_data: request.post_data_buffer,
41
+ is_navigation_request: request.navigation_request?,
42
+ )
43
+ case response['action']
44
+ when 'redirect'
45
+ redirect_url = response['redirectURL']
46
+ puts "pw:api HAR: #{request.url} redirected to #{redirect_url}" if @debug
47
+ route.redirect_navigation_request(redirect_url)
48
+ when 'fulfill'
49
+ route.fulfill(
50
+ status: response['status'],
51
+ headers: response['headers'].map { |header| [header['name'], header['value']] }.to_h,
52
+ body: Base64.strict_decode64(response['body']),
53
+ )
54
+ else
55
+ # Report the error, but fall through to the default handler.
56
+ if response['action'] == 'error'
57
+ puts "pw:api HAR: #{response['message']} redirected to #{redirect_url}" if @debug
58
+ end
59
+
60
+ if @not_found_action == 'abort'
61
+ route.abort
62
+ else
63
+ route.fallback
64
+ end
65
+ end
66
+ end
67
+
68
+ def add_context_route(context)
69
+ context.route(@url_match, method(:handle))
70
+ context.once(Events::BrowserContext::Close, method(:dispose))
71
+ end
72
+
73
+ def add_page_route(page)
74
+ page.route(@url_match, method(:handle))
75
+ page.once(Events::Page::Close, method(:dispose))
76
+ end
77
+
78
+ def dispose
79
+ @local_utils.async_har_close(@har_id)
80
+ end
81
+ end
82
+ end
@@ -7,7 +7,7 @@ module Playwright
7
7
 
8
8
  def as_serialized
9
9
  @headers.map do |key, value|
10
- { name: key, value: value }
10
+ { 'name' => key, 'value' => value }
11
11
  end
12
12
  end
13
13
  end
@@ -0,0 +1,23 @@
1
+ module Playwright
2
+ module JavaScript
3
+ class Regex
4
+ def initialize(regexp)
5
+ unless regexp.is_a?(Regexp)
6
+ raise ArgumentError("Argument must be a Regexp: #{regexp} (#{regexp.class})")
7
+ end
8
+
9
+ @source = regexp.source
10
+ @flag = flag_for(regexp)
11
+ end
12
+
13
+ attr_reader :source, :flag
14
+
15
+ private def flag_for(regexp)
16
+ flags = []
17
+ flags << 'ms' if (regexp.options & Regexp::MULTILINE) != 0
18
+ flags << 'i' if (regexp.options & Regexp::IGNORECASE) != 0
19
+ flags.join('')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,4 +1,5 @@
1
1
  require_relative './visitor_info'
2
+ require_relative './regex'
2
3
 
3
4
  module Playwright
4
5
  module JavaScript
@@ -40,10 +41,8 @@ module Playwright
40
41
  require 'time'
41
42
  { d: value.utc.iso8601 }
42
43
  when Regexp
43
- flags = []
44
- flags << 'ms' if (value.options & Regexp::MULTILINE) != 0
45
- flags << 'i' if (value.options & Regexp::IGNORECASE) != 0
46
- { r: { p: value.source, f: flags.join('') } }
44
+ regex_value = Regex.new(value)
45
+ { r: { p: regex_value.source, f: regex_value.flag } }
47
46
  when -> (value) { @visited.ref(value) }
48
47
  { ref: @visited.ref(value) }
49
48
  when Array
@@ -1,3 +1,4 @@
1
1
  require_relative './javascript/expression'
2
2
  require_relative './javascript/value_parser'
3
3
  require_relative './javascript/value_serializer'
4
+ require_relative './javascript/regex'
@@ -31,11 +31,9 @@ module Playwright
31
31
 
32
32
  case hasText
33
33
  when Regexp
34
- source = EscapeWithQuotes.new(hasText.source, '"')
35
- flags = []
36
- flags << 'ms' if (hasText.options & Regexp::MULTILINE) != 0
37
- flags << 'i' if (hasText.options & Regexp::IGNORECASE) != 0
38
- selector_scopes << ":scope:text-matches(#{source}, \"#{flags.join('')}\")"
34
+ regex = JavaScript::Regex.new(hasText)
35
+ source = EscapeWithQuotes.new(regex.source, '"')
36
+ selector_scopes << ":scope:text-matches(#{source}, \"#{regex.flag}\")"
39
37
  when String
40
38
  text = EscapeWithQuotes.new(hasText, '"')
41
39
  selector_scopes << ":scope:has-text(#{text})"
@@ -50,12 +50,8 @@ module Playwright
50
50
  def async_handle(route, request)
51
51
  @counter.increment
52
52
 
53
- Concurrent::Promises.future do
54
- begin
55
- @handler.call(route, request)
56
- rescue => err
57
- puts err, err.backtrace
58
- end
53
+ Concurrent::Promises.future { @handler.call(route, request) }.rescue do |err|
54
+ puts err, err.backtrace
59
55
  end
60
56
  end
61
57
 
@@ -1,6 +1,36 @@
1
1
  module Playwright
2
2
  module Utils
3
3
  module PrepareBrowserContextOptions
4
+ private def prepare_record_har_options(params)
5
+ out_params = {
6
+ path: params.delete(:record_har_path)
7
+ }
8
+ if params[:record_har_url_filter]
9
+ opt = params.delete(:record_har_url_filter)
10
+ if opt.is_a?(Regexp)
11
+ regex = ::Playwright::JavaScript::Regex.new(opt)
12
+ out_params[:urlRegexSource] = regex.source
13
+ out_params[:urlRegexFlags] = regex.flag
14
+ elsif opt.is_a?(String)
15
+ out_params[:urlGlob] = opt
16
+ end
17
+ end
18
+ if params[:record_har_mode]
19
+ out_params[:mode] = params.delete(:record_har_mode)
20
+ end
21
+ if params[:record_har_content]
22
+ out_params[:content] = params.delete(:record_har_content)
23
+ end
24
+ if params[:record_har_omit_content]
25
+ old_api_omit_content = params.delete(:record_har_omit_content)
26
+ if old_api_omit_content
27
+ out_params[:content] ||= 'omit'
28
+ end
29
+ end
30
+
31
+ out_params
32
+ end
33
+
4
34
  # @see https://github.com/microsoft/playwright/blob/5a2cfdbd47ed3c3deff77bb73e5fac34241f649d/src/client/browserContext.ts#L265
5
35
  private def prepare_browser_context_options(params)
6
36
  if params[:noViewport] == 0
@@ -11,12 +41,7 @@ module Playwright
11
41
  params[:extraHTTPHeaders] = ::Playwright::HttpHeaders.new(params[:extraHTTPHeaders]).as_serialized
12
42
  end
13
43
  if params[:record_har_path]
14
- params[:recordHar] = {
15
- path: params.delete(:record_har_path)
16
- }
17
- if params[:record_har_omit_content]
18
- params[:recordHar][:omitContent] = params.delete(:record_har_omit_content)
19
- end
44
+ params[:recordHar] = prepare_record_har_options(params)
20
45
  end
21
46
  if params[:record_video_dir]
22
47
  params[:recordVideo] = {
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '1.22.0'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.22.1'
4
+ VERSION = '1.23.0'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.23.4'
6
6
  end
data/lib/playwright.rb CHANGED
@@ -20,6 +20,7 @@ require 'playwright/channel_owner'
20
20
  require 'playwright/http_headers'
21
21
  require 'playwright/input_files'
22
22
  require 'playwright/connection'
23
+ require 'playwright/har_router'
23
24
  require 'playwright/raw_headers'
24
25
  require 'playwright/route_handler'
25
26
  require 'playwright/select_option_values'
@@ -143,6 +144,7 @@ module Playwright
143
144
  playwright = connection.initialize_playwright
144
145
  browser = playwright.send(:pre_launched_browser)
145
146
  browser.should_close_connection_on_close!
147
+ browser.send(:update_browser_type, browser.browser_type)
146
148
  Execution.new(connection, PlaywrightApi.wrap(playwright), PlaywrightApi.wrap(browser))
147
149
  rescue
148
150
  connection.stop
@@ -57,18 +57,22 @@ module Playwright
57
57
  noViewport: nil,
58
58
  offline: nil,
59
59
  permissions: nil,
60
+ record_har_content: nil,
61
+ record_har_mode: nil,
60
62
  record_har_omit_content: nil,
61
63
  record_har_path: nil,
64
+ record_har_url_filter: nil,
62
65
  record_video_dir: nil,
63
66
  record_video_size: nil,
64
67
  reducedMotion: nil,
65
68
  screen: nil,
69
+ serviceWorkers: nil,
66
70
  strictSelectors: nil,
67
71
  timezoneId: nil,
68
72
  userAgent: nil,
69
73
  viewport: nil,
70
74
  &block)
71
- wrap_impl(@impl.launch_browser(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), command: unwrap_impl(command), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), forcedColors: unwrap_impl(forcedColors), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), strictSelectors: unwrap_impl(strictSelectors), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
75
+ wrap_impl(@impl.launch_browser(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), command: unwrap_impl(command), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), forcedColors: unwrap_impl(forcedColors), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), record_har_content: unwrap_impl(record_har_content), record_har_mode: unwrap_impl(record_har_mode), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_har_url_filter: unwrap_impl(record_har_url_filter), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), serviceWorkers: unwrap_impl(serviceWorkers), strictSelectors: unwrap_impl(strictSelectors), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
72
76
  end
73
77
 
74
78
  # Performs a long tap on the widget defined by `selector`.