bidi2pdf 0.1.2 → 0.1.4

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -1
  3. data/CHANGELOG.md +36 -0
  4. data/cliff.toml +50 -26
  5. data/docker/Dockerfile.chromedriver +5 -0
  6. data/docker/entrypoint.sh +11 -1
  7. data/docker/nginx/default.conf +6 -0
  8. data/lib/bidi2pdf/bidi/add_headers_interceptor.rb +18 -21
  9. data/lib/bidi2pdf/bidi/auth_interceptor.rb +31 -38
  10. data/lib/bidi2pdf/bidi/browser_tab.rb +32 -52
  11. data/lib/bidi2pdf/bidi/client.rb +30 -57
  12. data/lib/bidi2pdf/bidi/command_manager.rb +50 -28
  13. data/lib/bidi2pdf/bidi/commands/add_intercept.rb +41 -0
  14. data/lib/bidi2pdf/bidi/commands/base.rb +73 -0
  15. data/lib/bidi2pdf/bidi/commands/browser_close.rb +15 -0
  16. data/lib/bidi2pdf/bidi/commands/browser_create_user_context.rb +15 -0
  17. data/lib/bidi2pdf/bidi/commands/browsing_context_close.rb +25 -0
  18. data/lib/bidi2pdf/bidi/commands/browsing_context_navigate.rb +31 -0
  19. data/lib/bidi2pdf/bidi/commands/browsing_context_print.rb +28 -0
  20. data/lib/bidi2pdf/bidi/commands/cancel_auth.rb +26 -0
  21. data/lib/bidi2pdf/bidi/commands/create_tab.rb +11 -0
  22. data/lib/bidi2pdf/bidi/commands/create_window.rb +32 -0
  23. data/lib/bidi2pdf/bidi/commands/get_user_contexts.rb +15 -0
  24. data/lib/bidi2pdf/bidi/commands/network_continue.rb +29 -0
  25. data/lib/bidi2pdf/bidi/commands/print_parameters_validator.rb +116 -0
  26. data/lib/bidi2pdf/bidi/commands/provide_credentials.rb +33 -0
  27. data/lib/bidi2pdf/bidi/commands/script_evaluate.rb +33 -0
  28. data/lib/bidi2pdf/bidi/commands/session_end.rb +15 -0
  29. data/lib/bidi2pdf/bidi/commands/session_status.rb +15 -0
  30. data/lib/bidi2pdf/bidi/commands/session_subscribe.rb +25 -0
  31. data/lib/bidi2pdf/bidi/commands/set_tab_cookie.rb +63 -0
  32. data/lib/bidi2pdf/bidi/commands/set_usercontext_cookie.rb +67 -0
  33. data/lib/bidi2pdf/bidi/commands.rb +27 -0
  34. data/lib/bidi2pdf/bidi/connection_manager.rb +16 -13
  35. data/lib/bidi2pdf/bidi/event_manager.rb +2 -0
  36. data/lib/bidi2pdf/bidi/interceptor.rb +75 -0
  37. data/lib/bidi2pdf/bidi/network_events.rb +0 -1
  38. data/lib/bidi2pdf/bidi/session.rb +141 -76
  39. data/lib/bidi2pdf/bidi/user_context.rb +25 -31
  40. data/lib/bidi2pdf/bidi/web_socket_dispatcher.rb +2 -0
  41. data/lib/bidi2pdf/chromedriver_manager.rb +23 -13
  42. data/lib/bidi2pdf/cli.rb +1 -3
  43. data/lib/bidi2pdf/launcher.rb +3 -1
  44. data/lib/bidi2pdf/version.rb +1 -1
  45. data/lib/bidi2pdf.rb +12 -0
  46. data/sig/bidi2pdf/bidi/command_manager.rbs +41 -0
  47. data/sig/bidi2pdf/bidi/commands/add_intercept.rbs +21 -0
  48. data/sig/bidi2pdf/bidi/commands/base.rbs +27 -0
  49. data/sig/bidi2pdf/bidi/commands/browser_close.rbs +9 -0
  50. data/sig/bidi2pdf/bidi/commands/browser_create_user_context.rbs +9 -0
  51. data/sig/bidi2pdf/bidi/commands/browsing_context_close.rbs +11 -0
  52. data/sig/bidi2pdf/bidi/commands/browsing_context_navigate.rbs +15 -0
  53. data/sig/bidi2pdf/bidi/commands/browsing_context_print.rbs +14 -0
  54. data/sig/bidi2pdf/bidi/commands/cancel_auth.rbs +11 -0
  55. data/sig/bidi2pdf/bidi/commands/create_tab.rbs +9 -0
  56. data/sig/bidi2pdf/bidi/commands/create_window.rbs +19 -0
  57. data/sig/bidi2pdf/bidi/commands/get_user_contexts.rbs +9 -0
  58. data/sig/bidi2pdf/bidi/commands/network_continue.rbs +19 -0
  59. data/sig/bidi2pdf/bidi/commands/print_parameters_validator.rbs +53 -0
  60. data/sig/bidi2pdf/bidi/commands/provide_credentials.rbs +15 -0
  61. data/sig/bidi2pdf/bidi/commands/script_evaluate.rbs +17 -0
  62. data/sig/bidi2pdf/bidi/commands/session_end.rbs +9 -0
  63. data/sig/bidi2pdf/bidi/commands/session_status.rbs +9 -0
  64. data/sig/bidi2pdf/bidi/commands/session_subscribe.rbs +15 -0
  65. data/sig/bidi2pdf/bidi/commands/set_tab_cookie.rbs +31 -0
  66. data/sig/bidi2pdf/bidi/commands/set_usercontext_cookie.rbs +27 -0
  67. data/sig/bidi2pdf/bidi/commands.rbs +6 -0
  68. data/sig/bidi2pdf/bidi/connection_manager.rbs +17 -0
  69. data/sig/bidi2pdf/bidi/interceptor.rbs +31 -0
  70. data/tasks/coverage.rake +16 -0
  71. metadata +65 -11
  72. data/lib/bidi2pdf/bidi/print_parameters_validator.rb +0 -114
  73. data/sig/bidi2pdf/bidi/print_parameters_validator.rbs +0 -44
  74. data/sig/bidi2pdf/chrome/chromedriver_downloader.rbs +0 -11
  75. data/sig/bidi2pdf/chrome/downloader_helper.rbs +0 -9
  76. data/sig/bidi2pdf/chrome/finder.rbs +0 -27
  77. data/sig/bidi2pdf/chrome/platform.rbs +0 -13
  78. data/sig/bidi2pdf/chrome/version_resolver.rbs +0 -19
