minibidi 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 607b907a85631222aca0cf29e33cdcc76af704464e8a64ee19b9e2da1b6c3b75
4
- data.tar.gz: 527e055f3473a2c08f26157d466f2759a210476e97e63d341f90e91b7053315a
3
+ metadata.gz: 74c2b07cd5b5a34c85ca23e6127e5c09b23af0814ab91339e8ffc3c18f2aaec4
4
+ data.tar.gz: 1de813a159df9930ffa27dc69b3c68426faebbe3604dc631b03fb899ea39a7ce
5
5
  SHA512:
6
- metadata.gz: 2a470c291ead662299187dff8f4cf4b3eaffa7308ad3ad15adee38ce39fa5112d93941ceabd120a7e7d47bd2153a36d449c18935364d90f346b5fac5def8ac3f
7
- data.tar.gz: 6ca0eff8038b65628ebf1e66040c5ed7d6b4ffbcd997084e018feeb8911974295e13c61d0d79652b74b20e54dd11ca60df332e992ece59c6231fe3265a4c3030
6
+ metadata.gz: 2be5e98fd4c177b4b087a3ca8af9efa5110386df709de76c61b477463b44fb6a797c13c002f270fba542a8b548a226dbae8dfa86000d26cc4b93fbd4bd486025
7
+ data.tar.gz: 185322a8c0ee29af4e7fd1a0663dc89746ab7203163c5a9f27bd17158b17a009d7f7dde2b910163f950c678a4f66e1a18133fdd69f7d40353d69df32c21f2e30
data/Gemfile CHANGED
@@ -4,3 +4,11 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in minibidi.gemspec
6
6
  gemspec
7
+
8
+ gem "bundler"
9
+ gem "minitest"
10
+ gem "pry"
11
+ gem "rack-test_server"
12
+ gem "rake"
13
+ gem "sinatra", require: false
14
+ gem 'webrick'
@@ -1,5 +1,6 @@
1
1
  require 'async'
2
2
  require 'async/variable'
3
+ require 'json'
3
4
 
4
5
  module Minibidi
5
6
  class Browser
@@ -8,10 +9,8 @@ module Minibidi
8
9
  @debug_protocol = %w[1 true].include?(ENV['DEBUG'])
9
10
 
10
11
  Async do
11
- while data = async_websocket_connection.read
12
- if message = Protocol::WebSocket::JSONMessage.wrap(data)
13
- handle_received_message_from_websocket(message.to_h)
14
- end
12
+ while message = async_websocket_connection.read
13
+ handle_received_message_from_websocket(message.to_h)
15
14
  end
16
15
  end
17
16
 
@@ -79,7 +78,7 @@ module Minibidi
79
78
 
80
79
  def send_message_to_websocket(payload)
81
80
  debug_print_send(payload)
82
- message = Protocol::WebSocket::JSONMessage.generate(payload)
81
+ message = Protocol::WebSocket::TextMessage.new(JSON.generate(payload))
83
82
  message.send(@websocket)
84
83
  @websocket.flush
85
84
  end
@@ -105,7 +104,7 @@ module Minibidi
105
104
  new(
106
105
  type: payload[:error],
107
106
  message: payload[:message],
108
- stacktrace: payload[:stacktrace].split("\n"),
107
+ stacktrace: (payload[:stacktrace] || '').split("\n"),
109
108
  )
110
109
  end
111
110
 
@@ -7,19 +7,76 @@ module Minibidi
7
7
  @context_id = context_id
8
8
  end
9
9
 
10
- def navigate(url)
11
- bidi_call_async('browsingContext.navigate', { url: url, wait: :interactive }).wait
10
+ def navigate(url, wait: :interactive)
11
+ bidi_call_async('browsingContext.navigate', {
12
+ url: url,
13
+ wait: wait,
14
+ }.compact).wait
12
15
  end
13
16
 
