chromate-rb 0.0.1.pre → 0.0.2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +54 -3
- data/README.md +33 -6
- data/Rakefile +48 -16
- data/docker_root/Gemfile +4 -0
- data/docker_root/Gemfile.lock +28 -0
- data/docker_root/TestInDocker.gif +0 -0
- data/docker_root/app.rb +92 -0
- data/dockerfiles/Dockerfile +21 -7
- data/dockerfiles/README.md +49 -0
- data/docs/README.md +74 -0
- data/docs/browser.md +149 -92
- data/docs/element.md +289 -0
- data/lib/bot_browser/downloader.rb +52 -0
- data/lib/bot_browser/installer.rb +81 -0
- data/lib/bot_browser.rb +39 -0
- data/lib/chromate/actions/dom.rb +28 -9
- data/lib/chromate/actions/navigate.rb +4 -5
- data/lib/chromate/actions/screenshot.rb +30 -11
- data/lib/chromate/actions/stealth.rb +47 -0
- data/lib/chromate/browser.rb +64 -12
- data/lib/chromate/c_logger.rb +7 -0
- data/lib/chromate/client.rb +40 -18
- data/lib/chromate/configuration.rb +31 -14
- data/lib/chromate/element.rb +65 -15
- data/lib/chromate/elements/select.rb +59 -7
- data/lib/chromate/hardwares/keyboard_controller.rb +34 -0
- data/lib/chromate/hardwares/keyboards/virtual_controller.rb +65 -0
- data/lib/chromate/hardwares/mouse_controller.rb +47 -11
- data/lib/chromate/hardwares/mouses/linux_controller.rb +124 -21
- data/lib/chromate/hardwares/mouses/mac_os_controller.rb +6 -6
- data/lib/chromate/hardwares/mouses/virtual_controller.rb +95 -7
- data/lib/chromate/hardwares/mouses/x11.rb +36 -0
- data/lib/chromate/hardwares.rb +16 -0
- data/lib/chromate/helpers.rb +22 -15
- data/lib/chromate/user_agent.rb +39 -15
- data/lib/chromate/version.rb +1 -1
- data/lib/chromate.rb +2 -0
- data/logo.png +0 -0
- data/results/bot.png +0 -0
- data/results/brotector.png +0 -0
- data/results/cloudflare.png +0 -0
- data/results/headers.png +0 -0
- data/results/pixelscan.png +0 -0
- metadata +20 -2
data/docs/browser.md
CHANGED
@@ -1,163 +1,220 @@
|
|
1
|
-
|
1
|
+
## `Chromate::Browser` Class
|
2
2
|
|
3
|
-
The `Chromate::Browser` class is
|
3
|
+
The `Chromate::Browser` class is responsible for controlling a browser instance using the Chrome DevTools Protocol (CDP). It provides methods for navigation, screenshots, and DOM interactions, as well as handling browser lifecycle (start and stop).
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
To create a new instance of the `Browser` class, you can pass in various options:
|
5
|
+
### Initialization
|
8
6
|
|
9
7
|
```ruby
|
10
|
-
browser = Chromate::Browser.new(
|
11
|
-
headless: true,
|
12
|
-
native_control: true,
|
13
|
-
user_data_dir: '/path/to/user/data',
|
14
|
-
record: false
|
15
|
-
)
|
8
|
+
browser = Chromate::Browser.new(options = {})
|
16
9
|
```
|
17
10
|
|
18
|
-
|
11
|
+
- **Parameters:**
|
12
|
+
- `options` (Hash, optional): Configuration options for the browser instance.
|
13
|
+
- `:chrome_path` (String): Path to the Chrome executable.
|
14
|
+
- `:user_data_dir` (String): Directory for storing user data (default: a temporary directory).
|
15
|
+
- `:headless` (Boolean): Run the browser in headless mode.
|
16
|
+
- `:xfvb` (Boolean): Use Xvfb for headless mode on Linux.
|
17
|
+
- `:native_control` (Boolean): Enable native control for enhanced undetection.
|
18
|
+
- `:record` (Boolean): Enable video recording of the browser session.
|
19
19
|
|
20
|
-
|
21
|
-
- `native_control`: Use native mouse control (default: false).
|
22
|
-
- `user_data_dir`: Directory to store user data (default: a temporary directory).
|
23
|
-
- `record`: Record the browser session (default: false).
|
24
|
-
- `xfvb`: Use xvfb for headless mode (default: false).
|
20
|
+
### Public Methods
|
25
21
|
|
26
|
-
|
22
|
+
#### `#start`
|
27
23
|
|
28
|
-
|
24
|
+
Starts the browser process and initializes the CDP client.
|
29
25
|
|
30
|
-
|
26
|
+
- **Example:**
|
27
|
+
```ruby
|
28
|
+
browser.start
|
29
|
+
```
|
31
30
|
|
31
|
+
#### `#stop`
|
32
32
|
|
33
|
+
Stops the browser process, including any associated Xvfb or video recording processes.
|
33
34
|
|
34
|
-
|
35
|
+
- **Example:**
|
36
|
+
```ruby
|
37
|
+
browser.stop
|
38
|
+
```
|
35
39
|
|
36
|
-
|
37
|
-
browser.start
|
38
|
-
```
|
40
|
+
#### `#native_control?`
|
39
41
|
|
40
|
-
|
42
|
+
Checks if native control is enabled for the browser instance.
|
41
43
|
|
42
|
-
|
44
|
+
- **Returns:**
|
45
|
+
- `Boolean`: `true` if native control is enabled, `false` otherwise.
|
43
46
|
|
47
|
+
- **Example:**
|
48
|
+
```ruby
|
49
|
+
puts "Native control enabled" if browser.native_control?
|
50
|
+
```
|
44
51
|
|
52
|
+
### Navigation Methods (from `Actions::Navigate`)
|
45
53
|
|
46
|
-
|
54
|
+
#### `#navigate_to(url)`
|
47
55
|
|
48
|
-
|
49
|
-
browser.stop
|
50
|
-
```
|
56
|
+
Navigates the browser to the specified URL.
|
51
57
|
|
52
|
-
|
58
|
+
- **Parameters:**
|
59
|
+
- `url` (String): The URL to navigate to.
|
53
60
|
|
54
|
-
|
61
|
+
- **Example:**
|
62
|
+
```ruby
|
63
|
+
browser.navigate_to('https://example.com')
|
64
|
+
```
|
55
65
|
|
56
|
-
|
57
|
-
browser.navigate_to('http://example.com')
|
58
|
-
```
|
66
|
+
#### `#wait_for_page_load`
|
59
67
|
|
60
|
-
|
68
|
+
Waits until the page has fully loaded, including the `DOMContentLoaded` event, `load` event, and `frameStoppedLoading` event.
|
61
69
|
|
62
|
-
|
70
|
+
- **Example:**
|
71
|
+
```ruby
|
72
|
+
browser.wait_for_page_load
|
73
|
+
```
|
63
74
|
|
64
|
-
|
65
|
-
element = browser.find_element('#some-element')
|
66
|
-
```
|
75
|
+
#### `#refresh`
|
67
76
|
|
68
|
-
|
77
|
+
Reloads the current page.
|
69
78
|
|
70
|
-
|
79
|
+
- **Example:**
|
80
|
+
```ruby
|
81
|
+
browser.refresh
|
82
|
+
```
|
71
83
|
|
72
|
-
|
73
|
-
browser.click_element('#some-element')
|
74
|
-
```
|
84
|
+
#### `#go_back`
|
75
85
|
|
76
|
-
|
86
|
+
Navigates back to the previous page in the browser history.
|
77
87
|
|
78
|
-
|
88
|
+
- **Example:**
|
89
|
+
```ruby
|
90
|
+
browser.go_back
|
91
|
+
```
|
79
92
|
|
80
|
-
|
81
|
-
browser.hover_element('#some-element')
|
82
|
-
```
|
93
|
+
### Screenshot Methods (from `Actions::Screenshot`)
|
83
94
|
|
84
|
-
|
95
|
+
#### `#screenshot(file_path, options = {})`
|
85
96
|
|
86
|
-
|
97
|
+
Takes a screenshot of the current page and saves it to the specified file.
|
87
98
|
|
88
|
-
|
89
|
-
|
90
|
-
|
99
|
+
- **Parameters:**
|
100
|
+
- `file_path` (String, optional): The file path to save the screenshot.
|
101
|
+
- `options` (Hash, optional): Additional options for the screenshot.
|
102
|
+
- - `full_page` (Boolean, optional): Take a full page screenshot
|
91
103
|
|
92
|
-
|
104
|
+
It will call `#xvfb_screenshot` private method if `xvfb` mode is `true`
|
93
105
|
|
94
|
-
|
106
|
+
- **Example:**
|
107
|
+
```ruby
|
108
|
+
browser.screenshot('screenshot.png')
|
109
|
+
```
|
95
110
|
|
96
|
-
|
97
|
-
browser.screenshot_to_file('screenshot.png')
|
98
|
-
```
|
111
|
+
### DOM Methods (from `Actions::Dom`)
|
99
112
|
|
100
|
-
|
113
|
+
#### `#find_element(selector)`
|
101
114
|
|
102
|
-
|
115
|
+
Finds a single element on the page using the specified CSS selector.
|
103
116
|
|
117
|
+
- **Parameters:**
|
118
|
+
- `selector` (String): The CSS selector to locate the element.
|
104
119
|
|
120
|
+
- **Returns:**
|
121
|
+
- `Chromate::Element`: The found element.
|
105
122
|
|
106
|
-
|
123
|
+
- **Example:**
|
124
|
+
```ruby
|
125
|
+
element = browser.find_element('#my-element')
|
126
|
+
puts element.text
|
127
|
+
```
|
107
128
|
|
108
|
-
|
109
|
-
puts browser.native_control? # => true or false
|
110
|
-
```
|
129
|
+
#### `#click_element(selector)`
|
111
130
|
|
112
|
-
|
131
|
+
Finds an element by selector and clicks it.
|
113
132
|
|
114
|
-
|
115
|
-
|
133
|
+
- **Parameters:**
|
134
|
+
- `selector` (String): The CSS selector of the element to click.
|
116
135
|
|
117
|
-
|
118
|
-
|
136
|
+
- **Example:**
|
137
|
+
```ruby
|
138
|
+
browser.click_element('#submit-button')
|
139
|
+
```
|
119
140
|
|
120
|
-
|
121
|
-
browser.find_element('#some-element').click
|
122
|
-
browser.screenshot_to_file('screenshot.png')
|
141
|
+
#### `#hover_element(selector)`
|
123
142
|
|
124
|
-
|
125
|
-
```
|
126
|
-
|
127
|
-
## Private Methods
|
143
|
+
Finds an element by selector and hovers over it.
|
128
144
|
|
129
|
-
|
145
|
+
- **Parameters:**
|
146
|
+
- `selector` (String): The CSS selector of the element to hover.
|
130
147
|
|
131
|
-
|
148
|
+
- **Example:**
|
149
|
+
```ruby
|
150
|
+
browser.hover_element('#hover-target')
|
151
|
+
```
|
132
152
|
|
153
|
+
#### `#type_text(selector, text)`
|
133
154
|
|
155
|
+
Finds an element by selector and types the specified text into it.
|
134
156
|
|
135
|
-
|
157
|
+
- **Parameters:**
|
158
|
+
- `selector` (String): The CSS selector of the element.
|
159
|
+
- `text` (String): The text to type into the element.
|
136
160
|
|
137
|
-
|
161
|
+
- **Example:**
|
162
|
+
```ruby
|
163
|
+
browser.type_text('#input-field', 'Hello, Chromate!')
|
164
|
+
```
|
138
165
|
|
139
|
-
|
166
|
+
#### `#select_option(selector, option)`
|
140
167
|
|
168
|
+
Selects an option from a dropdown element.
|
141
169
|
|
170
|
+
- **Parameters:**
|
171
|
+
- `selector` (String): The CSS selector of the dropdown element.
|
172
|
+
- `option` (String): The value of the option to select.
|
142
173
|
|
143
|
-
|
174
|
+
- **Example:**
|
175
|
+
```ruby
|
176
|
+
browser.select_option('#dropdown', 'option2')
|
177
|
+
```
|
144
178
|
|
145
|
-
|
179
|
+
#### `#evaluate_script(script)`
|
146
180
|
|
147
|
-
|
181
|
+
Executes the specified JavaScript expression on the page.
|
148
182
|
|
183
|
+
- **Parameters:**
|
184
|
+
- `script` (String): The JavaScript code to evaluate.
|
149
185
|
|
186
|
+
- **Returns:**
|
187
|
+
- The result of the JavaScript evaluation.
|
150
188
|
|
151
|
-
|
189
|
+
- **Example:**
|
190
|
+
```ruby
|
191
|
+
result = browser.evaluate_script('document.title')
|
192
|
+
puts "Page title: #{result}"
|
193
|
+
```
|
152
194
|
|
153
|
-
###
|
195
|
+
### Exception Handling
|
154
196
|
|
155
|
-
|
197
|
+
- The browser handles `INT` and `TERM` signals gracefully by stopping the browser process and exiting safely.
|
198
|
+
- The `stop_and_exit` method is used to ensure proper shutdown.
|
156
199
|
|
200
|
+
### Example Usage
|
157
201
|
|
202
|
+
```ruby
|
203
|
+
require 'chromate'
|
158
204
|
|
159
|
-
|
205
|
+
options = {
|
206
|
+
chrome_path: '/usr/bin/google-chrome',
|
207
|
+
headless: true,
|
208
|
+
native_control: true,
|
209
|
+
record: true
|
210
|
+
}
|
160
211
|
|
161
|
-
|
212
|
+
browser = Chromate::Browser.new(options)
|
162
213
|
|
163
|
-
|
214
|
+
browser.start
|
215
|
+
browser.navigate_to('https://example.com')
|
216
|
+
browser.screenshot('example.png')
|
217
|
+
element = browser.find_element('#main-header')
|
218
|
+
puts element.text
|
219
|
+
browser.stop
|
220
|
+
```
|
data/docs/element.md
ADDED
@@ -0,0 +1,289 @@
|
|
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
|
+
### Public Methods
|
19
|
+
|
20
|
+
#### `#mouse`
|
21
|
+
|
22
|
+
Returns the mouse controller for interacting with the element.
|
23
|
+
|
24
|
+
- **Example:**
|
25
|
+
```ruby
|
26
|
+
element.mouse.click
|
27
|
+
```
|
28
|
+
|
29
|
+
#### `#keyboard`
|
30
|
+
|
31
|
+
Returns the keyboard controller for interacting with the element.
|
32
|
+
|
33
|
+
- **Example:**
|
34
|
+
```ruby
|
35
|
+
element.keyboard.type('Hello World')
|
36
|
+
```
|
37
|
+
|
38
|
+
#### `#inspect`
|
39
|
+
|
40
|
+
Returns a string representation of the element.
|
41
|
+
|
42
|
+
- **Example:**
|
43
|
+
```ruby
|
44
|
+
puts element.inspect
|
45
|
+
```
|
46
|
+
|
47
|
+
#### `#text`
|
48
|
+
|
49
|
+
Retrieves the inner text of the element.
|
50
|
+
|
51
|
+
- **Example:**
|
52
|
+
```ruby
|
53
|
+
text = element.text
|
54
|
+
puts "Element text: #{text}"
|
55
|
+
```
|
56
|
+
|
57
|
+
#### `#html`
|
58
|
+
|
59
|
+
Retrieves the outer HTML of the element.
|
60
|
+
|
61
|
+
- **Example:**
|
62
|
+
```ruby
|
63
|
+
html = element.html
|
64
|
+
puts "Element HTML: #{html}"
|
65
|
+
```
|
66
|
+
|
67
|
+
#### `#attributes`
|
68
|
+
|
69
|
+
Returns a hash of the element's attributes.
|
70
|
+
|
71
|
+
- **Example:**
|
72
|
+
```ruby
|
73
|
+
attributes = element.attributes
|
74
|
+
puts "Element attributes: #{attributes}"
|
75
|
+
```
|
76
|
+
|
77
|
+
#### `#set_attribute(name, value)`
|
78
|
+
|
79
|
+
Sets an attribute on the element.
|
80
|
+
|
81
|
+
- **Parameters:**
|
82
|
+
- `name` (String): The name of the attribute.
|
83
|
+
- `value` (String): The value to set for the attribute.
|
84
|
+
|
85
|
+
- **Example:**
|
86
|
+
```ruby
|
87
|
+
element.set_attribute('class', 'highlighted')
|
88
|
+
```
|
89
|
+
|
90
|
+
#### `#bounding_box`
|
91
|
+
|
92
|
+
Returns a hash with the dimensions of the element's bounding box.
|
93
|
+
|
94
|
+
- **Example:**
|
95
|
+
```ruby
|
96
|
+
box = element.bounding_box
|
97
|
+
puts "Bounding box: #{box}"
|
98
|
+
```
|
99
|
+
|
100
|
+
#### `#x`
|
101
|
+
|
102
|
+
Returns the x-coordinate of the element's position.
|
103
|
+
|
104
|
+
- **Example:**
|
105
|
+
```ruby
|
106
|
+
x_position = element.x
|
107
|
+
puts "X Position: #{x_position}"
|
108
|
+
```
|
109
|
+
|
110
|
+
#### `#y`
|
111
|
+
|
112
|
+
Returns the y-coordinate of the element's position.
|
113
|
+
|
114
|
+
- **Example:**
|
115
|
+
```ruby
|
116
|
+
y_position = element.y
|
117
|
+
puts "Y Position: #{y_position}"
|
118
|
+
```
|
119
|
+
|
120
|
+
#### `#width`
|
121
|
+
|
122
|
+
Returns the width of the element.
|
123
|
+
|
124
|
+
- **Example:**
|
125
|
+
```ruby
|
126
|
+
width = element.width
|
127
|
+
puts "Element width: #{width}"
|
128
|
+
```
|
129
|
+
|
130
|
+
#### `#height`
|
131
|
+
|
132
|
+
Returns the height of the element.
|
133
|
+
|
134
|
+
- **Example:**
|
135
|
+
```ruby
|
136
|
+
height = element.height
|
137
|
+
puts "Element height: #{height}"
|
138
|
+
```
|
139
|
+
|
140
|
+
#### `#focus`
|
141
|
+
|
142
|
+
Sets focus on the element.
|
143
|
+
|
144
|
+
- **Example:**
|
145
|
+
```ruby
|
146
|
+
element.focus
|
147
|
+
```
|
148
|
+
|
149
|
+
#### `#click`
|
150
|
+
|
151
|
+
Simulates a click on the element.
|
152
|
+
|
153
|
+
- **Example:**
|
154
|
+
```ruby
|
155
|
+
element.click
|
156
|
+
```
|
157
|
+
|
158
|
+
#### `#hover`
|
159
|
+
|
160
|
+
Simulates a hover action over the element.
|
161
|
+
|
162
|
+
- **Example:**
|
163
|
+
```ruby
|
164
|
+
element.hover
|
165
|
+
```
|
166
|
+
|
167
|
+
#### `#type(text)`
|
168
|
+
|
169
|
+
Types the specified text into the element.
|
170
|
+
|
171
|
+
- **Parameters:**
|
172
|
+
- `text` (String): The text to type.
|
173
|
+
|
174
|
+
- **Example:**
|
175
|
+
```ruby
|
176
|
+
element.type('Hello, Chromate!')
|
177
|
+
```
|
178
|
+
|
179
|
+
#### `#press_enter`
|
180
|
+
|
181
|
+
Simulates pressing the Enter key and submits the form if the element is inside one.
|
182
|
+
|
183
|
+
- **Example:**
|
184
|
+
```ruby
|
185
|
+
element.press_enter
|
186
|
+
```
|
187
|
+
|
188
|
+
#### `#drop_to(element)`
|
189
|
+
|
190
|
+
Drag current element and drop to target
|
191
|
+
|
192
|
+
- **Example:**
|
193
|
+
```ruby
|
194
|
+
element.drop_to(target_element)
|
195
|
+
```
|
196
|
+
|
197
|
+
#### `#find_element(selector)`
|
198
|
+
|
199
|
+
Finds a single child element matching the given selector.
|
200
|
+
|
201
|
+
- **Parameters:**
|
202
|
+
- `selector` (String): The CSS selector to find the element.
|
203
|
+
|
204
|
+
- **Returns:**
|
205
|
+
- `Chromate::Element`: The found element.
|
206
|
+
|
207
|
+
- **Example:**
|
208
|
+
```ruby
|
209
|
+
child_element = element.find_element('.child')
|
210
|
+
puts child_element.text
|
211
|
+
```
|
212
|
+
|
213
|
+
#### `#find_elements(selector, max: 0)`
|
214
|
+
|
215
|
+
Finds all child elements matching the given selector.
|
216
|
+
|
217
|
+
- **Parameters:**
|
218
|
+
- `selector` (String): The CSS selector to find elements.
|
219
|
+
- `max` (Integer, optional): The maximum number of elements to find (0 for no limit).
|
220
|
+
|
221
|
+
- **Returns:**
|
222
|
+
- `Array<Chromate::Element>`: An array of found elements.
|
223
|
+
|
224
|
+
- **Example:**
|
225
|
+
```ruby
|
226
|
+
elements = element.find_elements('.item')
|
227
|
+
elements.each { |el| puts el.text }
|
228
|
+
```
|
229
|
+
|
230
|
+
#### `#shadow_root_id`
|
231
|
+
|
232
|
+
Returns the shadow root ID of the element if it has one.
|
233
|
+
|
234
|
+
- **Example:**
|
235
|
+
```ruby
|
236
|
+
shadow_id = element.shadow_root_id
|
237
|
+
puts "Shadow root ID: #{shadow_id}"
|
238
|
+
```
|
239
|
+
|
240
|
+
#### `#shadow_root?`
|
241
|
+
|
242
|
+
Checks if the element has a shadow root.
|
243
|
+
|
244
|
+
- **Returns:**
|
245
|
+
- `Boolean`: `true` if the element has a shadow root, otherwise `false`.
|
246
|
+
|
247
|
+
- **Example:**
|
248
|
+
```ruby
|
249
|
+
if element.shadow_root?
|
250
|
+
puts "Element has a shadow root."
|
251
|
+
end
|
252
|
+
```
|
253
|
+
|
254
|
+
#### `#find_shadow_child(selector)`
|
255
|
+
|
256
|
+
Finds a single child element inside the shadow root using the given selector.
|
257
|
+
|
258
|
+
- **Parameters:**
|
259
|
+
- `selector` (String): The CSS selector to find the shadow child element.
|
260
|
+
|
261
|
+
- **Returns:**
|
262
|
+
- `Chromate::Element` or `nil`: The found element or `nil` if not found.
|
263
|
+
|
264
|
+
- **Example:**
|
265
|
+
```ruby
|
266
|
+
shadow_child = element.find_shadow_child('.shadow-element')
|
267
|
+
puts shadow_child.text if shadow_child
|
268
|
+
```
|
269
|
+
|
270
|
+
#### `#find_shadow_children(selector)`
|
271
|
+
|
272
|
+
Finds all child elements inside the shadow root using the given selector.
|
273
|
+
|
274
|
+
- **Parameters:**
|
275
|
+
- `selector` (String): The CSS selector to find shadow child elements.
|
276
|
+
|
277
|
+
- **Returns:**
|
278
|
+
- `Array<Chromate::Element>`: An array of found elements.
|
279
|
+
|
280
|
+
- **Example:**
|
281
|
+
```ruby
|
282
|
+
shadow_elements = element.find_shadow_children('.shadow-item')
|
283
|
+
shadow_elements.each { |el| puts el.text }
|
284
|
+
```
|
285
|
+
|
286
|
+
### Exceptions
|
287
|
+
|
288
|
+
- `NotFoundError`: Raised when an element cannot be found with the given selector.
|
289
|
+
- `InvalidSelectorError`: Raised when the selector cannot resolve to a valid element.
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BotBrowser
|
4
|
+
class Downloader
|
5
|
+
class << self
|
6
|
+
def download(version = nil)
|
7
|
+
version ||= versions.keys.first
|
8
|
+
version = version.to_sym
|
9
|
+
platform = :mac
|
10
|
+
arch = :arm64
|
11
|
+
binary_path = download_file(versions[version][platform][arch][:binary], "/tmp/botbrowser_#{version}_#{platform}_#{arch}.dmg")
|
12
|
+
profile_path = download_file(versions[version][platform][arch][:profile], "/tmp/botbrowser_#{version}_#{platform}_#{arch}.json")
|
13
|
+
|
14
|
+
[binary_path, profile_path]
|
15
|
+
end
|
16
|
+
|
17
|
+
def download_file(url, path)
|
18
|
+
Chromate::CLogger.log("Downloading #{url} to #{path}")
|
19
|
+
`curl -L #{url} >> #{path}`
|
20
|
+
|
21
|
+
path
|
22
|
+
end
|
23
|
+
|
24
|
+
def versions
|
25
|
+
{
|
26
|
+
v130: {
|
27
|
+
mac: {
|
28
|
+
arm64: {
|
29
|
+
binary: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/v130/botbrowser_130.0.6723.92_mac_arm64.dmg',
|
30
|
+
profile: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v130/chrome130-macarm.enc'
|
31
|
+
}
|
32
|
+
},
|
33
|
+
linux: {
|
34
|
+
x64: {
|
35
|
+
binary: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/v130/botbrowser_130.0.6723.117_amd64.deb',
|
36
|
+
# no specifi linux profile for moment
|
37
|
+
profile: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v130/chrome130-macarm.enc'
|
38
|
+
}
|
39
|
+
},
|
40
|
+
windows: {
|
41
|
+
x64: {
|
42
|
+
binary: 'https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/v130/botbrowser_130.0.6723.117_win_x86_64.7z',
|
43
|
+
# no specific windows profile for moment
|
44
|
+
profile: 'https://raw.githubusercontent.com/MiddleSchoolStudent/BotBrowser/refs/heads/main/profiles/v130/chrome130-macarm.enc'
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|