ferrumwizard 0.1.0 → 0.1.1

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: ebfbe644929b142f88f8dc30e66db208bc8fa6c328eea266b18b6e6bf5c08da8
4
- data.tar.gz: f5e5403ad7dc857b0086213ef42e521fb91232fd93466036d22c35d269629804
3
+ metadata.gz: eb46fd03834d035f319b5654848eb8db05c4d8d870b59f261657fedc42b60222
4
+ data.tar.gz: a0e9d66110acbf0439494087795620675b10743eb767891e28cd9d0db55b4475
5
5
  SHA512:
6
- metadata.gz: 44ac0fdfca21e6b4bfdc42afe8bb7826de0b1df0c003b86bb19c025795633c9cad17962cd842762bb7c23c822757bd151a26dd11502015f7484f01e151d7f297
7
- data.tar.gz: 5ac3fd607f57b5b422b2e81b32ab29106bf80691ae445dcca405808fd087718d177006c790c73956521954e306ddc2fbea9597b1790cf5049027ccca9f201f11
6
+ metadata.gz: f7f3129f81ae7a79646f3ce13299a174265f7d42c1be53ef88dffe9461fddc42793c28b97ba55703d5ccfe62ef5aa5a9dd3a80665d3b3a897550de0d83325946
7
+ data.tar.gz: c7c5bac0cde40acc8d91a07e55890043bc16ae08d8533b4f0cf24719419cf62d5ee012b059dfd5d15befcd619140632cd4194dbb3294e09c1038f022ebccd524
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -8,96 +8,214 @@ require 'ferrum'
8
8
 
9
9
  class FerrumWizard
10
10
 
11
- attr_reader :browser, :links
11
+ attr_reader :browser, :links, :radio, :buttons, :js_methods
12
12
 
13
13
  def initialize(url, headless: true, debug: false)
14
14
 
15
15
  @url, @debug = url, debug
16
16
  @browser = Ferrum::Browser.new headless: headless
17
-
17
+ sleep 2
18
+ end
19
+
20
+ def inspect()
21
+ "#<FerrumWizard>"
18
22
  end
19
23
 
20
- def login(username, password)
24
+ def login(usernamex=nil, passwordx=nil, username: usernamex, password: passwordx)
25
+
26
+ puts 'username: ' + username.inspect if @debug
21
27
 
22
28
  b = @browser
23
29
  b.goto(@url)
24
-
30
+ @browser.network.wait_for_idle
31
+ sleep 3
25
32
 
26
33
  # search for the username input box
27
34
  e_username = b.at_xpath('//input[@type="email"]')
28
-
35
+ puts 'e_username: ' + e_username.inspect if @debug
36
+ sleep 1
29
37
  # search for the password input box
30
38
  e_password = b.at_xpath('//input[@type="password"]')
31
-
32
- if e_username and e_password then
33
-
34
- e_username.focus.type(username)
35
- e_password.focus.type(password, :Enter)
36
-
39
+ sleep 1
40
+
41
+ if username and e_username then
42
+ puts 'entering the username' if @debug
43
+ e_username.focus.type(username)
44
+ sleep 1
37
45
  end
38
46
 
47
+ e_password.focus.type(password, :Enter) if e_password
48
+ @browser.network.wait_for_idle
49
+
39
50
  sleep 4
40
- fetch_links()
41
- self
51
+
52
+ scan_page()
42
53
 
43
- end
54
+ end
44
55
 
45
56
  def quit
46
57
  @browser.quit
47
58
  end
59
+
60
+ def scan_page()
61
+
62
+ @doc = Rexle.new @browser.body
63
+ fetch_links()
64
+ scan_form_elements()
65
+ scan_js_links()
66
+ self
67
+ end
48
68
 
49
69
  def to_rb()
50
70
  end
51
71
 
52
72
  private
53
73
 
74
+ def fetch_buttons()
75
+
76
+ a2 = @browser.xpath('//input[@type="button"]')
77
+ @buttons = a2.flat_map do |x|
78
+
79
+ a = x.value.split(/\W+/).map {|label| [label, x]}
80
+ a << [x.value, x]
81
+ a + a.map {|x, obj| [x.downcase, obj]}
82
+
83
+ end.to_h
84
+
85
+ names = @buttons.keys.map(&:downcase).uniq.select {|x| x =~ /^\w+$/}
86
+ buttons = @buttons
87
+
88
+ names.each do |name|
89
+
90
+ define_singleton_method name.to_sym do
91
+ buttons[name].click
92
+ @browser.network.wait_for_idle
93
+ sleep = 1
94
+ self
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
54
101
  def fetch_links()
102
+
103
+ all_links = @doc.root.xpath('//a')
55
104
 
56
- b = @browser
57
- doc = Rexle.new b.body
58
- all_links = doc.root.xpath('//a')
59
-
105
+ all_links.each do |x|
106
+
107
+ if x.plaintext.empty? then
108
+ x.text = x.attributes[:href].sub(/\.\w+$/,'')[/([^\/]+)$/].split(/[_]|(?=[A-Z])/).join(' ')
109
+ else
110
+ x.text = x.plaintext.gsub('&amp;','&')
111
+ end
112
+
113
+ end
114
+
60
115
  valid_links = all_links.reject do |x|