14
- def capture_screenshot(origin:, format:)
17
+ def realms
18
+ result = bidi_call_async('script.getRealms').wait
19
+ result[:realms].map do |realm|
20
+ Realm.new(
21
+ browsing_context: self,
22
+ id: realm[:realm],
23
+ origin: realm[:origin],
24
+ type: realm[:type],
25
+ )
26
+ end
27
+ end
28
+
29
+ def default_realm
30
+ realms.find { |realm| realm.type == 'window' }
31
+ end
32
+
33
+ def input
34
+ Input.new(self)
35
+ end
36
+
37
+ def activate
38
+ bidi_call_async('browsingContext.activate').wait
39
+ end
40
+
41
+ def capture_screenshot(origin: nil, format: nil, clip: nil)
15
42
  result = bidi_call_async('browsingContext.captureScreenshot', {
16
43
  origin: origin,
17
44
  format: format,
18
- }).wait
45
+ clip: clip,
46
+ }.compact).wait
19
47
 
20
48
  Base64.strict_decode64(result[:data])
21
49
  end
22
50
 
51
+ def close(prompt_unload: nil)
52
+ bidi_call_async('browsingContext.close', {
53
+ promptUnload: prompt_unload,
54
+ }.compact).wait
55
+ end
56
+
57
+ def reload(ignore_cache: nil, wait: nil)
58
+ bidi_call_async('browsingContext.reload', {
59
+ ignoreCache: ignore_cache,
60
+ wait: wait,
61
+ }.compact).wait
62
+ end
63
+
64
+ def set_viewport(width:, height:, device_pixel_ratio: nil)
65
+ bidi_call_async('browsingContext.setViewport', {
66
+ viewport: {
67
+ width: width,
68
+ height: height,
69
+ },
70
+ devicePixelRatio: device_pixel_ratio,
71
+ }.compact).wait
72
+ end
73
+
74
+ def traverse_history(delta)
75
+ bidi_call_async('browsingContext.traverseHistory', {
76
+ delta: delta,
77
+ }).wait
78
+ end
79
+
23
80
  private
24
81
 
25
82
  def bidi_call_async(method_, params = {})
@@ -2,41 +2,72 @@ require 'async'
2
2
  require 'async/http/endpoint'
3
3
  require 'async/websocket'
4
4
  require 'open3'
5
- require 'protocol/websocket/json_message'
6
5
  require 'timeout'
7
6
  require 'tmpdir'
8
7
 
9
8
  module Minibidi
9
+ class Firefox
10
+ def self.launch(&block)
11
+ FirefoxLauncher.new.launch(&block)
12
+ end
13
+
14
+ def self.discover_binary
15
+ # check if macOS
16
+ if RUBY_PLATFORM =~ /darwin/
17
+ if File.exist?("/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox")
18
+ return "/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox"
19
+ end
20
+ elsif RUBY_PLATFORM =~ /linux/
21
+ if File.exist?("/usr/bin/firefox-devedition")
22
+ return "/usr/bin/firefox-devedition"
23
+ end
24
+ end
25
+
26
+ raise LaunchError, 'Firefox Developer Edition is not found. Please install it from https://www.mozilla.org/firefox/developer/'
27
+ end
28
+ end
29
+
10
30
  class FirefoxLauncher
11
31
  def launch(&block)
12
32
  raise ArgumentError, "block is required" unless block
13
33
 
14
- Dir.mktmpdir('minibidi') do |tmp|
15
- create_user_profile(tmp)
34
+ tmp = Dir.mktmpdir('minibidi')
35
+ create_user_profile(tmp)
36
+ args = [
37
+ "--remote-debugging-port=0",
38
+ "--profile",
39
+ tmp,
40
+ "--no-remote",
41
+ ]
42
+ if RUBY_PLATFORM =~ /darwin/
43
+ args << "--foreground"
44
+ end
45
+ if %w[true 1].include?(ENV['HEADLESS'])
46
+ args << "--headless"
47
+ end
16
48
 
17
- proc = BrowserProcess.new(
18
- "/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox",
19
- "--remote-debugging-port=0",
20
- "--profile #{tmp}",
21
- "--no-remote",
22
- "--foreground",
23
- "about:blank",
24
- )
25
- at_exit { proc.kill }
26
- trap(:INT) { proc.kill ; exit 130 }
27
- trap(:TERM) { proc.kill ; proc.dispose }
28
- trap(:HUP) { proc.kill ; proc.dispose }
49
+ proc = BrowserProcess.new(
50
+ Firefox.discover_binary,
51
+ *args,
52
+ "about:blank",
53
+ )
54
+ at_exit do
55
+ proc.kill
56
+ FileUtils.remove_entry(tmp)
57
+ end
58
+ trap(:INT) { proc.kill ; exit 130 }
59
+ trap(:TERM) { proc.kill ; proc.dispose }
60
+ trap(:HUP) { proc.kill ; proc.dispose }
29
61
 
