locatine 0.02637 → 0.03050

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +266 -297
  3. data/bin/locatine-daemon.rb +4 -2
  4. data/lib/locatine.rb +16 -2
  5. data/lib/locatine/daemon.rb +45 -59
  6. data/lib/locatine/daemon_helpers/methods.rb +93 -0
  7. data/lib/locatine/element.rb +46 -0
  8. data/lib/locatine/error.rb +14 -0
  9. data/lib/locatine/logger.rb +73 -0
  10. data/lib/locatine/results.rb +124 -0
  11. data/lib/locatine/results_helpers/common.rb +61 -0
  12. data/lib/locatine/results_helpers/comparing.rb +51 -0
  13. data/lib/locatine/results_helpers/config.rb +48 -0
  14. data/lib/locatine/results_helpers/find_by_magic.rb +123 -0
  15. data/lib/locatine/results_helpers/guess.rb +47 -0
  16. data/lib/locatine/results_helpers/info_generator.rb +77 -0
  17. data/lib/locatine/{for_search → results_helpers}/xpath_generator.rb +19 -18
  18. data/lib/locatine/scripts/element.js +40 -0
  19. data/lib/locatine/scripts/page.js +54 -0
  20. data/lib/locatine/scripts/parent.js +6 -0
  21. data/lib/locatine/session.rb +147 -0
  22. data/lib/locatine/version.rb +4 -2
  23. metadata +42 -49
  24. data/lib/locatine/app/background.js +0 -8
  25. data/lib/locatine/app/content.css +0 -38
  26. data/lib/locatine/app/content.js +0 -152
  27. data/lib/locatine/app/devtools.html +0 -1
  28. data/lib/locatine/app/devtools.js +0 -3
  29. data/lib/locatine/app/manifest.json +0 -20
  30. data/lib/locatine/app/popup.css +0 -47
  31. data/lib/locatine/app/popup.html +0 -19
  32. data/lib/locatine/app/popup.js +0 -65
  33. data/lib/locatine/daemon_helpers.rb +0 -52
  34. data/lib/locatine/for_search.rb +0 -6
  35. data/lib/locatine/for_search/data_generate.rb +0 -67
  36. data/lib/locatine/for_search/data_logic.rb +0 -98
  37. data/lib/locatine/for_search/defaults.rb +0 -40
  38. data/lib/locatine/for_search/dialog_logic.rb +0 -107
  39. data/lib/locatine/for_search/element_selection.rb +0 -80
  40. data/lib/locatine/for_search/file_work.rb +0 -67
  41. data/lib/locatine/for_search/find_by_guess.rb +0 -67
  42. data/lib/locatine/for_search/find_by_locator.rb +0 -59
  43. data/lib/locatine/for_search/find_by_magic.rb +0 -65
  44. data/lib/locatine/for_search/find_logic.rb +0 -79
  45. data/lib/locatine/for_search/helpers.rb +0 -106
  46. data/lib/locatine/for_search/highlight.rb +0 -41
  47. data/lib/locatine/for_search/listening.rb +0 -48
  48. data/lib/locatine/for_search/merge.rb +0 -40
  49. data/lib/locatine/for_search/name_helper.rb +0 -51
  50. data/lib/locatine/for_search/page_work.rb +0 -126
  51. data/lib/locatine/for_search/public.rb +0 -179
  52. data/lib/locatine/for_search/saying.rb +0 -199
  53. data/lib/locatine/large_scripts/css.js +0 -21
  54. data/lib/locatine/large_scripts/dimensions.js +0 -17
  55. data/lib/locatine/large_scripts/element.js +0 -30
  56. data/lib/locatine/large_scripts/page.js +0 -60
  57. data/lib/locatine/scope.rb +0 -88
  58. data/lib/locatine/search.rb +0 -67
