locatine 0.01659 → 0.01811
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/locatine/app/manifest.json +1 -1
- data/lib/locatine/for_search/data_generate.rb +100 -0
- data/lib/locatine/for_search/data_logic.rb +54 -0
- data/lib/locatine/for_search/dialog_logic.rb +118 -0
- data/lib/locatine/for_search/file_work.rb +65 -0
- data/lib/locatine/for_search/find_by_css.rb +47 -0
- data/lib/locatine/for_search/find_by_guess.rb +65 -0
- data/lib/locatine/for_search/find_by_locator.rb +87 -0
- data/lib/locatine/for_search/find_by_magic.rb +117 -0
- data/lib/locatine/for_search/find_logic.rb +77 -0
- data/lib/locatine/for_search/helpers.rb +100 -0
- data/lib/locatine/for_search/highlight.rb +42 -0
- data/lib/locatine/for_search/listening.rb +47 -0
- data/lib/locatine/for_search/merge.rb +38 -0
- data/lib/locatine/for_search/public.rb +118 -0
- data/lib/locatine/for_search/saying.rb +142 -0
- data/lib/locatine/for_search/xpath_generator.rb +50 -0
- data/lib/locatine/for_search.rb +6 -0
- data/lib/locatine/search.rb +32 -30
- data/lib/locatine/version.rb +1 -1
- metadata +19 -17
- data/lib/locatine/data_generate.rb +0 -98
- data/lib/locatine/data_logic.rb +0 -53
- data/lib/locatine/dialog_actions.rb +0 -71
- data/lib/locatine/dialog_logic.rb +0 -118
- data/lib/locatine/file_work.rb +0 -61
- data/lib/locatine/find_by_css.rb +0 -45
- data/lib/locatine/find_by_guess.rb +0 -62
- data/lib/locatine/find_by_locator.rb +0 -84
- data/lib/locatine/find_by_magic.rb +0 -114
- data/lib/locatine/find_logic.rb +0 -77
- data/lib/locatine/helpers.rb +0 -91
- data/lib/locatine/highlight.rb +0 -41
- data/lib/locatine/merge.rb +0 -36
- data/lib/locatine/public.rb +0 -116
- data/lib/locatine/xpath_generator.rb +0 -47
data/lib/locatine/search.rb
CHANGED
@@ -4,21 +4,22 @@ require 'fileutils'
|
|
4
4
|
require 'chromedriver-helper'
|
5
5
|
|
6
6
|
# Internal requires
|
7
|
-
require 'locatine/merge'
|
8
|
-
require 'locatine/public'
|
9
|
-
require 'locatine/
|
10
|
-
require 'locatine/
|
11
|
-
require 'locatine/
|
12
|
-
require 'locatine/
|
13
|
-
require 'locatine/
|
14
|
-
require 'locatine/
|
15
|
-
require 'locatine/
|
16
|
-
require 'locatine/
|
17
|
-
require 'locatine/
|
18
|
-
require 'locatine/
|
19
|
-
require 'locatine/
|
20
|
-
require 'locatine/
|
21
|
-
require 'locatine/
|
7
|
+
require 'locatine/for_search/merge'
|
8
|
+
require 'locatine/for_search/public'
|
9
|
+
require 'locatine/for_search/saying'
|
10
|
+
require 'locatine/for_search/helpers'
|
11
|
+
require 'locatine/for_search/file_work'
|
12
|
+
require 'locatine/for_search/highlight'
|
13
|
+
require 'locatine/for_search/data_logic'
|
14
|
+
require 'locatine/for_search/find_logic'
|
15
|
+
require 'locatine/for_search/find_by_css'
|
16
|
+
require 'locatine/for_search/dialog_logic'
|
17
|
+
require 'locatine/for_search/find_by_magic'
|
18
|
+
require 'locatine/for_search/find_by_guess'
|
19
|
+
require 'locatine/for_search/data_generate'
|
20
|
+
require 'locatine/for_search/listening'
|
21
|
+
require 'locatine/for_search/xpath_generator'
|
22
|
+
require 'locatine/for_search/find_by_locator'
|
22
23
|
|
23
24
|
module Locatine
|
24
25
|
##
|
@@ -26,21 +27,22 @@ module Locatine
|
|
26
27
|
#
|
27
28
|
# Locatine can search.
|
28
29
|
class Search
|
29
|
-
include Locatine::Merge
|
30
|
-
include Locatine::Public
|
31
|
-
include Locatine::
|
32
|
-
include Locatine::
|
33
|
-
include Locatine::
|
34
|
-
include Locatine::
|
35
|
-
include Locatine::
|
36
|
-
include Locatine::
|
37
|
-
include Locatine::
|
38
|
-
include Locatine::
|
39
|
-
include Locatine::
|
40
|
-
include Locatine::
|
41
|
-
include Locatine::
|
42
|
-
include Locatine::
|
43
|
-
include Locatine::
|
30
|
+
include Locatine::ForSearch::Merge
|
31
|
+
include Locatine::ForSearch::Public
|
32
|
+
include Locatine::ForSearch::Saying
|
33
|
+
include Locatine::ForSearch::Helpers
|
34
|
+
include Locatine::ForSearch::FileWork
|
35
|
+
include Locatine::ForSearch::DataLogic
|
36
|
+
include Locatine::ForSearch::Listening
|
37
|
+
include Locatine::ForSearch::FindLogic
|
38
|
+
include Locatine::ForSearch::Highlight
|
39
|
+
include Locatine::ForSearch::FindByCss
|
40
|
+
include Locatine::ForSearch::FindByMagic
|
41
|
+
include Locatine::ForSearch::DialogLogic
|
42
|
+
include Locatine::ForSearch::FindByGuess
|
43
|
+
include Locatine::ForSearch::DataGenerate
|
44
|
+
include Locatine::ForSearch::FindByLocator
|
45
|
+
include Locatine::ForSearch::XpathGenerator
|
44
46
|
|
45
47
|
attr_accessor :data,
|
46
48
|
:depth,
|
data/lib/locatine/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locatine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.01811'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergei Seleznev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -124,25 +124,27 @@ files:
|
|
124
124
|
- lib/locatine/app/popup.css
|
125
125
|
- lib/locatine/app/popup.html
|
126
126
|
- lib/locatine/app/popup.js
|
127
|
-
- lib/locatine/
|
128
|
-
- lib/locatine/
|
129
|
-
- lib/locatine/
|
130
|
-
- lib/locatine/dialog_logic.rb
|
131
|
-
- lib/locatine/file_work.rb
|
132
|
-
- lib/locatine/find_by_css.rb
|
133
|
-
- lib/locatine/find_by_guess.rb
|
134
|
-
- lib/locatine/find_by_locator.rb
|
135
|
-
- lib/locatine/find_by_magic.rb
|
136
|
-
- lib/locatine/find_logic.rb
|
137
|
-
- lib/locatine/helpers.rb
|
138
|
-
- lib/locatine/highlight.rb
|
127
|
+
- lib/locatine/for_search.rb
|
128
|
+
- lib/locatine/for_search/data_generate.rb
|
129
|
+
- lib/locatine/for_search/data_logic.rb
|
130
|
+
- lib/locatine/for_search/dialog_logic.rb
|
131
|
+
- lib/locatine/for_search/file_work.rb
|
132
|
+
- lib/locatine/for_search/find_by_css.rb
|
133
|
+
- lib/locatine/for_search/find_by_guess.rb
|
134
|
+
- lib/locatine/for_search/find_by_locator.rb
|
135
|
+
- lib/locatine/for_search/find_by_magic.rb
|
136
|
+
- lib/locatine/for_search/find_logic.rb
|
137
|
+
- lib/locatine/for_search/helpers.rb
|
138
|
+
- lib/locatine/for_search/highlight.rb
|
139
|
+
- lib/locatine/for_search/listening.rb
|
140
|
+
- lib/locatine/for_search/merge.rb
|
141
|
+
- lib/locatine/for_search/public.rb
|
142
|
+
- lib/locatine/for_search/saying.rb
|
143
|
+
- lib/locatine/for_search/xpath_generator.rb
|
139
144
|
- lib/locatine/large_scripts/css.js
|
140
145
|
- lib/locatine/large_scripts/dimensions.js
|
141
|
-
- lib/locatine/merge.rb
|
142
|
-
- lib/locatine/public.rb
|
143
146
|
- lib/locatine/search.rb
|
144
147
|
- lib/locatine/version.rb
|
145
|
-
- lib/locatine/xpath_generator.rb
|
146
148
|
homepage: https://github.com/sseleznevqa/locatine
|
147
149
|
licenses:
|
148
150
|
- MIT
|
@@ -1,98 +0,0 @@
|
|
1
|
-
module Locatine
|
2
|
-
##
|
3
|
-
# Collecting data of element and making it dynamic
|
4
|
-
module DataGenerate
|
5
|
-
private
|
6
|
-
|
7
|
-
def real_text_of(element)
|
8
|
-
element.text == element.inner_html ? element.text : ''
|
9
|
-
end
|
10
|
-
|
11
|
-
def mesure(element)
|
12
|
-
xy = element.location
|
13
|
-
wh = element.size
|
14
|
-
return xy.x, xy.y, wh.width, wh.height
|
15
|
-
end
|
16
|
-
|
17
|
-
def get_dynamic_tag(element, vars)
|
18
|
-
tag = element.tag_name
|
19
|
-
tag = "\#{tag}" if vars[:tag] == tag
|
20
|
-
push_hash('tag', tag, 'tag')
|
21
|
-
end
|
22
|
-
|
23
|
-
def get_dynamic_text(element, vars)
|
24
|
-
attrs = []
|
25
|
-
real_text_of(element).split(/['" ]/).each do |word|
|
26
|
-
final = if !vars[:text].to_s.strip.empty?
|
27
|
-
word.gsub(vars[:text].to_s, "\#{text}")
|
28
|
-
else
|
29
|
-
word
|
30
|
-
end
|
31
|
-
attrs.push push_hash('text', final, 'text') unless final.empty?
|
32
|
-
end
|
33
|
-
attrs
|
34
|
-
end
|
35
|
-
|
36
|
-
def process_dimension(name, value, vars)
|
37
|
-
s_name = name.to_s
|
38
|
-
value = value.to_s.gsub(vars[name], "\#{#{s_name}}") if vars[name]
|
39
|
-
value
|
40
|
-
end
|
41
|
-
|
42
|
-
def processed_dimensions(element, vars)
|
43
|
-
x, y, width, height = mesure(element)
|
44
|
-
x = process_dimension(:x, x, vars)
|
45
|
-
y = process_dimension(:y, y, vars)
|
46
|
-
width = process_dimension(:width, width, vars)
|
47
|
-
height = process_dimension(:height, height, vars)
|
48
|
-
return x, y, width, height
|
49
|
-
end
|
50
|
-
|
51
|
-
def get_dimensions(element, vars)
|
52
|
-
resolution = window_size
|
53
|
-
x, y, w, h = processed_dimensions(element, vars)
|
54
|
-
push_hash(resolution, "#{x}*#{y}*#{w}*#{h}", 'dimensions')
|
55
|
-
end
|
56
|
-
|
57
|
-
def hash_by_style(style, value, vars)
|
58
|
-
value.gsub!(vars[style.to_sym], "\#{#{style}}") if vars[style.to_sym]
|
59
|
-
push_hash(style, value, 'css')
|
60
|
-
end
|
61
|
-
|
62
|
-
def get_raw_css(element)
|
63
|
-
test_script = 'return typeof(arguments[0])'
|
64
|
-
ok = engine.execute_script(test_script, element) == 'object'
|
65
|
-
script = 'return getComputedStyle(arguments[0]).cssText'
|
66
|
-
return engine.execute_script(script, element) if ok
|
67
|
-
end
|
68
|
-
|
69
|
-
def get_dynamic_css(element, vars)
|
70
|
-
attrs = []
|
71
|
-
raw = get_raw_css(element)
|
72
|
-
if raw
|
73
|
-
styles = css_text_to_hash(get_raw_css(element))
|
74
|
-
(styles.to_a - @default_styles).to_h.each_pair do |style, value|
|
75
|
-
hash = hash_by_style(style, value, vars)
|
76
|
-
attrs.push(hash) if hash
|
77
|
-
end
|
78
|
-
end
|
79
|
-
attrs
|
80
|
-
end
|
81
|
-
|
82
|
-
##
|
83
|
-
# Collecting attributes of the element
|
84
|
-
def get_attributes(element)
|
85
|
-
attributes = element.attributes
|
86
|
-
array = []
|
87
|
-
attributes.each_pair do |name, value|
|
88
|
-
next if name.to_s == 'locatineclass' # Should never happen
|
89
|
-
|
90
|
-
value.split(/['" ]/).reject(&:empty?).uniq.each do |part|
|
91
|
-
array.push('name' => name.to_s, 'type' => 'attribute',
|
92
|
-
'value' => part)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
array
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
data/lib/locatine/data_logic.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
module Locatine
|
2
|
-
##
|
3
|
-
# Logic of collecting data of the element
|
4
|
-
module DataLogic
|
5
|
-
private
|
6
|
-
|
7
|
-
def get_dynamic_attributes(element, vars)
|
8
|
-
attrs = []
|
9
|
-
get_attributes(element).each do |hash|
|
10
|
-
if vars[hash['name'].to_sym]
|
11
|
-
hash['value'].gsub!(vars[hash['name'].to_sym], "\#{#{hash['name']}}")
|
12
|
-
end
|
13
|
-
attrs.push hash
|
14
|
-
end
|
15
|
-
attrs
|
16
|
-
end
|
17
|
-
|
18
|
-
##
|
19
|
-
# Generating array of hashes representing data of the element
|
20
|
-
def get_element_info(element, vars, depth)
|
21
|
-
attrs = get_dynamic_attributes(element, vars)
|
22
|
-
attrs.push get_dynamic_tag(element, vars)
|
23
|
-
attrs += get_dynamic_text(element, vars)
|
24
|
-
attrs += get_dynamic_css(element, vars) if depth.to_i.zero? && visual?
|
25
|
-
attrs.push get_dimensions(element, vars) if depth.to_i.zero? && visual?
|
26
|
-
attrs
|
27
|
-
end
|
28
|
-
|
29
|
-
##
|
30
|
-
# Generating data for group of elements
|
31
|
-
def generate_data(result, vars)
|
32
|
-
family = {}
|
33
|
-
result.each do |item|
|
34
|
-
family = get_commons(get_family_info(item, vars), family)
|
35
|
-
end
|
36
|
-
family
|
37
|
-
end
|
38
|
-
|
39
|
-
##
|
40
|
-
# Getting element\\parents information
|
41
|
-
def get_family_info(element, vars)
|
42
|
-
i = 0
|
43
|
-
attributes = {}
|
44
|
-
while i != @depth
|
45
|
-
attributes[i.to_s] = get_element_info(element, vars, i)
|
46
|
-
i += 1
|
47
|
-
element = element.parent
|
48
|
-
i = @depth unless element.exists?
|
49
|
-
end
|
50
|
-
attributes
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
module Locatine
|
2
|
-
##
|
3
|
-
# Simple actions about communicating with chrome extension (and user)
|
4
|
-
module DialogActions
|
5
|
-
private
|
6
|
-
|
7
|
-
##
|
8
|
-
# Setting attribute of locatine div (way to communicate)
|
9
|
-
def send_to_app(what, value, bro = engine)
|
10
|
-
fix_iframe
|
11
|
-
bro.wd.execute_script(
|
12
|
-
%[if (document.getElementById('locatine_magic_div')){
|
13
|
-
const magic_div = document.getElementById('locatine_magic_div');
|
14
|
-
return magic_div.setAttribute("#{what}", "#{value}")}]
|
15
|
-
)
|
16
|
-
fix_iframe
|
17
|
-
end
|
18
|
-
|
19
|
-
##
|
20
|
-
# Getting attribute of locatine div (way to communicate)
|
21
|
-
def get_from_app(what)
|
22
|
-
fix_iframe
|
23
|
-
result = engine.wd.execute_script(
|
24
|
-
%[if (document.getElementById('locatine_magic_div')) {
|
25
|
-
const magic_div = document.getElementById('locatine_magic_div');
|
26
|
-
return magic_div.getAttribute("#{what}")}]
|
27
|
-
)
|
28
|
-
fix_iframe
|
29
|
-
result
|
30
|
-
end
|
31
|
-
|
32
|
-
def fix_iframe
|
33
|
-
@iframe = @browser.iframe(@iframe.selector) if @iframe && @iframe.stale?
|
34
|
-
end
|
35
|
-
|
36
|
-
def push_title(text)
|
37
|
-
puts text
|
38
|
-
send_to_app('locatinetitle', text)
|
39
|
-
end
|
40
|
-
|
41
|
-
##
|
42
|
-
# Sending request to locatine app
|
43
|
-
def start_listening(scope, name)
|
44
|
-
push_title "You are selecting #{name} in #{scope}"
|
45
|
-
send_to_app('locatinestyle', 'blocked', @browser) if @iframe
|
46
|
-
send_to_app('locatinehint', 'Toggle single//collection mode button if '\
|
47
|
-
'you need. If you want to do some actions on the page toggle Locatine'\
|
48
|
-
' waiting button. You also can select element on devtools -> Elements.'\
|
49
|
-
' Do not forget to confirm your selection.')
|
50
|
-
send_to_app('locatinestyle', 'set_true')
|
51
|
-
sleep 0.5
|
52
|
-
end
|
53
|
-
|
54
|
-
def tag_index
|
55
|
-
tag = get_from_app('tag')
|
56
|
-
tag = tag.downcase unless tag.nil?
|
57
|
-
index = get_from_app('index').to_i
|
58
|
-
return tag, index
|
59
|
-
end
|
60
|
-
|
61
|
-
def response_action(element)
|
62
|
-
send_to_app('locatineconfirmed', 'ok')
|
63
|
-
push_title 'Right now you are defining nothing. So no button will work'
|
64
|
-
send_to_app('locatinehint', 'Place for a smart hint here')
|
65
|
-
mass_highlight_turn(element, false)
|
66
|
-
send_to_app('locatinestyle', 'set_false')
|
67
|
-
send_to_app('locatinestyle', 'ok', @browser) if @iframe
|
68
|
-
sleep 1
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,118 +0,0 @@
|
|
1
|
-
module Locatine
|
2
|
-
##
|
3
|
-
# Logic of recieving element selected by user
|
4
|
-
module DialogLogic
|
5
|
-
private
|
6
|
-
|
7
|
-
def suggest_element(element, vars, name, scope)
|
8
|
-
attributes = {}
|
9
|
-
if !element.nil?
|
10
|
-
attributes = generate_data(element, vars)
|
11
|
-
push_title("#{element.length} elements found as #{name} in #{scope}.")
|
12
|
-
elsif name.length >= 5
|
13
|
-
push_title("Locatine is trying to guess what is #{name} in #{scope}.")
|
14
|
-
element, attributes = find_by_guess(scope, name, vars)
|
15
|
-
end
|
16
|
-
mass_highlight_turn(element) if element
|
17
|
-
return element, attributes
|
18
|
-
end
|
19
|
-
|
20
|
-
def add_selected_attributes(new_attributes, attributes)
|
21
|
-
if get_from_app('locatinecollection') == 'true'
|
22
|
-
get_commons(new_attributes, attributes.to_h)
|
23
|
-
else
|
24
|
-
new_attributes
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def selected_element_attributes(tag, index, vars)
|
29
|
-
generate_data([engine.elements(tag_name: tag)[index]], vars).to_h
|
30
|
-
end
|
31
|
-
|
32
|
-
def selected_element(tag, index, vars, attributes)
|
33
|
-
new_attributes = selected_element_attributes(tag, index, vars)
|
34
|
-
new_attributes = add_selected_attributes(new_attributes, attributes)
|
35
|
-
element = find_by_data(new_attributes, vars)
|
36
|
-
return element, new_attributes
|
37
|
-
end
|
38
|
-
|
39
|
-
def working_on_selected(tag, index, vars, attributes)
|
40
|
-
push_title "You've selected //#{tag}[#{index}]. Wait while Locatine works"
|
41
|
-
element, new_attributes = selected_element(tag, index, vars, attributes)
|
42
|
-
warn 'Cannot proceed with selected. Dropping it.' unless element
|
43
|
-
|
44
|
-
warn "Maybe #{tag} can't be found as a #{@type}?" if @type && !element
|
45
|
-
|
46
|
-
return_selected(element, attributes, new_attributes, vars)
|
47
|
-
end
|
48
|
-
|
49
|
-
def return_old_selection(attrs, vars)
|
50
|
-
return find_by_data(attrs, vars).to_a, attrss.to_h if attrs.to_h != {}
|
51
|
-
|
52
|
-
return nil, {}
|
53
|
-
end
|
54
|
-
|
55
|
-
def return_selected(element, attributes, new_attributes, vars)
|
56
|
-
if !element && new_attributes.to_h != {}
|
57
|
-
push_title 'Selected element was lost before locatine locate it. '\
|
58
|
-
'Consider choosing it from devtools or write your own locator'
|
59
|
-
return return_old_selection(attributes, vars)
|
60
|
-
|
61
|
-
end
|
62
|
-
return element, new_attributes
|
63
|
-
end
|
64
|
-
|
65
|
-
def what_was_selected(element, attributes, vars, name, scope)
|
66
|
-
tag, index = tag_index
|
67
|
-
send_to_app('locatineconfirmed', 'ok')
|
68
|
-
mass_highlight_turn(element, false) if element
|
69
|
-
element, attributes = working_on_selected(tag, index, vars, attributes)
|
70
|
-
if element
|
71
|
-
mass_highlight_turn(element)
|
72
|
-
push_title "#{element.length} elements were selected as #{name} in "\
|
73
|
-
"#{scope}. If it is correct - confirm the selection."
|
74
|
-
end
|
75
|
-
return element, attributes
|
76
|
-
end
|
77
|
-
|
78
|
-
def decline(element, name, scope)
|
79
|
-
mass_highlight_turn(element, false) if element
|
80
|
-
send_to_app('locatineconfirmed', 'ok')
|
81
|
-
push_title "Nothing is selected as #{name} in #{scope}"
|
82
|
-
return nil, {}
|
83
|
-
end
|
84
|
-
|
85
|
-
def user_selection(els, attrs, vars, name, scope)
|
86
|
-
case get_from_app('locatineconfirmed')
|
87
|
-
when 'selected'
|
88
|
-
els, attrs = what_was_selected(els, attrs, vars, name, scope)
|
89
|
-
when 'declined'
|
90
|
-
els, attrs = decline(els, name, scope)
|
91
|
-
end
|
92
|
-
return els, attrs
|
93
|
-
end
|
94
|
-
|
95
|
-
def listening(els, attrs, vars, name, scope)
|
96
|
-
until get_from_app('locatineconfirmed') == 'true'
|
97
|
-
sleep(0.1)
|
98
|
-
els, attrs = user_selection(els, attrs, vars, name, scope)
|
99
|
-
end
|
100
|
-
return els, attrs if els
|
101
|
-
|
102
|
-
decline(els, name, scope)
|
103
|
-
listening(els, attrs, vars, name, scope)
|
104
|
-
end
|
105
|
-
|
106
|
-
##
|
107
|
-
# request send and waiting for an answer
|
108
|
-
def ask(scope, name, element, vars)
|
109
|
-
start_listening(scope, name)
|
110
|
-
element, attributes = suggest_element(element, vars, name, scope)
|
111
|
-
@cold_time = 0
|
112
|
-
element, attributes = listening(element, attributes, vars, name, scope)
|
113
|
-
@cold_time = nil
|
114
|
-
response_action(element)
|
115
|
-
return element, attributes
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
data/lib/locatine/file_work.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module Locatine
|
2
|
-
##
|
3
|
-
# Methods about creating, reading and writing files
|
4
|
-
module FileWork
|
5
|
-
private
|
6
|
-
|
7
|
-
##
|
8
|
-
# Reading data from provided file which is set on init of the class instance
|
9
|
-
#
|
10
|
-
# If there is no dir or\and file they will be created
|
11
|
-
def read_create
|
12
|
-
FileUtils.mkdir_p(@folder) unless File.directory?(@folder)
|
13
|
-
hash = Hash.new { |h, k| h[k] = Hash.new { |hi, ki| hi[ki] = {} } }
|
14
|
-
create_json_file unless File.exist?(@json)
|
15
|
-
hash.merge(JSON.parse(File.read(@json))['data'])
|
16
|
-
end
|
17
|
-
|
18
|
-
def import_file(json)
|
19
|
-
@json = json
|
20
|
-
@folder = File.dirname(@json)
|
21
|
-
@name = File.basename(@json)
|
22
|
-
@data = read_create
|
23
|
-
end
|
24
|
-
|
25
|
-
def create_json_file
|
26
|
-
f = File.new(@json, 'w')
|
27
|
-
f.puts '{"data" : {}}'
|
28
|
-
f.close
|
29
|
-
end
|
30
|
-
|
31
|
-
##
|
32
|
-
# Setting stability
|
33
|
-
def set_stability(first, second)
|
34
|
-
second = first if second.to_h == {}
|
35
|
-
final = Hash.new { |hash, key| hash[key] = [] }
|
36
|
-
first.each_pair do |depth, array|
|
37
|
-
final[depth] = same_entries(array, second, depth, true).uniq
|
38
|
-
end
|
39
|
-
final
|
40
|
-
end
|
41
|
-
|
42
|
-
def stability_bump(to_add, hash)
|
43
|
-
if to_add.empty? # new ones
|
44
|
-
hash['stability'] = '1'
|
45
|
-
elsif to_add[0]['stability'].to_i < @stability_limit # old ones
|
46
|
-
to_add[0]['stability'] = (to_add[0]['stability'].to_i + 1).to_s
|
47
|
-
end
|
48
|
-
to_add.empty? ? [hash] : to_add
|
49
|
-
end
|
50
|
-
|
51
|
-
##
|
52
|
-
# Saving json
|
53
|
-
def store(attributes, scope, name)
|
54
|
-
@data[scope][name] = set_stability(attributes, @data[scope][name])
|
55
|
-
to_write = { 'data' => @data }
|
56
|
-
File.open(@json, 'w') do |f|
|
57
|
-
f.write(JSON.pretty_generate(to_write))
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/locatine/find_by_css.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module Locatine
|
2
|
-
##
|
3
|
-
# Looking for elements by css values
|
4
|
-
module FindByCss
|
5
|
-
private
|
6
|
-
|
7
|
-
def css_array_by_data(data, vars)
|
8
|
-
q_css = []
|
9
|
-
get_trusted(data['0']).each do |hash|
|
10
|
-
if hash['type'] == 'css'
|
11
|
-
value = process_string(hash['value'], vars) if vars[hash['name']]
|
12
|
-
q_css.push("#{hash['name']}: #{value || hash['value']}")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
q_css
|
16
|
-
end
|
17
|
-
|
18
|
-
def return_caught_elements(caught)
|
19
|
-
all = []
|
20
|
-
caught.each do |i|
|
21
|
-
@help_hash[i[0]] ||= engine.elements(tag_name: i[0].downcase).to_a
|
22
|
-
elm = @help_hash[i[0]][i[1].to_i]
|
23
|
-
all.push(elm) if elm
|
24
|
-
end
|
25
|
-
all
|
26
|
-
end
|
27
|
-
|
28
|
-
def select_elements_from_raws_by_css(q_css, raws)
|
29
|
-
all = []
|
30
|
-
@help_hash = {}
|
31
|
-
q_css.each do |item|
|
32
|
-
caught = (raws.select { |i| i[2].include?(item) })
|
33
|
-
all += return_caught_elements(caught)
|
34
|
-
end
|
35
|
-
all
|
36
|
-
end
|
37
|
-
|
38
|
-
def full_find_by_css(data, vars)
|
39
|
-
q_css = css_array_by_data(data, vars)
|
40
|
-
script = File.read("#{HOME}/large_scripts/css.js")
|
41
|
-
raws = engine.execute_script(script)
|
42
|
-
select_elements_from_raws_by_css(q_css, raws)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
module Locatine
|
2
|
-
##
|
3
|
-
# If html code is good and name is related to the code, Locatine can guess it
|
4
|
-
#
|
5
|
-
# Methods for finding element by name only
|
6
|
-
module FindByGuess
|
7
|
-
private
|
8
|
-
|
9
|
-
def main_guess(name)
|
10
|
-
all = []
|
11
|
-
name.split(' ').each do |part|
|
12
|
-
all += guess_by_part(part)
|
13
|
-
end
|
14
|
-
all
|
15
|
-
end
|
16
|
-
|
17
|
-
def guess_by_part(part)
|
18
|
-
all = []
|
19
|
-
tag_xpath = "//#{part}#{not_magic_div}"
|
20
|
-
text_xpath = "//*[contains(text(),'#{part}')]#{not_magic_div}"
|
21
|
-
attr_xpath = "//*[@*[contains(., '#{part}')]]#{not_magic_div}"
|
22
|
-
all += find_by_locator(xpath: tag_xpath).to_a
|
23
|
-
all += find_by_locator(xpath: text_xpath).to_a
|
24
|
-
all += find_by_locator(xpath: attr_xpath).to_a
|
25
|
-
all
|
26
|
-
end
|
27
|
-
|
28
|
-
def full_guess(all, vars, name)
|
29
|
-
max = all.count(all.max_by { |i| all.count(i) })
|
30
|
-
if max >= name.split(' ').length
|
31
|
-
guess = (all.select { |i| all.count(i) == max }).uniq
|
32
|
-
guess_data = generate_data(guess, vars)
|
33
|
-
found_by_data = find_by_data(guess_data, vars)
|
34
|
-
end
|
35
|
-
return found_by_data, guess_data.to_h
|
36
|
-
end
|
37
|
-
|
38
|
-
def check_guess(all, vars, name, scope)
|
39
|
-
guess, guess_data = full_guess(all, vars, name)
|
40
|
-
if guess.nil? || (engine.elements.length / guess.length <= 4)
|
41
|
-
push_title "Locatine has no good guess for #{name} in #{scope}."
|
42
|
-
guess = nil
|
43
|
-
guess_data = {}
|
44
|
-
else
|
45
|
-
push_title "#{guess.length} elements guessed as #{name} in #{scope}."
|
46
|
-
end
|
47
|
-
return guess, guess_data
|
48
|
-
end
|
49
|
-
|
50
|
-
def find_by_guess(scope, name, vars)
|
51
|
-
@cold_time = 0
|
52
|
-
all = main_guess(name)
|
53
|
-
if all.empty?
|
54
|
-
push_title "Locatine has no guess for #{name} in #{scope}."
|
55
|
-
else
|
56
|
-
guess, guess_data = check_guess(all, vars, name, scope)
|
57
|
-
end
|
58
|
-
@cold_time = nil
|
59
|
-
return guess, guess_data.to_h
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|