30
- endpoint = wait_for_ws_endpoint(proc)
62
+ endpoint = wait_for_ws_endpoint(proc)
31
63
 
32
- Async::Reactor.run do
33
- Async::WebSocket::Client.connect(Async::HTTP::Endpoint.parse("#{endpoint}/session")) do |async_websocket_connection|
34
- browser = Browser.new(async_websocket_connection)
35
- begin
36
- block.call(browser)
37
- ensure
38
- browser.close
39
- end
64
+ Async::Reactor.run do
65
+ Async::WebSocket::Client.connect(Async::HTTP::Endpoint.parse("#{endpoint}/session")) do |async_websocket_connection|
66
+ browser = Browser.new(async_websocket_connection)
67
+ begin
68
+ block.call(browser)
69
+ ensure
70
+ browser.close
40
71
  end
41
72
  end
42
73
  end
@@ -0,0 +1,298 @@
1
+ module Minibidi
2
+ class Input
3
+ def initialize(browser_context)
4
+ @browser_context = browser_context
5
+ end
6
+
7
+ def click(x:, y:, delay: 50)
8
+ perform_mouse_actions do |q|
9
+ q.pointer_move(x: x.to_i, y: y.to_i)
10
+ q.pointer_down(button: 0)
11
+ q.pause(delay)
12
+ q.pointer_up(button: 0)
13
+ end
14
+ end
15
+
16
+ def while_pressing_key(key, &block)
17
+ value = convert_key(key)
18
+ perform_keyboard_actions do |q|
19
+ q.key_down(value)
20
+ end
21
+
22
+ begin
23
+ block.call
24
+ ensure
25
+ perform_keyboard_actions do |q|
26
+ q.key_up(value)
27
+ end
28
+ end
29
+ end
30
+
31
+ def press_key(key, delay: 50)
32
+ value = convert_key(key)
33
+ perform_keyboard_actions do |q|
34
+ q.key_down(value)
35
+ q.pause(delay)
36
+ q.key_up(value)
37
+ end
38
+ end
39
+
40
+ def type_text(text, delay: 50)
41
+ text.each_char do |char|
42
+ perform_keyboard_actions do |q|
43
+ q.key_down(char)
44
+ q.pause(delay / 2)
45
+ q.key_up(char)
46
+ q.pause(delay / 2)
47
+ end
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def perform_actions(actions)
54
+ @browser_context.send(:bidi_call_async, 'input.performActions', {
55
+ actions: actions,
56
+ }).wait
57
+ end
58
+
59
+ def perform_keyboard_actions(&block)
60
+ q = KeyboardActionQueue.new
61
+ block.call(q)
62
+ perform_actions([{
63
+ type: 'key',
64
+ id: '__minibidi_keyboard',
65
+ actions: q.to_a,
66
+ }])
67
+ end
68
+
69
+ def perform_mouse_actions(&block)
70
+ q = MouseActionQueue.new
71
+ block.call(q)
72
+ perform_actions([{
73
+ type: 'pointer',
74
+ id: '__minibidi_mouse',
75
+ actions: q.to_a,
76
+ }])
77
+ end
78
+
79
+ def macos?
80
+ RUBY_PLATFORM =~ /darwin/
81
+ end
82
+
83
+ # ref: https://github.com/puppeteer/puppeteer/blob/puppeteer-v23.5.3/packages/puppeteer-core/src/bidi/Input.ts#L52
84
+ # Converted using ChatGPT 4o
85
+ def convert_key(key)
86
+ return key if key.length == 1
87
+
88
+ case key
89
+ when 'Cancel'
90
+ "\uE001"
91
+ when 'Help'
92
+ "\uE002"
93
+ when 'Backspace'
94
+ "\uE003"
95
+ when 'Tab'
96
+ "\uE004"
97
+ when 'Clear'
98
+ "\uE005"
99
+ when 'Enter'
100
+ "\uE007"
101
+ when 'Shift', 'ShiftLeft'
102
+ "\uE008"
103
+ when 'Control', 'ControlLeft', 'Ctrl'
104
+ "\uE009"
105
+ when 'ControlOrMeta', 'CtrlOrMeta'
106
+ macos? ? "\uE03D" : "\uE009"
107
+ when 'Alt', 'AltLeft'
108
+ "\uE00A"
109
+ when 'Pause'
110
+ "\uE00B"
111
+ when 'Escape'
112
+ "\uE00C"
113
+ when 'PageUp'
114
+ "\uE00E"
115
+ when 'PageDown'
116
+ "\uE00F"
117
+ when 'End'
118
+ "\uE010"
119
+ when 'Home'
120
+ "\uE011"
121
+ when 'ArrowLeft'
122
+ "\uE012"
123
+ when 'ArrowUp'
124
+ "\uE013"
125
+ when 'ArrowRight'
126
+ "\uE014"
127
+ when 'ArrowDown'
128
+ "\uE015"
129
+ when 'Insert'
130
+ "\uE016"
131
+ when 'Delete'
132
+ "\uE017"
133
+ when 'NumpadEqual'
134
+ "\uE019"
135
+ when 'Numpad0'
136
+ "\uE01A"
137
+ when 'Numpad1'
138
+ "\uE01B"
139
+ when 'Numpad2'
140
+ "\uE01C"
141
+ when 'Numpad3'
142
+ "\uE01D"
143
+ when 'Numpad4'
144
+ "\uE01E"
145
+ when 'Numpad5'
146
+ "\uE01F"
147
+ when 'Numpad6'
148
+ "\uE020"
149
+ when 'Numpad7'
150
+ "\uE021"
151
+ when 'Numpad8'
152
+ "\uE022"
153
+ when 'Numpad9'
154
+ "\uE023"
155
+ when 'NumpadMultiply'
156
+ "\uE024"
157
+ when 'NumpadAdd'
158
+ "\uE025"
159
+ when 'NumpadSubtract'
160
+ "\uE027"
161
+ when 'NumpadDecimal'
162
+ "\uE028"
163
+ when 'NumpadDivide'
164
+ "\uE029"
165
+ when 'F1'
166
+ "\uE031"
167
+ when 'F2'
168
+ "\uE032"
169
+ when 'F3'
170
+ "\uE033"
171
+ when 'F4'
172
+ "\uE034"
173
+ when 'F5'
174
+ "\uE035"
175
+ when 'F6'
176
+ "\uE036"
177
+ when 'F7'
178
+ "\uE037"
179
+ when 'F8'
180
+ "\uE038"
181
+ when 'F9'
182
+ "\uE039"
183
+ when 'F10'
184
+ "\uE03A"
185
+ when 'F11'
186
+ "\uE03B"
187
+ when 'F12'
188
+ "\uE03C"
189
+ when 'Meta', 'MetaLeft'
190
+ "\uE03D"
191
+ when 'ShiftRight'
192
+ "\uE050"
193
+ when 'ControlRight'
194
+ "\uE051"
195
+ when 'AltRight'
196
+ "\uE052"
197
+ when 'MetaRight'
198
+ "\uE053"
199
+ when 'Digit0'
200
+ '0'
201
+ when 'Digit1'
202
+ '1'
203
+ when 'Digit2'
204
+ '2'
205
+ when 'Digit3'
206
+ '3'
207
+ when 'Digit4'
208
+ '4'
209
+ when 'Digit5'
210
+ '5'
211
+ when 'Digit6'
212
+ '6'
213
+ when 'Digit7'
214
+ '7'
215
+ when 'Digit8'
216
+ '8'
217
+ when 'Digit9'
218
+ '9'
219
+ when 'KeyA'
220
+ 'a'
221
+ when 'KeyB'
222
+ 'b'
223
+ when 'KeyC'
224
+ 'c'
225
+ when 'KeyD'
226
+ 'd'
227
+ when 'KeyE'
228
+ 'e'
229
+ when 'KeyF'
230
+ 'f'
231
+ when 'KeyG'
232
+ 'g'
233
+ when 'KeyH'
234
+ 'h'
235
+ when 'KeyI'
236
+ 'i'
237
+ when 'KeyJ'
238
+ 'j'
239
+ when 'KeyK'
240
+ 'k'
241
+ when 'KeyL'
242
+ 'l'
243
+ when 'KeyM'
244
+ 'm'
245
+ when 'KeyN'
246
+ 'n'
247
+ when 'KeyO'
248
+ 'o'
249
+ when 'KeyP'
250
+ 'p'
251
+ when 'KeyQ'
252
+ 'q'
253
+ when 'KeyR'
254
+ 'r'
255
+ when 'KeyS'
256
+ 's'
257
+ when 'KeyT'
258
+ 't'
259
+ when 'KeyU'
260
+ 'u'
261
+ when 'KeyV'
262
+ 'v'
263
+ when 'KeyW'
264
+ 'w'
265
+ when 'KeyX'
266
+ 'x'
267
+ when 'KeyY'
268
+ 'y'
269
+ when 'KeyZ'
270
+ 'z'
271
+ when 'Semicolon'
272
+ ';'
273
+ when 'Equal'
274
+ '='
275
+ when 'Comma'
276
+ ','
277
+ when 'Minus'
278
+ '-'
279
+ when 'Period'
280
+ '.'
281
+ when 'Slash'
282
+ '/'
283
+ when 'Backquote'
284
+ '`'
285
+ when 'BracketLeft'
286
+ '['
287
+ when 'Backslash'
288
+ '\\'
289
+ when 'BracketRight'
290
+ ']'
291
+ when 'Quote'
292
+ '"'
293
+ else
294
+ raise ArgumentError, "Unknown key: \"#{key}\""
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,23 @@
1
+ module Minibidi
2
+ class KeyboardActionQueue
3
+ def initialize
4
+ @actions = []
5
+ end
6
+
7
+ def to_a
8
+ @actions
9
+ end
10
+
11
+ def pause(duration)
12
+ @actions << { type: 'pause', duration: duration }
13
+ end
14
+
15
+ def key_down(value)
16
+ @actions << { type: 'keyDown', value: value }
17
+ end
18
+
19
+ def key_up(value)
20
+ @actions << { type: 'keyUp', value: value }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ module Minibidi
2
+ class MouseActionQueue
3
+ def initialize
4
+ @actions = []
5
+ end
6
+
7
+ def to_a
8
+ @actions
9
+ end
10
+
11
+ def pause(duration)
12
+ @actions << { type: 'pause', duration: duration }
13
+ end
14
+
15
+ # button: 0 for left, 1 for middle, 2 for right
16
+ def pointer_down(button:)
17
+ @actions << { type: 'pointerDown', button: button }
18
+ end
19
+
20
+ def pointer_move(x:, y:, duration: nil)
21
+ @actions << { type: 'pointerMove', x: x, y: y, duration: duration }.compact
22
+ end
23
+
24
+ # button: 0 for left, 1 for middle, 2 for right
25
+ def pointer_up(button:)
26
+ @actions << { type: 'pointerUp', button: button }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,76 @@
1
+ module Minibidi
2
+ class Realm
3
+ def initialize(browsing_context:, id:, origin:, type: nil)
4
+ @browsing_context = browsing_context
5
+ @id = id
6
+ @origin = origin
7
+ @type = type
8
+ end
9
+
10
+ class ScriptEvaluationError < StandardError ; end
11
+
12
+ def script_evaluate(expression)
13
+ result = @browsing_context.send(:bidi_call_async, 'script.evaluate', {
14
+ expression: expression,
15
+ target: { realm: @id },
16
+ awaitPromise: true,
17
+ }).wait
18
+
19
+ if result[:type] == 'exception'
20
+ raise ScriptEvaluationError.new(result[:exceptionDetails][:text])
21
+ end
22
+
23
+ deserialize(result[:result])
24
+ end
25
+
26
+ attr_reader :type
27
+
28
+ private
29
+
30
+ def deserialize(result)
31
+ # ref: https://github.com/puppeteer/puppeteer/blob/puppeteer-v23.5.3/packages/puppeteer-core/src/bidi/Deserializer.ts#L21
32
+ # Converted using ChatGPT 4o
33
+ case result[:type]
34
+ when 'array'
35
+ result[:value]&.map { |value| deserialize(value) }
36
+ when 'set'
37
+ result[:value]&.each_with_object(Set.new) do |value, acc|
38
+ acc.add(deserialize(value))
39
+ end
40
+ when 'object'
41
+ result[:value]&.each_with_object({}) do |tuple, acc|
42
+ key, value = tuple
43
+ acc[key] = deserialize(value)
44
+ end
45
+ when 'map'
46
+ result[:value]&.each_with_object({}) do |tuple, acc|
47
+ key, value = tuple
48
+ acc[key] = deserialize(value)
49
+ end
50
+ when 'promise'
51
+ {}
52
+ when 'regexp'
53
+ flags = 0
54
+ result[:value][:flags]&.each_char do |flag|
55
+ case flag
56
+ when 'm'
57
+ flags |= Regexp::MULTILINE
58
+ when 'i'
59
+ flags |= Regexp::IGNORECASE
60
+ end
61
+ end
62
+ Regexp.new(result[:value][:pattern], flags)
63
+ when 'date'
64
+ Date.parse(result[:value])
65
+ when 'undefined'
66
+ nil
67
+ when 'null'
68
+ nil
69
+ when 'number', 'bigint', 'boolean', 'string'
70
+ result[:value]
71
+ else
72
+ raise ArgumentError, "Unknown type: #{result[:type]}"
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,3 @@
1
1
  module Minibidi