@@ -4,10 +4,9 @@ require "json"
4
4
  require "websocket-client-simple"
5
5
 
6
6
  require_relative "web_socket_dispatcher"
7
- require_relative "add_headers_interceptor"
8
- require_relative "auth_interceptor"
9
7
  require_relative "command_manager"
10
8
  require_relative "connection_manager"
9
+ require_relative "commands"
11
10
 
12
11
  module Bidi2pdf
13
12
  module Bidi
@@ -18,29 +17,22 @@ module Bidi2pdf
18
17
 
19
18
  def initialize(ws_url)
20
19
  @ws_url = ws_url
21
- @id = 0
22
- @pending_responses = {}
23
-
24
- @connected = false
25
- @connection_mutex = Mutex.new
26
- @next_id_mutex = Mutex.new
27
- @connection_cv = ConditionVariable.new
28
-
29
20
  @started = false
21
+ @connection_manager = ConnectionManager.new(logger: Bidi2pdf.logger)
30
22
  end
31
23
 
32
24
  def start
33
25
  return @socket if started?
34
26
 
35
- @socket = WebSocket::Client::Simple.connect(ws_url)
27
+ WebSocket::Client::Simple.connect(ws_url) do |socket|
28
+ @socket = socket
29
+ @command_manager = CommandManager.new(@socket, logger: Bidi2pdf.logger)
36
30
 