@@ -1,59 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Methods related to the most simple search by ready locator.
5
- module FindByLocator
6
- private
7
-
8
- def collection?(the_class)
9
- case the_class.superclass.to_s
10
- when 'Watir::Element'
11
- false
12
- when 'Watir::ElementCollection'
13
- true
14
- else
15
- collection?(the_class.superclass)
16
- end
17
- end
18
-
19
- ##
20
- # Getting all the elements matching a locator
21
- def find_by_locator(locator)
22
- method = @type.nil? ? :elements : @type
23
- begin
24
- engine.element(locator).wait_until(timeout: @cold_time, &:exists?)
25
- rescue StandardError
26
- return nil
27
- end
28
- results = engine.send(method, locator)
29
- return correct_method_detected(results) if collection?(results.class)
30
-
31
- acceptable_method_detected(results, method, locator)
32
- end
33
-
34
- def correct_method_detected(results)
35
- return nil if results.empty?
36
-
37
- all = results.reject(&:stale?)
38
- return all unless all.empty?
39
-
40
- nil
41
- end
42
-
43
- def acceptable_method_detected(results, method, locator)
44
- warn_acceptable_type(method)
45
- the_class = results.class
46
- results = engine.elements(locator)
47
- .to_a
48
- .select { |item| item.to_subtype.class == the_class }
49
- correct_method_detected(results)
50
- end
51
-
52
- ##
53
- # Getting all the elements via stored information
54
- def find_by_data(data, vars)
55
- find_by_locator(xpath: generate_xpath(data, vars))
56
- end
57
- end
58
- end
59
- end
@@ -1,65 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Logic for finding lost element
5
- module FindByMagic
6
- private
7
-
8
- ##
9
- # Getting all the elements via black magic
10
- def find_by_magic(name, scope, data, vars, iteration = 0)
11
- html = take_html
12
- page = take_dom
13
- suggested = magic_elements(name, scope, data, vars, page)
14
- warn_unstable if page_changed?(page, html)
15
- if html != take_html && iteration < 5
16
- return find_by_magic(name, scope, data, vars, iteration + 1)
17
- end
18
-
19
- warn_highly_unstable if iteration == 5
20
- suggest_by_all(suggested, data, vars, name, scope)
21
- end
22
-
23
- def page_changed?(page, html)
24
- html != take_html || page != take_dom
25
- end
26
-
27
- ##
28
- # We are taking every element that look at least a bit similar to one we
29
- # are looking for
30
- def magic_elements(name, scope, data, vars, page)
31
- warn_element_lost(name, scope, data, vars)
32
- all = select_from_page(page, data, vars)
33
- raise_not_found(name, scope) if all.empty? && !@current_no_f
34
- suggested = most_common_of(all).map do |element|
35
- engine.elements(tag_name: element['tag'])[element['index'].to_i]
36
- end
37
- suggested
38
- end
39
-
40
- def similar_enough(data, attributes)
41
- same = same_entries(data['0'], attributes, '0').length
42
- all = data['0'].length
43
- sameness = (same * 100) / all
44
- sameness >= 100 - @current_t
45
- end
46
-
47
- def final_of_all(suggest, vars)
48
- attributes = generate_data(suggest, vars) unless suggest.empty?
49
- return suggest, attributes
50
- end
51
-
52
- def suggest_by_all(all, data, vars, name, scope)
53
- suggest, attributes = final_of_all(all, vars)
54
- ok = similar_enough(data, attributes) unless suggest.empty?
55
- raise_not_similar(name, scope) if !ok && !@current_no_f
56
- if ok
57
- warn_lost_found(name, scope, attributes, vars)
58
- return suggest, attributes
59
- end
60
- warn_not_found(name, scope)
61
- return nil, nil
62
- end
63
- end
64
- end
65
- end
@@ -1,79 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Methods explaining find logic
5
- module FindLogic
6
- private
7
-
8
- def set_name(simple_name, name)
9
- name ||= simple_name
10
- raise_no_name unless name
11
- name
12
- end
13
-
14
- def data_search(name, scope, vars, exact)
15
- result = find_by_data(@data[scope][name], vars)
16
- attributes = generate_data(result, vars) if result
17
- if !result && !exact
18
- @autolearn = true if @autolearn.nil?
19
- @save = true
20
- result, attributes = find_by_magic(name, scope,
21
- @data[scope][name], vars)
22
- end
23
- return result, attributes
24
- end
25
-
26
- def core_search(name, scope, vars, exact)
27
- if @data[scope][name].to_h != {}
28
- result, attributes = data_search(name, scope, vars, exact)
29
- end
30
- return result, attributes
31
- end
32
-
33
- def full_search(name, scope, vars, locator, exact)
34
- @save = @autolearn
35
- result, attributes = search_steps(name, scope, vars, locator, exact)
36
- raise_not_found(name, scope) if !result && !@current_no_f
37
- store(attributes, scope, name) if result && (@save || @learn)
38
- return result, attributes
39
- end
40
-
41
- def search_steps(name, scope, vars, locator, exact)
42
- result, attributes = locator_search(locator, vars)
43
- ok = result || ((locator != {}) && exact)
44
- result, attributes = core_search(name, scope, vars, exact) unless ok
45
- if @learn
46
- answer = ask(scope, name, result, vars)
47
- result = answer[:element]
48
- attributes = answer[:attributes]
49
- end
50
- return result, attributes
51
- end
52
-
53
- def locator_search(locator, vars)
54
- result = find_by_locator(locator) unless locator == {}
55
- attributes = generate_data(result, vars) if result
56
- warn_broken_locator(locator) if locator.to_h != {} && !result
57
- return result, attributes
58
- end
59
-
60
- ##
61
- # Returning subtype of the only element of collection OR collection
62
- #
63
- # Params:
64
- # +result+ must be Watir::HTMLElementCollection or Array
65
- #
66
- # +collection+ nil, true or false
67
- def to_subtype(result, collection)
68
- result = result.to_a
69
- to_return = result.map(&:to_subtype)
70
- case collection
71
- when true
72
- to_return
73
- when false
74
- to_return.first
75
- end
76
- end
77
- end
78
- end
79
- end
@@ -1,106 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Different methods to make life easier
5
- module Helpers
6
- private
7
-
8
- def enforce(inject, *args)
9
- inject = args.last.merge(inject) if args.last.class == Hash
10
- ok = (args.first.class == String) && inject[:name].nil?
11
- inject[:name] = args.first if ok
12
- find(inject)
13
- end
14
-
15
- def engine
16
- (@iframe || @browser)
17
- end
18
-
19
- def take_html
20
- engine.locate
21
- engine.html.gsub(/<div.*id="locatine_magic_div".*>/, '')
22
- end
23
-
24
- def time
25
- t = Time.now
26
- t.strftime('%F %T')
27
- end
28
-
29
- def fix_iframe
30
- @iframe = @browser.iframe(@iframe.selector) if @iframe && @iframe.stale?
31
- end
32
-
33
- def set_env_for_search(look_in,
34
- iframe,
35
- tolerance,
36
- no_fail,
37
- trusted,
38
- untrusted)
39
- @type = look_in
40
- @iframe = iframe
41
- @current_t = tolerance || @tolerance
42
- @current_no_f = no_fail || @no_fail
43
- @trust_now = trusted || @trusted
44
- @untrust_now = untrusted || @untrusted
45
- end
46
-
47
- def not_magic_div
48
- "[not(@id = 'locatine_magic_div')]"
49
- end
50
-
51
- def push_hash(name, value, type)
52
- { 'name' => name,
53
- 'value' => value,
54
- 'type' => type }
55
- end
56
-
57
- def window_size
58
- b_w = engine.execute_script('return window.innerWidth')
59
- b_h = engine.execute_script('return window.innerHeight')
60
- "#{b_w}x#{b_h}"
61
- end
62
-
63
- def visual?
64
- @visual_search
65
- end
66
-
67
- def right_browser
68
- Watir::Browser.new(:chrome, switches: ["--load-extension=#{HOME}/app"])
69
- end
70
-
71
- def css_text_to_hash(text)
72
- almost_hash = []
73
- array = text[0..-2].split('; ')
74
- array.each do |item|
75
- almost_hash.push item.split(': ')
76
- end
77
- almost_hash.to_h
78
- end
79
-
80
- def default_styles
81
- css =
82
- engine.execute_script("const dummy = document.createElement('dummy');
83
- document.body.appendChild(dummy);
84
- return getComputedStyle(dummy).cssText;")
85
- css_text_to_hash(css)
86
- end
87
-
88
- def process_string(str, vars)
89
- str = str.to_s
90
- thevar = str.match(/\#{([^\#{]*)}/)[1] unless str.match(/\#{(.*)}/).nil?
91
- return str unless thevar
92
-
93
- value = vars[thevar.to_sym] || vars[thevar]
94
- raise_no_var(thevar) unless value
95
- process_string(str.gsub('#{' + thevar + '}', value.to_s), vars)
96
- end
97
-
98
- def most_common_of(all)
99
- max = all.count(all.max_by { |i| all.count(i) })
100
- return (all.select { |i| all.count(i) == max }).uniq unless max.zero?
101
-
102
- []
103
- end
104
- end
105
- end
106
- end
@@ -1,41 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Locatine can highlight elements
5
- module Highlight
6
- private
7
-
8
- ##
9
- # We can highlight an element
10
- def highlight(element)
11
- script = "arguments[0].setAttribute('locatineclass','foundbylocatine')"
12
- engine.execute_script(script, element)
13
- rescue StandardError
14
- warn_cannot_highlight(element.selector)
15
- end
16
-
17
- ##
18
- # We can unhighlight an element
19
- def unhighlight(element)
20
- script = "arguments[0].removeAttribute('locatineclass')"
21
- engine.execute_script(script, element)
22
- rescue StandardError
23
- false
24
- # watir is not allowing to play with attributes of some elements
25
- end
26
-
27
- ##
28
- # We can highlight\unhighlight tons of elements at once
29
- def mass_highlight_turn(mass, turn_on = true)
30
- warn_much_highlight(mass.length) if turn_on && mass.length > 50
31
- mass[0..49].each do |element|
32
- if turn_on
33
- highlight element
34
- else
35
- unhighlight element
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,48 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Simple actions about communicating with chrome extension (and user)
5
- module Listening
6
- private
7
-
8
- ##
9
- # Getting attribute of locatine div (way to communicate)
10
- def get_from_app(what)
11
- fix_iframe
12
- result = engine.wd.execute_script(
13
- %[if (document.getElementById('locatine_magic_div')) {
14
- const magic_div = document.getElementById('locatine_magic_div');
15
- return magic_div.getAttribute("#{what}")}]
16
- )
17
- fix_iframe
18
- result
19
- end
20
-
21
- ##
22
- # Sending request to locatine app
23
- def start_listening(scope, name)
24
- send_to_app('locatinestyle', 'set_false', @browser) if @iframe
25
- send_to_app('locatinestyle', 'set_true')
26
- send_to_app('locatineconfirmed', 'ok')
27
- send_selecting(name, scope)
28
- sleep 0.5
29
- end
30
-
31
- def tag_index
32
- tag = get_from_app('tag')
33
- tag = tag.downcase unless tag.nil?
34
- index = get_from_app('index').to_i
35
- return tag, index
36
- end
37
-
38
- def response_action(element)
39
- send_to_app('locatineconfirmed', 'ok')
40
- send_has_response
41
- mass_highlight_turn(element, false) if element
42
- send_to_app('locatinestyle', 'set_false')
43
- send_to_app('locatinestyle', 'ok', @browser) if @iframe
44
- sleep 1
45
- end
46
- end
47
- end
48
- end
@@ -1,40 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Getting commons of two piles of elements data. To find all similar to them
5
- module Merge
6
- private
7
-
8
- def select_same(where, hash)
9
- where.select do |item|
10
- (item['name'] == hash['name']) &&
11
- (item['value'] == hash['value']) &&
12
- (item['type'] == hash['type'])
13
- end
14
- end
15
-
16
- def same_entries(array, second, depth, stability_up = false)
17
- result = []
18
- array.each do |hash|
19
- item = second[depth]
20
- to_add = item.nil? ? [] : select_same(second[depth], hash)
21
- max = max_stability(second[depth]).to_i + 1
22
- to_add = stability_bump(to_add, hash, max) if stability_up
23
- result += to_add
24
- end
25
- result
26
- end
27
-
28
- ##
29
- # Merging data of two elements (new data is to find both)
30
- def get_commons(first, second)
31
- second = first if second == {}
32
- final = Hash.new { |hash, key| hash[key] = [] }
33
- first.each_pair do |depth, array|
34
- final[depth] = same_entries(array, second, depth)
35
- end
36
- final
37
- end
38
- end
39
- end
40
- end