chromate-rb 0.0.1.pre → 0.0.3.pre

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/CHANGELOG.md +72 -3
  4. data/README.md +33 -6
  5. data/Rakefile +48 -16
  6. data/docker_root/Gemfile +4 -0
  7. data/docker_root/Gemfile.lock +28 -0
  8. data/docker_root/TestInDocker.gif +0 -0
  9. data/docker_root/app.rb +87 -0
  10. data/dockerfiles/Dockerfile +21 -7
  11. data/dockerfiles/README.md +49 -0
  12. data/docs/BOT_BROWSER.md +74 -0
  13. data/docs/README.md +74 -0
  14. data/docs/browser.md +124 -102
  15. data/docs/client.md +126 -0
  16. data/docs/element.md +365 -0
  17. data/docs/elements/checkbox.md +69 -0
  18. data/docs/elements/radio.md +57 -0
  19. data/lib/bot_browser/downloader.rb +64 -0
  20. data/lib/bot_browser/installer.rb +99 -0
  21. data/lib/bot_browser.rb +43 -0
  22. data/lib/chromate/actions/dom.rb +35 -27
  23. data/lib/chromate/actions/navigate.rb +7 -5
  24. data/lib/chromate/actions/screenshot.rb +71 -14
  25. data/lib/chromate/actions/stealth.rb +62 -0
  26. data/lib/chromate/binary.rb +83 -0
  27. data/lib/chromate/browser.rb +120 -24
  28. data/lib/chromate/c_logger.rb +8 -0
  29. data/lib/chromate/client.rb +65 -26
  30. data/lib/chromate/configuration.rb +31 -14
  31. data/lib/chromate/element.rb +119 -16
  32. data/lib/chromate/elements/checkbox.rb +40 -0
  33. data/lib/chromate/elements/option.rb +43 -0
  34. data/lib/chromate/elements/radio.rb +37 -0
  35. data/lib/chromate/elements/select.rb +50 -6
  36. data/lib/chromate/elements/tags.rb +29 -0
  37. data/lib/chromate/exceptions.rb +2 -0
  38. data/lib/chromate/files/agents.json +11 -0
  39. data/lib/chromate/files/stealth.js +199 -0
  40. data/lib/chromate/hardwares/keyboard_controller.rb +45 -0
  41. data/lib/chromate/hardwares/keyboards/virtual_controller.rb +65 -0
  42. data/lib/chromate/hardwares/mouse_controller.rb +55 -11
  43. data/lib/chromate/hardwares/mouses/linux_controller.rb +124 -21
  44. data/lib/chromate/hardwares/mouses/mac_os_controller.rb +6 -6
  45. data/lib/chromate/hardwares/mouses/virtual_controller.rb +95 -7
  46. data/lib/chromate/hardwares/mouses/x11.rb +36 -0
  47. data/lib/chromate/hardwares.rb +19 -3
  48. data/lib/chromate/helpers.rb +22 -15
  49. data/lib/chromate/user_agent.rb +41 -15
  50. data/lib/chromate/version.rb +1 -1
  51. data/lib/chromate.rb +2 -0
  52. data/logo.png +0 -0
  53. data/results/bot.png +0 -0
  54. data/results/brotector.png +0 -0
  55. data/results/cloudflare.png +0 -0
  56. data/results/headers.png +0 -0
  57. data/results/pixelscan.png +0 -0
  58. metadata +45 -2