2
- VERSION = '0.0.0'
2
+ VERSION = '0.1.0'
3
3
  end
data/lib/minibidi.rb CHANGED
@@ -3,8 +3,11 @@ require "minibidi/version"
3
3
  require 'minibidi/browser'
4
4
  require 'minibidi/browsing_context'
5
5
  require 'minibidi/browser_process'
6
- require 'minibidi/firefox'
7
6
  require 'minibidi/firefox_launcher'
7
+ require 'minibidi/input'
8
+ require 'minibidi/keyboard_action_queue'
9
+ require 'minibidi/mouse_action_queue'
10
+ require 'minibidi/realm'
8
11
 
9
12
  module Minibidi
10
13
  class LaunchError < StandardError ; end
data/minibidi.gemspec CHANGED
@@ -25,8 +25,4 @@ Gem::Specification.new do |spec|
25
25
  spec.required_ruby_version = ">= 3.2" # Dependency for socketry/async and Data.define
26
26
  spec.add_dependency "async"
27
27
  spec.add_dependency "async-websocket"
28
- spec.add_development_dependency "bundler"
29
- spec.add_development_dependency "minitest"
30
- spec.add_development_dependency "pry"
31
- spec.add_development_dependency "rake"
32
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minibidi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.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-04-08 00:00:00.000000000 Z
11
+ date: 2024-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -38,62 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: minitest
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: pry
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
41
  description:
98
42
  email:
99
43
  - q7w8e9w8q7w8e9@yahoo.co.jp
@@ -110,8 +54,11 @@ files:
110
54
  - lib/minibidi/browser.rb
111
55
  - lib/minibidi/browser_process.rb
112
56
  - lib/minibidi/browsing_context.rb
113
- - lib/minibidi/firefox.rb
114
57
  - lib/minibidi/firefox_launcher.rb
58
+ - lib/minibidi/input.rb
59
+ - lib/minibidi/keyboard_action_queue.rb
60
+ - lib/minibidi/mouse_action_queue.rb
61
+ - lib/minibidi/realm.rb
115
62
  - lib/minibidi/version.rb
116
63
  - minibidi.gemspec
117
64
  homepage: https://github.com/YusukeIwaki/minibidi
@@ -133,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
80
  - !ruby/object:Gem::Version
134
81
  version: '0'
135
82
  requirements: []
136
- rubygems_version: 3.5.3
83
+ rubygems_version: 3.5.22
137
84
  signing_key:
138
85
  specification_version: 4
139
86
  summary: Mini WebDriver BiDi binding for Ruby
@@ -1,7 +0,0 @@
1
- module Minibidi
2
- class Firefox
3
- def self.launch(&block)
4
- FirefoxLauncher.new.launch(&block)
5
- end
6
- end
7
- end