37
- @connection_manager = ConnectionManager.new(logger: Bidi2pdf.logger)
38
- @command_manager = CommandManager.new(@socket, logger: Bidi2pdf.logger)
39
-
40
- dispatcher.on_open { @connection_manager.mark_connected }
41
- dispatcher.on_message { |data| handle_response_to_cmd(data) }
31
+ dispatcher.on_open { @connection_manager.mark_connected }
32
+ dispatcher.on_message { |data| handle_response_to_cmd(data) }
33
+ dispatcher.start_listening
34
+ end
42
35
 
43
- dispatcher.start_listening
44
36
  @started = true
45
37
 
46
38
  @socket
@@ -50,15 +42,23 @@ module Bidi2pdf
50
42
 
51
43
  def wait_until_open(timeout: Bidi2pdf.default_timeout)
52
44
  @connection_manager.wait_until_open(timeout: timeout)
45
+ rescue Bidi2pdf::WebsocketError => e
46
+ raise Bidi2pdf::WebsocketError, "Client#start must be called within #{timeout} sec." unless started?
47
+
48
+ raise e
53
49
  end
54
50
 
55
- def send_cmd(method, params = {})
56
- @command_manager.send_cmd(method, params)
51
+ def send_cmd(cmd)
52
+ raise Bidi2pdf::ClientError, "Client#start must be called before" unless started?
53
+
54
+ @command_manager.send_cmd(cmd)
57
55
  end
58
56
 
59
- def send_cmd_and_wait(method, params = {}, timeout: Bidi2pdf.default_timeout, &block)
60
- timed("Command #{method}") do
61
- @command_manager.send_cmd_and_wait(method, params, timeout: timeout, &block)
57
+ def send_cmd_and_wait(cmd, timeout: Bidi2pdf.default_timeout, &block)
58
+ raise Bidi2pdf::ClientError, "Client#start must be called before" unless started?
59
+
60
+ timed("Command #{cmd.inspect}") do
61
+ @command_manager.send_cmd_and_wait(cmd, timeout: timeout, &block)
62
62
  end
63
63
  end
64
64
 
@@ -72,7 +72,8 @@ module Bidi2pdf
72
72
 
73
73
  def on_event(*names, &block)
74
74
  names.each { |name| dispatcher.on_event(name, &block) }
75
- send_cmd("session.subscribe", { events: names }) if names.any?
75
+ cmd = Bidi2pdf::Bidi::Commands::SessionSubscribe.new(events: names)
76
+ send_cmd(cmd) if names.any?
76
77
  end
77
78
 
78
79
  def remove_message_listener(block) = dispatcher.remove_message_listener(block)
@@ -81,26 +82,13 @@ module Bidi2pdf
81
82
  names.each { |event_name| dispatcher.remove_event_listener(event_name, block) }
82
83
  end
83
84
 
84
- def add_headers_interceptor(context:, url_patterns:, headers:)
85
- add_interceptor(
86
- context: context,
87
- url_patterns: url_patterns,
88
- phase: "beforeRequestSent",
89
- event: "network.beforeRequestSent",
90
- interceptor_class: AddHeadersInterceptor,
91
- extra_args: { headers: headers }
92
- )
93
- end
85
+ def close
86
+ return unless @socket
94
87
 
95
- def add_auth_interceptor(context:, url_patterns:, username:, password:)
96
- add_interceptor(
97
- context: context,
98
- url_patterns: url_patterns,
99
- phase: "authRequired",
100
- event: "network.authRequired",
101
- interceptor_class: AuthInterceptor,
102
- extra_args: { username: username, password: password }
103
- )
88
+ Bidi2pdf.logger.debug "Closing WebSocket connection"
89
+ @socket&.close
90
+ @socket = nil
91
+ @started = false
104
92
  end