data/docs/element.md ADDED
@@ -0,0 +1,365 @@
1
+ # Element
2
+
3
+ The `Chromate::Element` class represents a DOM element in a browser controlled via the Chrome DevTools Protocol (CDP). It provides methods to interact with the element, including manipulating its attributes, getting its text content, and simulating user actions.
4
+
5
+ ### Initialization
6
+
7
+ ```ruby
8
+ element = Chromate::Element.new(selector, client, node_id: nil, object_id: nil, root_id: nil)
9
+ ```
10
+
11
+ - **Parameters:**
12
+ - `selector` (String): The CSS selector used to locate the element.
13
+ - `client` (Chromate::Client): An instance of the CDP client.
14
+ - `node_id` (Integer, optional): The node ID of the element.
15
+ - `object_id` (String, optional): The object ID of the element.
16
+ - `root_id` (Integer, optional): The root node ID of the document.
17
+
18
+ ### Attributes
19
+
20
+ #### `#selector`
21
+
22
+ Returns the CSS selector used to locate the element.
23
+
24
+ - **Returns:**
25
+ - `String`: The CSS selector.
26
+
27
+ #### `#client`
28
+
29
+ Returns the CDP client instance used to communicate with the browser.
30
+
31
+ - **Returns:**
32
+ - `Chromate::Client`: The CDP client instance.
33
+
34
+ #### `#root_id`
35
+
36
+ Returns the root node ID of the document.
37
+
38
+ - **Returns:**
39
+ - `Integer`: The root node ID.
40
+
41
+ #### `#object_id`
42
+
43
+ Returns the object ID of the element.
44
+
45
+ - **Returns:**
46
+ - `String`: The object ID.
47
+
48
+ #### `#node_id`
49
+
50
+ Returns the node ID of the element.
51
+
52
+ - **Returns:**
53
+ - `Integer`: The node ID.
54
+
55
+ ### Public Methods
56
+
57
+ #### `#mouse`
58
+
59
+ Returns the mouse controller for interacting with the element.
60
+
61
+ - **Example:**
62
+ ```ruby
63
+ element.mouse.click
64
+ ```
65
+
66
+ #### `#keyboard`
67
+
68
+ Returns the keyboard controller for interacting with the element.
69
+
70
+ - **Example:**
71
+ ```ruby
72
+ element.keyboard.type('Hello World')
73
+ ```
74
+
75
+ #### `#inspect`
76
+
77
+ Returns a string representation of the element.
78
+
79
+ - **Example:**
80
+ ```ruby
81
+ puts element.inspect
82
+ ```
83
+
84
+ #### `#text`
85
+
86
+ Retrieves the inner text of the element.
87
+
88
+ - **Example:**
89
+ ```ruby
90
+ text = element.text
91
+ puts "Element text: #{text}"
92
+ ```
93
+
94
+ #### `#html`
95
+
96
+ Retrieves the outer HTML of the element.
97
+
98
+ - **Example:**
99
+ ```ruby
100
+ html = element.html
101
+ puts "Element HTML: #{html}"
102
+ ```
103
+
104
+ #### `#attributes`
105
+
106
+ Returns a hash of the element's attributes.
107
+
108
+ - **Example:**
109
+ ```ruby
110
+ attributes = element.attributes
111
+ puts "Element attributes: #{attributes}"
112
+ ```
113
+
114
+ #### `#tag_name`
115
+
116
+ Gets the HTML tag name of the element in lowercase.
117
+
118
+ - **Returns:**
119
+ - `String`: The HTML tag name.
120
+
121
+ - **Example:**
122
+ ```ruby
123
+ tag = element.tag_name
124
+ puts "Tag name: #{tag}"
125
+ ```
126
+
127
+ #### `#set_attribute(name, value)`
128
+
129
+ Sets an attribute on the element.
130
+
131
+ - **Parameters:**
132
+ - `name` (String): The name of the attribute.
133
+ - `value` (String): The value to set for the attribute.
134
+
135
+ - **Example:**
136
+ ```ruby
137
+ element.set_attribute('class', 'highlighted')
138
+ ```
139
+
140
+ #### `#bounding_box`
141
+
142
+ Returns a hash with the dimensions of the element's bounding box.
143
+
144
+ - **Example:**
145
+ ```ruby
146
+ box = element.bounding_box
147
+ puts "Bounding box: #{box}"
148
+ ```
149
+
150
+ #### `#x`
151
+
152
+ Returns the x-coordinate of the element's position.
153
+
154
+ - **Example:**
155
+ ```ruby
156
+ x_position = element.x
157
+ puts "X Position: #{x_position}"
158
+ ```
159
+
160
+ #### `#y`
161
+
162
+ Returns the y-coordinate of the element's position.
163
+
164
+ - **Example:**
165
+ ```ruby
166
+ y_position = element.y
167
+ puts "Y Position: #{y_position}"
168
+ ```
169
+
170
+ #### `#width`
171
+
172
+ Returns the width of the element.
173
+
174
+ - **Example:**
175
+ ```ruby
176
+ width = element.width
177
+ puts "Element width: #{width}"
178
+ ```
179
+
180
+ #### `#height`
181
+
182
+ Returns the height of the element.
183
+
184
+ - **Example:**
185
+ ```ruby
186
+ height = element.height
187
+ puts "Element height: #{height}"
188
+ ```
189
+
190
+ #### `#focus`
191
+
192
+ Sets focus on the element.
193
+
194
+ - **Example:**
195
+ ```ruby
196
+ element.focus
197
+ ```
198
+
199
+ #### `#click`
200
+
201
+ Simulates a click on the element.
202
+
203
+ - **Example:**
204
+ ```ruby
205
+ element.click
206
+ ```
207
+
208
+ #### `#hover`
209
+
210
+ Simulates a hover action over the element.
211
+
212
+ - **Example:**
213
+ ```ruby
214
+ element.hover
215
+ ```
216
+
217
+ #### `#type(text)`
218
+
219
+ Types the specified text into the element.
220
+
221
+ - **Parameters:**
222
+ - `text` (String): The text to type.
223
+
224
+ - **Example:**
225
+ ```ruby
226
+ element.type('Hello, Chromate!')
227
+ ```
228
+
229
+ #### `#press_enter`
230
+
231
+ Simulates pressing the Enter key and submits the form if the element is inside one.
232
+
233
+ - **Example:**
234
+ ```ruby
235
+ element.press_enter
236
+ ```
237
+
238
+ #### `#drop_to(element)`
239
+
240
+ Drag current element and drop to target
241
+
242
+ - **Example:**
243
+ ```ruby
244
+ element.drop_to(target_element)
245
+ ```
246
+
247
+ #### `#find_element(selector)`
248
+
249
+ Finds a single child element matching the given selector.
250
+
251
+ - **Parameters:**
252
+ - `selector` (String): The CSS selector to find the element.
253
+
254
+ - **Returns:**
255
+ - `Chromate::Element`: The found element.
256
+
257
+ - **Example:**
258
+ ```ruby
259
+ child_element = element.find_element('.child')
260
+ puts child_element.text
261
+ ```
262
+
263
+ #### `#find_elements(selector, max: 0)`
264
+
265
+ Finds all child elements matching the given selector.
266
+
267
+ - **Parameters:**
268
+ - `selector` (String): The CSS selector to find elements.
269
+ - `max` (Integer, optional): The maximum number of elements to find (0 for no limit).
270
+
271
+ - **Returns:**
272
+ - `Array<Chromate::Element>`: An array of found elements.
273
+
274
+ - **Example:**
275
+ ```ruby
276
+ elements = element.find_elements('.item')
277
+ elements.each { |el| puts el.text }
278
+ ```
279
+
280
+ #### `#shadow_root_id`
281
+
282
+ Returns the shadow root ID of the element if it has one.
283
+
284
+ - **Example:**
285
+ ```ruby
286
+ shadow_id = element.shadow_root_id
287
+ puts "Shadow root ID: #{shadow_id}"
288
+ ```
289
+
290
+ #### `#shadow_root?`
291
+
292
+ Checks if the element has a shadow root.
293
+
294
+ - **Returns:**
295
+ - `Boolean`: `true` if the element has a shadow root, otherwise `false`.
296
+
297
+ - **Example:**
298
+ ```ruby
299
+ if element.shadow_root?
300
+ puts "Element has a shadow root."
301
+ end
302
+ ```
303
+
304
+ #### `#find_shadow_child(selector)`
305
+
306
+ Finds a single child element inside the shadow root using the given selector.
307
+
308
+ - **Parameters:**
309
+ - `selector` (String): The CSS selector to find the shadow child element.
310
+
311
+ - **Returns:**
312
+ - `Chromate::Element` or `nil`: The found element or `nil` if not found.
313
+
314
+ - **Example:**
315
+ ```ruby
316
+ shadow_child = element.find_shadow_child('.shadow-element')
317
+ puts shadow_child.text if shadow_child
318
+ ```
319
+
320
+ #### `#find_shadow_children(selector)`
321
+
322
+ Finds all child elements inside the shadow root using the given selector.
323
+
324
+ - **Parameters:**
325
+ - `selector` (String): The CSS selector to find shadow child elements.
326
+
327
+ - **Returns:**
328
+ - `Array<Chromate::Element>`: An array of found elements.
329
+
330
+ - **Example:**
331
+ ```ruby
332
+ shadow_elements = element.find_shadow_children('.shadow-item')
333
+ shadow_elements.each { |el| puts el.text }
334
+ ```
335
+
336
+ #### `#value`
337
+
338
+ Gets the value of the element.
339
+
340
+ - **Returns:**
341
+ - `String`: The element's value.
342
+
343
+ - **Example:**
344
+ ```ruby
345
+ value = element.value
346
+ puts "Element value: #{value}"
347
+ ```
348
+
349
+ ### Exceptions
350
+
351
+ - `NotFoundError`: Raised when an element cannot be found with the given selector.
352
+ - `InvalidSelectorError`: Raised when the selector cannot resolve to a valid element.
353
+
354
+ ## Specialized Elements
355
+
356
+ Chromate provides specialized element classes for specific HTML elements that have unique behaviors and methods. When using `find_element`, Chromate automatically returns the appropriate specialized element based on the element type.
357
+
358
+ ### Available Specialized Elements
359
+
360
+ - [Select Element](elements/select.md): For `<select>` elements
361
+ - [Option Element](elements/option.md): For `<option>` elements within select elements
362
+ - [Radio Element](elements/radio.md): For radio button inputs (`<input type="radio">`)
363
+ - [Checkbox Element](elements/checkbox.md): For checkbox inputs (`<input type="checkbox">`)
364
+
365
+ Each specialized element inherits from the base `Element` class and adds specific methods for interacting with that type of element. See the individual documentation files for details on the methods available for each element type.
@@ -0,0 +1,69 @@
1
+ # Checkbox Element
2
+
3
+ The `Chromate::Elements::Checkbox` class represents a checkbox input element in the browser. It extends the base `Element` class with specific functionality for checkboxes.
4
+
5
+ ### Initialization
6
+
7
+ ```ruby
8
+ checkbox = Chromate::Elements::Checkbox.new(selector, client, **options)
9
+ ```
10
+
11
+ - **Parameters:**
12
+ - `selector` (String): The CSS selector used to locate the checkbox.
13
+ - `client` (Chromate::Client): An instance of the CDP client.
14
+ - `options` (Hash): Additional options passed to the Element constructor.
15
+ - `object_id` (String): Optional. The object ID of a pre-searched element.
16
+ - `node_id` (Integer): Optional. The node ID of a pre-searched element.
17
+ - `root_id` (Integer): Optional. The root ID of a pre-searched element.
18
+
19
+ ### Public Methods
20
+
21
+ #### `#checked?`
22
+
23
+ Returns whether the checkbox is currently checked.
24
+
25
+ - **Returns:**
26
+ - `Boolean`: `true` if the checkbox is checked, `false` otherwise.
27
+
28
+ - **Example:**
29
+ ```ruby
30
+ if checkbox.checked?
31
+ puts "Checkbox is checked"
32
+ end
33
+ ```
34
+
35
+ #### `#check`
36
+
37
+ Checks the checkbox if it's not already checked.
38
+
39
+ - **Returns:**
40
+ - `self`: Returns the checkbox element for method chaining.
41
+
42
+ - **Example:**
43
+ ```ruby
44
+ checkbox.check
45
+ ```
46
+
47
+ #### `#uncheck`
48
+
49
+ Unchecks the checkbox if it's currently checked.
50
+
51
+ - **Returns:**
52
+ - `self`: Returns the checkbox element for method chaining.
53
+
54
+ - **Example:**
55
+ ```ruby
56
+ checkbox.uncheck
57
+ ```
58
+
59
+ #### `#toggle`
60
+
61
+ Toggles the checkbox state (checks if unchecked, unchecks if checked).
62
+
63
+ - **Returns:**
64
+ - `self`: Returns the checkbox element for method chaining.
65
+
66
+ - **Example:**
67
+ ```ruby
68
+ checkbox.toggle
69
+ ```
@@ -0,0 +1,57 @@
1
+ # Radio Element
2
+
3
+ The `Chromate::Elements::Radio` class represents a radio button input element in the browser. It extends the base `Element` class with specific functionality for radio buttons.
4
+
5
+ ### Initialization
6
+
7
+ ```ruby
8
+ radio = Chromate::Elements::Radio.new(selector, client, **options)
9
+ ```
10
+
11
+ - **Parameters:**
12
+ - `selector` (String): The CSS selector used to locate the radio button.
13
+ - `client` (Chromate::Client): An instance of the CDP client.
14
+ - `options` (Hash): Additional options passed to the Element constructor.
15
+ - `object_id` (String): Optional. The object ID of a pre-searched element.
16
+ - `node_id` (Integer): Optional. The node ID of a pre-searched element.
17
+ - `root_id` (Integer): Optional. The root ID of a pre-searched element.
18
+
19
+ ### Public Methods
20
+
21
+ #### `#checked?`
22
+
23
+ Returns whether the radio button is currently checked.
24
+
25
+ - **Returns:**
26
+ - `Boolean`: `true` if the radio button is checked, `false` otherwise.
27
+
28
+ - **Example:**
29
+ ```ruby
30
+ if radio.checked?
31
+ puts "Radio button is checked"
32
+ end
33
+ ```
34
+
35
+ #### `#check`
36
+
37
+ Checks the radio button if it's not already checked.
38
+
39
+ - **Returns:**
40
+ - `self`: Returns the radio element for method chaining.
41
+
42
+ - **Example:**
43
+ ```ruby
44
+ radio.check
45
+ ```
46
+
47
+ #### `#uncheck`
48
+
49
+ Unchecks the radio button if it's currently checked.
50
+
51
+ - **Returns:**
52
+ - `self`: Returns the radio element for method chaining.
53
+
54
+ - **Example:**
55
+ ```ruby
56
+ radio.uncheck
57
+ ```
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Special thanks to the BotBrowser project (https://github.com/MiddleSchoolStudent/BotBrowser)
4
+ # for providing an amazing foundation for browser automation and making this work possible.
5
+
6
+ require 'chromate/binary'
7
+
8
+ module BotBrowser
9
+ class Downloader
10
+ class << self
11
+ def download(version = nil, profile = nil, platform = :mac)
12
+ version ||= versions.keys.first
13
+ profile ||= profiles[version].keys.first
14
+ version = version.to_sym
15
+ binary_path = download_file(versions[version][platform], "/tmp/botbrowser_#{version}_#{platform}.dmg")
16
+ profile_path = download_file(profiles[version][profile], "/tmp/botbrowser_#{version}_#{platform}.json")
17
+
18
+ [binary_path, profile_path]
19
+ end
20
+
21
+ def download_file(url, path)
22
+ Chromate::CLogger.log("Downloading #{url} to #{path}")
23
+ Chromate::Binary.run('curl', ['-L', url, '-o', path])
24
+
25
+ path
26
+ end
27
+
28
+ def versions
29
+ {
30
+ v132: {
31
+ mac: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/20250204/botbrowser_132.0.6834.84_mac_arm64.dmg',
32
+ linux: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/20250204/botbrowser_132.0.6834.84_amd64.deb',
33
+ windows: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/20250204/botbrowser_132.0.6834.84_win_x86_64.7z'
34
+ },
35
+ v130: {
36
+ mac: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/v130/botbrowser_130.0.6723.92_mac_arm64.dmg',
37
+ linux: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/v130/botbrowser_130.0.6723.117_amd64.deb',
38
+ windows: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/v130/botbrowser_130.0.6723.117_win_x86_64.7z'
39
+ }
40
+ }
41
+ end
42
+
43
+ def profiles
44
+ {
45
+ v128: {
46
+ mac: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v128/chrome128_mac_arm64.enc',
47
+ win: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v128/chrome128_win10_x86_64.enc'
48
+ },
49
+ v129: {
50
+ mac: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v129/chrome129_mac_arm64.enc'
51
+ },
52
+ v130: {
53
+ mac: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v130/chrome130_mac_arm64.enc',
54
+ iphone: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v130/chrome130_iphone.enc'
55
+ },
56
+ v132: {
57
+ mac: 'https://github.com/MiddleSchoolStudent/BotBrowser/blob/main/profiles/v132/chrome132_mac_arm64.enc',
58
+ win: 'https://github.com/MiddleSchoolStudent/BotBrowser/blob/main/profiles/v132/chrome132_win10_x86_64.enc'
59
+ }
60
+ }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'chromate/helpers'
5
+ require 'chromate/c_logger'
6
+ require 'bot_browser/downloader'
7
+
8
+ module BotBrowser
9
+ class Installer
10
+ class NotInstalledError < StandardError; end
11
+ class << self
12
+ include Chromate::Helpers
13
+
14
+ def install(version = nil)
15
+ create_config_dir
16
+ binary_path, profile_path = Downloader.download(version)
17
+ bot_browser_path = install_binary(binary_path)
18
+ bot_browser_profile_path = install_profile(profile_path)
19
+
20
+ write_config(bot_browser_path, bot_browser_profile_path)
21
+ end
22
+
23
+ def config_dir
24
+ "#{Dir.home}/.botbrowser"
25
+ end
26
+
27
+ def installed?
28
+ File.exist?("#{config_dir}/config.yml")
29
+ end
30
+
31
+ def uninstall
32
+ raise NotInstalledError, 'BotBrowser is not installed' unless installed?
33
+
34
+ config = YAML.load_file("#{config_dir}/config.yml")
35
+ Chromate::CLogger.log("Uninstalling binary at #{config["bot_browser_path"]}")
36
+ FileUtils.rm_rf(config['bot_browser_path'])
37
+ Chromate::CLogger.log("Uninstalling profile at #{config["profile"]}")
38
+ FileUtils.rm_rf(config['profile'])
39
+ FileUtils.rm_rf(config_dir)
40
+ Chromate::CLogger.log('Uninstalled')
41
+ end
42
+
43
+ private
44
+
45
+ def install_binary(binary_path)
46
+ Chromate::CLogger.log("Installing binary from #{binary_path}")
47
+ return install_binary_mac(binary_path) if mac?
48
+ return install_binary_linux(binary_path) if linux?
49
+ return install_binary_windows(binary_path) if windows?
50
+
51
+ raise 'Unsupported platform'
52
+ end
53
+
54
+ def create_config_dir
55
+ Chromate::CLogger.log("Creating config directory at #{config_dir}")
56
+ FileUtils.mkdir_p(config_dir)
57
+ end
58
+
59
+ def install_profile(profile_path)
60
+ Chromate::CLogger.log("Installing profile from #{profile_path}")
61
+ `cp #{profile_path} #{config_dir}/`
62
+
63
+ "#{config_dir}/#{File.basename(profile_path)}"
64
+ end
65
+
66
+ def install_binary_mac(binary_path)
67
+ Chromate::Binary.run('hdiutil', ['attach', binary_path])
68
+ Chromate::Binary.run('cp', ['-r', '/Volumes/Chromium/Chromium.app', '/Applications/'])
69
+ Chromate::Binary.run('hdiutil', ['detach', '/Volumes/Chromium'])
70
+ Chromate::Binary.run('xattr', ['-rd', 'com.apple.quarantine', '/Applications/Chromium.app'])
71
+ Chromate::Binary.run('codesign', ['--force', '--deep', '--sign', '-', '/Applications/Chromium.app'], need_success: false)
72
+
73
+ '/Applications/Chromium.app/Contents/MacOS/Chromium'
74
+ end
75
+
76
+ def install_binary_linux(binary_path)
77
+ Chromate::Binary.run('sudo', ['dpkg', '-i', binary_path])
78
+ Chromate::Binary.run('sudo', ['apt-get', 'install', '-f'])
79
+
80
+ '/usr/bin/chromium'
81
+ end
82
+
83
+ def install_binary_windows(binary_path)
84
+ Chromate::Binary.run('7z', ['x', binary_path])
85
+
86
+ 'chromium.exe'
87
+ end
88
+
89
+ def write_config(bot_browser_path, bot_browser_profile_path)
90
+ Chromate::CLogger.log("Writing config to #{config_dir}/config.yml")
91
+ File.write(File.expand_path("#{config_dir}/config.yml"), <<~YAML)
92
+ ---
93
+ bot_browser_path: #{bot_browser_path}
94
+ profile: #{bot_browser_profile_path}
95
+ YAML
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'chromate/c_logger'
5
+ require 'bot_browser/installer'
6
+
7
+ module BotBrowser
8
+ class << self
9
+ def install(version = nil)
10
+ Installer.install(version)
11
+ end
12
+
13
+ def uninstall
14
+ Installer.uninstall
15
+ end
16
+
17
+ def installed?
18
+ Installer.installed?
19
+ end
20
+
21
+ def load
22
+ yaml = YAML.load_file("#{Dir.home}/.botbrowser/config.yml")
23
+
24
+ Chromate.configure do |config|
25
+ ENV['CHROME_BIN'] = yaml['bot_browser_path']
26
+ config.args = [
27
+ "--bot-profile=#{yaml["profile"]}",
28
+ '--no-sandbox'
29
+ ]
30
+ config.startup_patch = false
31
+ end
32
+
33
+ Chromate::CLogger.log('BotBrowser loaded', level: :debug)
34
+ end
35
+ end
36
+ end
37
+
38
+ # Usage
39
+ # require 'bot_browser'
40
+
41
+ # BotBrowser.install
42
+ # BotBrowser.load
43
+ # browser = Chromate::Browser.new