61
116
 
62
117
  puts 'x: ' + x.inspect if @debug
63
- s = x.plaintext.gsub('&amp;','&')
64
- r = (x.attributes[:target] == '_blank') | s.empty?
118
+ r = (x.attributes[:target] == '_blank')
65
119
 
66
120
  puts 'r: ' + r.inspect if @debug
67
121
  r
68
122
 
69
- end.map {|x| all_links.index x}
123
+ end
124
+ indices = valid_links.map {|x| all_links.index x}
70
125
 
71
- active_links = b.xpath('//a')
72
- valid_active_links = valid_links.map {|n| active_links[n]}
126
+ active_links = @browser.xpath('//a')
127
+ valid_active_links = indices.map {|n| active_links[n]}
73
128
 
74
129
 
75
- @links = valid_active_links.flat_map do |x|
76
- a = x.text.split(/\W+/).map {|label| [label, x]} << [x.text, x]
130
+ @links = valid_active_links.flat_map.with_index do |x, i|
131
+
132
+ a = valid_links[i].text.split(/\W+/).map {|label| [label, x]}
133
+ a << [valid_links[i].text, x]
134
+
135
+ puts 'a: ' + a.inspect if @debug
77
136
  a + a.map {|x, obj| [x.downcase, obj]}
78
137
  end.to_h
79
138
 
80
- names = @links.keys.map(&:downcase).uniq.select {|x| x =~ /^\w+$/}
139
+ names = @links.keys.map(&:downcase).uniq.select {|x| x =~ /^[\w ]+$/}
81
140
  links = @links
82
141
 
83
142
  names.each do |name|
84
143
 
85
- define_singleton_method name.to_sym do
144
+ define_singleton_method name.gsub(/ +/,'_').to_sym do
86
145
  links[name].click
87
- sleep 3
146
+ sleep 1
147
+ scan_page()
88
148
  self
89
149
  end
90
150
 
91
151
  end
92
152
 
93
- end
153
+ end
154
+
155
+ def scan_form_elements()
156
+
157
+ # find radio buttons
158
+
159
+ #a = doc.root.xpath('//input[@type="radio"]')
160
+ a = @browser.xpath('//input[@type="radio"]')
161
+ #h = a.group_by {|x| x.attributes[:name]}
162
+ h = a.group_by {|x| x.attribute('name')}
163
+ @radio = h.values
164
+ define_singleton_method(:on) { @radio[0][0].click; self }
165
+ define_singleton_method(:off) { @radio[0][1].click; self }
166
+
167
+ fetch_buttons()
168
+
169
+ end
170
+
171
+ def scan_js_links()
172
+
173
+ @js_methods = {}
174
+ b = @browser
175
+
176
+ b.xpath('//a').select {|x| x.attribute('href') =~ /^javascript/}.each do |e|
177
+
178
+
179
+ s = e.attribute('href')[/(?<=^javascript:)[^\(]+/]
180
+ puts 's: ' + s.inspect
181
+ a = s.split(/\W+|(?=[A-Z])/).map {|label| [label, s]}
182
+ a << [s, s]
183
+ a << [s.split(/\W+|(?=[A-Z])/).join('_'), s]
184
+ a << [s.split(/\W+|(?=[A-Z])/).join('_').downcase, s]
185
+ #@js_methods[s] = a
186
+
187
+ a.concat a.map {|x, name| [x.downcase, name] }
188
+
189
+ puts 'a: ' + a.inspect
190
+
191
+ a.uniq.select {|x, _| x =~ /^[a-z0-9_]+$/}.each do |x, name|
192
+
193
+ if @debug then
194
+ puts 'x: ' + x.inspect
195
+ puts 'name: ' + name.inspect
196
+ end
197
+
198
+ define_singleton_method(x.to_sym) do |*args|
199
+ #args = raw_args.map {|x| x[/^[0-9]+$/] ? x.to_i : x}
200
+ js_method = "%s(%s)" % [name, args.map(&:inspect).join(', ')]
201
+ puts 'js_method: ' + js_method.inspect if @debug
202
+ @browser.evaluate(js_method)
203
+ @browser.network.wait_for_idle
204
+ sleep 4
205
+ self.scan_page()
206
+ end
207
+
208
+ end
209
+
210
+ end
211
+ end
94
212
 
95
213
  def method_missing(method_name, *args)
96
214
 
215
+ puts 'method_missing: ' + method_name.inspect if @debug
97
216
  node = @browser.at_css '.' + method_name.to_s
98
217
  node.text if node
99
218
 
100
219
  end
101
220
 
102
221
  end
103
-
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferrumwizard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -35,7 +35,7 @@ cert_chain:
35
35
  7e24hNRMt3t/JE9ogEO4JzFUH2vq2zzR5X9JQqEclWfwHi4cf8bZFJ7spjZQPjSZ
36
36
  Ok3rs0A+kW4ixAj1rDYuoyG/
37
37
  -----END CERTIFICATE-----
38
- date: 2020-07-30 00:00:00.000000000 Z
38
+ date: 2020-08-01 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: rexle
metadata.gz.sig CHANGED
Binary file