105
93
 
106
94
  private
@@ -119,21 +107,6 @@ module Bidi2pdf
119
107
  Bidi2pdf.logger.warn "Unknown response: #{data.inspect}"
120
108
  end
121
109
  end
122
-
123
- def add_interceptor(context:, url_patterns:, phase:, event:, interceptor_class:, extra_args: {})
124
- send_cmd_and_wait("network.addIntercept", {
125
- context: context,
126
- phases: [phase],
127
- urlPatterns: url_patterns
128
- }) do |response|
129
- id = response["result"]["intercept"]
130
- Bidi2pdf.logger.debug "Interceptor added: #{id}"
131
-
132
- interceptor_class.new(id, **extra_args, client: self).tap do |interceptor|
133
- on_event(event, &interceptor.method(:handle_event))
134
- end
135
- end
136
- end
137
110
  end
138
111
  end
139
112
  end
@@ -3,18 +3,35 @@
3
3
  module Bidi2pdf
4
4
  module Bidi
5
5
  class CommandManager
6
+ class << self
7
+ def initialize_counter
8
+ @id = 0
9
+ @id_mutex = Mutex.new
10
+ end
11
+
12
+ def next_id = @id_mutex.synchronize { @id += 1 }
13
+ end
14
+
15
+ initialize_counter
16
+
6
17
  def initialize(socket, logger:)
7
18
  @socket = socket
8
19
  @logger = logger
9
20
 
10
- @id = 0
11
- @next_id_mutex = Mutex.new
12
21
  @pending_responses = {}
22
+ @initiated_cmds = {}
13
23
  end
14
24
 
15
- def send_cmd(method, params = {})
25
+ def send_cmd(cmd, store_response: false)
16
26
  id = next_id
17
- payload = { id: id, method: method, params: params }
27
+
28
+ if store_response
29
+ init_queue_for id
30
+ else
31
+ @initiated_cmds[id] = true
32
+ end
33
+
34
+ payload = cmd.as_payload(id)
18
35
 
19
36
  @logger.debug "Sending command: #{redact_sensitive_fields(payload).inspect}"
20
37
  @socket.send(payload.to_json)
@@ -22,40 +39,46 @@ module Bidi2pdf
22
39
  id
23
40
  end
24
41
 
25
- def send_cmd_and_wait(method, params = {}, timeout: Bidi2pdf.default_timeout)
26
- id = send_cmd(method, params)
27
- queue = @pending_responses[id]
42
+ def send_cmd_and_wait(cmd, timeout: Bidi2pdf.default_timeout)
43
+ id = send_cmd(cmd, store_response: true)
44
+ response = pop_response id, timeout: timeout
28
45
 
29
- response = queue.pop(timeout: timeout)
30
- raise_timeout_error(id, method, params) if response.nil?
31
- raise "Error response: #{response["error"]}" if response["error"]
46
+ raise_timeout_error(id, cmd) if response.nil?
47
+ raise CmdError, "Error response: #{response["error"]} #{cmd.inspect}" if response["error"]
32
48
 
33
49
  block_given? ? yield(response) : response
34
50
  ensure
35
51
  @pending_responses.delete(id)
36
52
  end
37
53
 
38
- def queue_for(id)
39
- @pending_responses[id]
54
+ def pop_response(id, timeout:)
55
+ raise CmdResponseNotStoredError, "No response stored for command ID #{id} or already popped or this command was not send" unless @pending_responses.key?(id)
56
+
57
+ @pending_responses[id].pop(timeout: timeout)
58
+ ensure
59
+ @pending_responses.delete(id)
40
60
  end
41
61
 
42
62
  def handle_response(data)
43
- if (id = data["id"]) && @pending_responses.key?(id)
44
- @pending_responses[id]&.push(data)
45
- else
46
- false
63
+ if (id = data["id"])
64
+ if @pending_responses.key?(id)
65
+ @pending_responses[id]&.push(data)
66
+ return true
67
+ elsif @initiated_cmds.key?(id)
68
+ @logger.error "Received error: #{data["error"]} for cmd: #{id}" if data["error"]
69
+
70
+ return @initiated_cmds.delete(id)
71
+ end
47
72
  end
73
+
74
+ false
48
75
  end
49
76
 
50
77
  private
51
78
 
52
- def next_id
53
- @next_id_mutex.synchronize do
54
- @id += 1
55
- @pending_responses[@id] = Thread::Queue.new
56
- @id
57
- end
58
- end
79
+ def init_queue_for(id) = @pending_responses[id] = Thread::Queue.new
80
+
81
+ def next_id = self.class.next_id
59
82
 
60
83
  def redact_sensitive_fields(obj, sensitive_keys = %w[value token password authorization username])
61
84
  case obj
@@ -71,11 +94,10 @@ module Bidi2pdf
71
94
  end
72
95
  end
73
96
 
74
- def raise_timeout_error(id, method, params)
75
- # rubocop:disable Layout/LineLength
76
- @logger.error "Timeout waiting for response to command #{id}, cmd: #{method}, params: #{redact_sensitive_fields(params).inspect}"
77
- # rubocop:enable Layout/LineLength
78
- raise "Timeout waiting for response to command ID #{id}"
97
+ def raise_timeout_error(id, cmd)
98
+ @logger.error "Timeout waiting for response to command #{id}, cmd: #{cmd.inspect}"
99
+
100
+ raise CmdTimeoutError, "Timeout waiting for response to command ID #{id}"
79
101
  end
80
102
  end
81
103
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class AddIntercept
7
+ include Base
8
+
9
+ BEFORE_REQUEST = "beforeRequestSent"
10
+ RESPONSE_STARTED = "responseStarted"
11
+ AUTH_REQUIRED = "authRequired"
12
+
13
+ def initialize(context:, phases:, url_patterns:)
14
+ @context = context
15
+ @phases = phases
16
+ @url_patterns = url_patterns
17
+
18
+ validate_phases!
19
+ end
20
+
21
+ def method_name
22
+ "network.addIntercept"
23
+ end
24
+
25
+ def params
26
+ {
27
+ context: @context,
28
+ phases: @phases,
29
+ urlPatterns: @url_patterns
30
+ }.compact
31
+ end
32
+
33
+ def validate_phases!
34
+ valid_phases = [BEFORE_REQUEST, RESPONSE_STARTED, AUTH_REQUIRED]
35
+
36
+ raise ArgumentError, "Unsupported phase(s): #{@phases}" unless @phases.all? { |phase| valid_phases.include?(phase) }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ module Base
7
+ def method_name = raise(NotImplementedError, "method_name must be implemented in subclass")
8
+
9
+ def params = {}
10
+
11
+ def as_payload(id)
12
+ {
13
+ id: id,
14
+ method: method_name,
15
+ params: params
16
+ }
17
+ end
18
+
19
+ # rubocop: disable Metrics/AbcSize
20
+ def ==(other)
21
+ return false unless other.respond_to?(:method_name) && other.respond_to?(:params)
22
+
23
+ return false unless method_name == other.method_name
24
+
25
+ return false unless params.keys.sort == other.params.keys.sort
26
+
27
+ params.all? { |key, value| other.params.key?(key) && value == other.params[key] }
28
+ end
29
+
30
+ # rubocop: enable Metrics/AbcSize
31
+
32
+ # Hash equality comparison
33
+ def eql?(other)
34
+ return false unless other.is_a?(Bidi2pdf::Bidi::Commands::Base)
35
+
36
+ self == other
37
+ end
38
+
39
+ def hash
40
+ [method_name, params].hash
41
+ end
42
+
43
+ def inspect
44
+ attributes = redact_sensitive_fields({ method_name: method_name, params: params })
45
+
46
+ "#<#{self.class}:#{object_id} #{attributes}>"
47
+ end
48
+
49
+ private
50
+
51
+ def redact_sensitive_fields(obj, sensitive_keys = %w[value token password authorization username])
52
+ case obj
53
+ when Hash
54
+ obj.transform_values.with_index do |v, idx|
55
+ k = obj.keys[idx]
56
+ sensitive_keys.include?(k.to_s.downcase) ? "[REDACTED]" : redact_sensitive_fields(v, sensitive_keys)
57
+ end
58
+ when Array
59
+ obj.map { |item| redact_sensitive_fields(item, sensitive_keys) }
60
+ else
61
+ obj
62
+ end
63
+ end
64
+
65
+ def raise_timeout_error(id, method, params)
66
+ @logger.error "Timeout waiting for response to command #{id}, cmd: #{method}, params: #{redact_sensitive_fields(params).inspect}"
67
+
68
+ raise CmdTimeoutError, "Timeout waiting for response to command ID #{id}"
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class BrowserClose
7
+ include Base
8
+
9
+ def method_name
10
+ "browser.close"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class BrowserCreateUserContext
7
+ include Base
8
+
9
+ def method_name
10
+ "browser.createUserContext"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class BrowsingContextClose
7
+ include Base
8
+
9
+ def initialize(context:)
10
+ @context = context
11
+ end
12
+
13
+ def params
14
+ {
15
+ context: @context
16
+ }
17
+ end
18
+
19
+ def method_name
20
+ "browsingContext.close"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class BrowsingContextNavigate
7
+ include Base
8
+
9
+ def initialize(url:,
10
+ context:,
11
+ wait: "complete")
12
+ @url = url
13
+ @context = context
14
+ @wait = wait
15
+ end
16
+
17
+ def params
18
+ {
19
+ url: @url,
20
+ context: @context,
21
+ wait: @wait
22
+ }
23
+ end
24
+
25
+ def method_name
26
+ "browsingContext.navigate"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "print_parameters_validator"
4
+
5
+ module Bidi2pdf
6
+ module Bidi
7
+ module Commands
8
+ class BrowsingContextPrint
9
+ include Base
10
+
11
+ def initialize(context:, print_options:)
12
+ @context = context
13
+ @print_options = print_options || { background: true }
14
+
15
+ PrintParametersValidator.validate!(@print_options)
16
+ end
17
+
18
+ def params
19
+ @print_options.merge(context: @context)
20
+ end
21
+
22
+ def method_name
23
+ "browsingContext.print"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class CancelAuth
7
+ include Base
8
+
9
+ def initialize(request:)
10
+ @request = request
11
+ end
12
+
13
+ def params
14
+ {
15
+ request: @request,
16
+ action: "cancel"
17
+ }
18
+ end
19
+
20
+ def method_name
21
+ "network.continueWithAuth"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class CreateTab < CreateWindow
7
+ def type = "tab"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class CreateWindow
7
+ include Base
8
+
9
+ def initialize(user_context_id: nil, reference_context: nil, background: false)
10
+ @user_context_id = user_context_id
11
+ @reference_context = reference_context
12
+ @background = background
13
+ end
14
+
15
+ def method_name
16
+ "browsingContext.create"
17
+ end
18
+
19
+ def params
20
+ {
21
+ type: type,
22
+ userContext: @user_context_id,
23
+ referenceContext: @reference_context,
24
+ background: @background
25
+ }.compact
26
+ end
27
+
28
+ def type = "window"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class GetUserContexts
7
+ include Base
8
+
9
+ def method_name
10
+ "browser.getUserContexts"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module Bidi
5
+ module Commands
6
+ class NetworkContinue
7
+ include Base
8
+
9
+ attr_reader :request, :headers
10
+
11
+ def initialize(request:, headers:)
12
+ @headers = headers
13
+ @request = request
14
+ end
15
+
16
+ def method_name
17
+ "network.continueRequest"
18
+ end
19
+
20
+ def params
21
+ {
22
+ request: request,
23
+ headers: headers
24
+ }.compact
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end