locatine 0.02542 → 0.02878

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +269 -296
  3. data/bin/locatine-daemon.rb +4 -2
  4. data/lib/locatine.rb +14 -2
  5. data/lib/locatine/daemon.rb +48 -56
  6. data/lib/locatine/daemon_helpers/methods.rb +85 -0
  7. data/lib/locatine/element.rb +32 -0
  8. data/lib/locatine/error.rb +14 -0
  9. data/lib/locatine/logger.rb +69 -0
  10. data/lib/locatine/results.rb +128 -0
  11. data/lib/locatine/results_helpers/common.rb +68 -0
  12. data/lib/locatine/results_helpers/find_by_magic.rb +121 -0
  13. data/lib/locatine/results_helpers/guess.rb +76 -0
  14. data/lib/locatine/results_helpers/info_generator.rb +79 -0
  15. data/lib/locatine/{for_search → results_helpers}/xpath_generator.rb +18 -11
  16. data/lib/locatine/scripts/element.js +40 -0
  17. data/lib/locatine/scripts/page.js +54 -0
  18. data/lib/locatine/scripts/parent.js +6 -0
  19. data/lib/locatine/session.rb +107 -0
  20. data/lib/locatine/version.rb +4 -2
  21. metadata +40 -49
  22. data/lib/locatine/app/background.js +0 -8
  23. data/lib/locatine/app/content.css +0 -43
  24. data/lib/locatine/app/content.js +0 -149
  25. data/lib/locatine/app/devtools.html +0 -1
  26. data/lib/locatine/app/devtools.js +0 -3
  27. data/lib/locatine/app/manifest.json +0 -20
  28. data/lib/locatine/app/popup.css +0 -47
  29. data/lib/locatine/app/popup.html +0 -19
  30. data/lib/locatine/app/popup.js +0 -65
  31. data/lib/locatine/daemon_helpers.rb +0 -52
  32. data/lib/locatine/for_search.rb +0 -6
  33. data/lib/locatine/for_search/data_generate.rb +0 -67
  34. data/lib/locatine/for_search/data_logic.rb +0 -98
  35. data/lib/locatine/for_search/defaults.rb +0 -40
  36. data/lib/locatine/for_search/dialog_logic.rb +0 -107
  37. data/lib/locatine/for_search/element_selection.rb +0 -80
  38. data/lib/locatine/for_search/file_work.rb +0 -67
  39. data/lib/locatine/for_search/find_by_guess.rb +0 -67
  40. data/lib/locatine/for_search/find_by_locator.rb +0 -59
  41. data/lib/locatine/for_search/find_by_magic.rb +0 -65
  42. data/lib/locatine/for_search/find_logic.rb +0 -79
  43. data/lib/locatine/for_search/helpers.rb +0 -106
  44. data/lib/locatine/for_search/highlight.rb +0 -41
  45. data/lib/locatine/for_search/listening.rb +0 -48
  46. data/lib/locatine/for_search/merge.rb +0 -40
  47. data/lib/locatine/for_search/name_helper.rb +0 -51
  48. data/lib/locatine/for_search/page_work.rb +0 -126
  49. data/lib/locatine/for_search/public.rb +0 -179
  50. data/lib/locatine/for_search/saying.rb +0 -196
  51. data/lib/locatine/large_scripts/css.js +0 -21
  52. data/lib/locatine/large_scripts/dimensions.js +0 -17
  53. data/lib/locatine/large_scripts/element.js +0 -30
  54. data/lib/locatine/large_scripts/page.js +0 -60
  55. data/lib/locatine/scope.rb +0 -88
  56. data/lib/locatine/search.rb +0 -67
@@ -1 +0,0 @@
1
- <script src="devtools.js"></script>
@@ -1,3 +0,0 @@
1
- setInterval(function(){
2
- chrome.devtools.inspectedWindow.eval("getSelected($0)", { useContentScriptContext: true });
3
- }, 100);
@@ -1,20 +0,0 @@
1
- {
2
- "name": "Locatine app",
3
- "version": "0.02542",
4
- "description": "Messaging from browser to main app",
5
- "devtools_page": "devtools.html",
6
- "permissions": ["activeTab", "storage", "contextMenus", "tabs"],
7
- "background": {
8
- "scripts": ["background.js"],
9
- "persistent": true
10
- },
11
- "content_scripts": [{
12
- "matches": ["<all_urls>"],
13
- "all_frames": true,
14
- "js": ["content.js"],
15
- "css": ["content.css"]
16
- }],
17
- "browser_action": {
18
- "default_title": "Locatine"},
19
- "manifest_version": 2
20
- }
@@ -1,47 +0,0 @@
1
- .button {
2
- border: none;
3
- height: 30px;
4
- width: 100%;
5
- color: white;
6
- padding: 5px 32px;
7
- text-align: center;
8
- text-decoration: none;
9
- display: inline-block;
10
- font-size: 16px;
11
- }
12
-
13
- .field {
14
- width: 100%;
15
- height: 30px;
16
- display: block;
17
- }
18
-
19
- .green {
20
- background-color: #4CAF50
21
- }
22
-
23
- .red {
24
- background-color: #AF4C50
25
- }
26
-
27
- .blue {
28
- background-color: #4C50AF
29
- }
30
-
31
- .header {
32
- padding: 10px 5px 10px 5px;
33
- text-align: center;
34
- color: black;
35
- font-size: 25px;
36
- }
37
-
38
- .hint {
39
- padding: 10px 5px 10px 5px;
40
- text-align: center;
41
- background-color: #EFFA93;
42
- box-shadow: 5px 5px 5px;
43
- }
44
-
45
- .block {
46
- padding: 30px 5px 30px 5px;
47
- }
@@ -1,19 +0,0 @@
1
-
2
- <html>
3
- <head>
4
- <link rel="stylesheet" href="popup.css">
5
- </head>
6
- <body>
7
- <h2 class="header" id="mainTitle">Right now you are defining nothing. So no button will work</h2>
8
- <h3 class="hint" id="hint">But you can click it anyway :)</h3>
9
- <div class="block">
10
- <input title="You can set your own element name here. Do not forget to use it in your code!" class="usual field" id="nameHandler" type="text" placeholder="Element name" value=""/>
11
- <input title="If you need to do some actions on page for debug purposes before defining the element you can turn off waiting for click. If Locatine is waiting for click every click is gonna be counted as element selection." class="blue button" id="watchSwitch" type="button" value="Do not watch"/>
12
- <input title="If you need to find a collection of elements. Turn collection mode on. And click two elements of the kind. Locatine will automatically select all the elements that are similar to selected" class="blue button" id="mode" type="button" value="Adding mode is enabled"/>
13
- <input title="Click it to start element selection process from the very beginning." class="red button" id="clearMark" type="button" value="Clear selection"/>
14
- <input title="Will forcedly stop the selection process. Use with care since ruby methods will return nils and errors since element is not selected properly. Use it when you finish to define a scope." class="red button" id="abort" type="button" value="Abort selection"/>
15
- <input title="When you've selected a correct element - confirm it in order to save." class="green button" id="confirm" type="button" value="Confirm selection"/>
16
- </div>
17
- <script src="popup.js"></script>
18
- </body>
19
- </html>
@@ -1,65 +0,0 @@
1
- async function get_value(name) {
2
- let x = await new Promise((resolve, reject) => chrome.storage.sync.get([name], resolve));
3
- return x[name];
4
- };
5
-
6
- async function set_value(name, value){
7
- let temp = {};
8
- temp[name] = value;
9
- await chrome.storage.sync.set(temp, function() {});
10
- };
11
-
12
- async function correct_buttons() {
13
- if (await get_value("magic_div") === true) {
14
- document.getElementById("watchSwitch").setAttribute("value", "Locatine is waiting for click");
15
- } else {
16
- document.getElementById("watchSwitch").setAttribute("value", "Locatine is not waiting now");
17
- };
18
- if (await get_value("locatine_collection") === true) {
19
- document.getElementById("mode").setAttribute("value", "You are in collection mode")
20
- } else {
21
- document.getElementById("mode").setAttribute("value", "You are in single selection mode")
22
- };
23
- if (await get_value("locatine_title")) {
24
- document.getElementById("mainTitle").innerText = await get_value("locatine_title");
25
- document.getElementById("hint").innerText = await get_value("locatine_hint");
26
- }
27
- if ((document.getElementById("nameHandler").value != await get_value("locatineName")) && (!document.hasFocus())){
28
- document.getElementById("nameHandler").value = (await get_value("locatineName") || "");
29
- }
30
- }
31
-
32
- async function watch() {
33
- await set_value("magic_div", !(await get_value("magic_div")));
34
- }
35
-
36
- function clear() {
37
- set_value("locatine_confirm", "declined");
38
- }
39
-
40
- function confirm() {
41
- set_value("locatine_confirm", true);
42
- }
43
-
44
- function abort() {
45
- set_value("locatine_confirm", 'abort');
46
- }
47
-
48
- async function mode() {
49
- await set_value("locatine_collection", !(await get_value("locatine_collection")));
50
- }
51
-
52
- async function doName() {
53
- await set_value("locatineName", document.getElementById("nameHandler").value);
54
- }
55
-
56
- document.getElementById("watchSwitch").onclick = function() {watch()};
57
- document.getElementById("clearMark").onclick = function() {clear()};
58
- document.getElementById("confirm").onclick = function() {confirm()};
59
- document.getElementById("mode").onclick = function() {mode()};
60
- document.getElementById("abort").onclick = function() {abort()};
61
- document.getElementById("nameHandler").oninput = function() {doName()};
62
-
63
- setInterval(function(){
64
- correct_buttons();
65
- }, 100);
@@ -1,52 +0,0 @@
1
- module Locatine
2
- #
3
- # Usefull things daemon can do
4
- module DaemonHelpers
5
- private
6
-
7
- def steal
8
- cast_ghost_browser
9
- disguise_session
10
- disguise_server_url
11
- disguise_http
12
- disguise_proxy unless params['proxy'].to_s.empty?
13
- end
14
-
15
- def bridge
16
- search.browser.wd.send(:bridge)
17
- end
18
-
19
- def b_http
20
- bridge.send(:http)
21
- end
22
-
23
- def disguise_session
24
- bridge.instance_variable_set('@session_id', params['session_id'])
25
- end
26
-
27
- def disguise_server_url
28
- uri = URI.parse(params['url'])
29
- b_http.instance_variable_set('@server_url', uri)
30
- end
31
-
32
- def disguise_http
33
- b_http.instance_variable_set('@http', make_net)
34
- end
35
-
36
- def disguise_proxy
37
- b_http.instance_variable_set('@proxy', params['proxy'])
38
- end
39
-
40
- def make_net
41
- parsed = URI.parse(params['url'])
42
- path = parsed.path == '/' ? '' : parsed.path
43
- Net::HTTP.new("#{parsed.host}#{path}", parsed.port)
44
- end
45
-
46
- def cast_ghost_browser
47
- search.browser = Watir::Browser.new(params['browser'].to_sym)
48
- search.browser.quit
49
- search.browser.instance_variable_set('@closed', false)
50
- end
51
- end
52
- end
@@ -1,6 +0,0 @@
1
- module Locatine
2
- ##
3
- # One module to collect all parts of search
4
- module ForSearch
5
- end
6
- end
@@ -1,67 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Collecting data of element and making it dynamic
5
- module DataGenerate
6
- private
7
-
8
- def mesure(element)
9
- xy = element.location
10
- wh = element.size
11
- return xy.x, xy.y, wh.width, wh.height
12
- end
13
-
14
- def get_dynamic_tag(tag, vars)
15
- tag = "\#{tag}" if vars[:tag].to_s.casecmp(tag).zero?
16
- push_hash('tag', tag, 'tag')
17
- end
18
-
19
- def text_array(text)
20
- text.to_s.tr("\n", ' ').split(/['" ]/)
21
- end
22
-
23
- def get_dynamic_text(text, vars)
24
- attrs = text_array(text).map do |word|
25
- final = if !vars[:text].to_s.strip.empty?
26
- word.gsub(vars[:text].to_s, "\#{text}")
27
- else
28
- word
29
- end
30
- push_hash('text', final, 'text') unless final.empty?
31
- end
32
- attrs.compact
33
- end
34
-
35
- def get_dimensions(element)
36
- resolution = window_size
37
- x, y, w, h = mesure(element)
38
- push_hash(resolution, "#{x}*#{y}*#{w}*#{h}", 'dimensions')
39
- end
40
-
41
- def hash_by_style(style, value, vars)
42
- value.gsub!(vars[style.to_sym], "\#{#{style}}") if vars[style.to_sym]
43
- push_hash(style, value, 'css')
44
- end
45
-
46
- def get_raw_css(element)
47
- test_script = 'return typeof(arguments[0])'
48
- ok = engine.execute_script(test_script, element) == 'object'
49
- script = 'return getComputedStyle(arguments[0]).cssText'
50
- return engine.execute_script(script, element) if ok
51
- end
52
-
53
- def get_dynamic_css(element, vars)
54
- attrs = []
55
- raw = get_raw_css(element)
56
- if raw
57
- styles = css_text_to_hash(get_raw_css(element))
58
- (styles.to_a - @default_styles).to_h.each_pair do |style, value|
59
- hash = hash_by_style(style, value, vars)
60
- attrs.push(hash) if hash
61
- end
62
- end
63
- attrs
64
- end
65
- end
66
- end
67
- end
@@ -1,98 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Logic of collecting data of the element
5
- module DataLogic
6
- private
7
-
8
- def get_dynamic_attributes(data, vars)
9
- attrs = []
10
- data.each do |hash|
11
- hash.each_pair do |key, full_value|
12
- full_value.split(' ').each do |value|
13
- next if key == 'locatineclass'
14
-
15
- attrs.push some_attribute(value, key, vars)
16
- end
17
- end
18
- end
19
- attrs
20
- end
21
-
22
- def some_attribute(value, key, vars)
23
- replace = vars[key.to_sym]
24
- push_hash(key,
25
- replace ? value.gsub(replace, "\#{#{key}}") : value,
26
- 'attribute')
27
- end
28
-
29
- def get_element_raw(element)
30
- element = element.to_subtype.wd.wd if element.tag_name == 'iframe'
31
- script = File.read("#{HOME}/large_scripts/element.js")
32
- engine.execute_script(script, element)
33
- end
34
-
35
- ##
36
- # Generating array of hashes representing data of the element
37
- def get_element_info(element, vars, depth)
38
- data = get_element_raw(element)
39
- attrs = get_dynamic_attributes(data['attrs'], vars)
40
- attrs.push get_dynamic_tag(data['tag'], vars)
41
- attrs += get_dynamic_text(data['text'], vars)
42
- attrs += get_dynamic_css(element, vars) if looking?(depth)
43
- attrs.push get_dimensions(element) if looking?(depth)
44
- attrs
45
- end
46
-
47
- def looking?(depth)
48
- depth.to_i.zero? && visual?
49
- end
50
-
51
- ##
52
- # Generating data for group of elements
53
- def generate_data(result, vars)
54
- family = {}
55
- result.each do |item|
56
- family = get_commons(get_family_info(item, vars), family)
57
- end
58
- family
59
- end
60
-
61
- def equal_elements?(one, another)
62
- good = true unless one == {}
63
- one.each_pair do |depth, array|
64
- trusted = get_trusted(array).map do |i|
65
- i.reject { |k| k == 'stability' }
66
- end
67
- good &&= ((trusted - another[depth] == []) && !trusted.empty?)
68
- end
69
- good
70
- end
71
-
72
- def find_in_data(attributes)
73
- found = []
74
- @data.each_pair do |scope, elements|
75
- elements.each_pair do |element, hash|
76
- good = equal_elements?(hash, attributes)
77
- found.push(scope: scope, name: element) if good
78
- end
79
- end
80
- found.empty? ? nil : found
81
- end
82
-
83
- ##
84
- # Getting element\\parents information
85
- def get_family_info(element, vars)
86
- i = 0
87
- attributes = {}
88
- while i != @depth
89
- attributes[i.to_s] = get_element_info(element, vars, i)
90
- i += 1
91
- element = element.parent
92
- i = @depth unless element.exists?
93
- end
94
- attributes
95
- end
96
- end
97
- end
98
- end
@@ -1,40 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Default settings for search are living here
5
- module Defaults
6
- private
7
-
8
- def default_init_config
9
- { json: './Locatine_files/default.json', depth: 3,
10
- browser: nil, learn: ENV['LEARN'].nil? ? false : true,
11
- stability_limit: 10, scope: 'Default',
12
- tolerance: 67, visual_search: false,
13
- no_fail: false, trusted: [],
14
- untrusted: [], autolearn: nil }
15
- end
16
-
17
- def import_browser(browser)
18
- selenium = browser.class.superclass == Selenium::WebDriver::Driver
19
- b = right_browser unless browser
20
- b = browser if browser.class == Watir::Browser
21
- b = Watir::Browser.new(browser) if selenium
22
- @browser = b
23
- @default_styles = default_styles.to_a
24
- end
25
-
26
- def import_file(json)
27
- @json = json
28
- @folder = File.dirname(@json)
29
- @name = File.basename(@json)
30
- @data = read_create
31
- end
32
-
33
- def import_config(config)
34
- config.each_pair do |key, value|
35
- instance_variable_set("@#{key}", value)
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,107 +0,0 @@
1
- module Locatine
2
- module ForSearch
3
- ##
4
- # Logic of recieving element selected by user
5
- module DialogLogic
6
- private
7
-
8
- def suggest_element(element, vars, name, scope)
9
- attributes = {}
10
- if !element.nil?
11
- attributes = generate_data(element, vars)
12
- send_found(name, scope, element.length)
13
- elsif name.length >= 5
14
- send_guessing(name, scope)
15
- element, attributes = find_by_guess(scope, name, vars)
16
- end
17
- mass_highlight_turn(element) if element
18
- return element, attributes
19
- end
20
-
21
- def what_was_selected(element, attributes, vars)
22
- tag, index = tag_index
23
- # TODO: ELEMENT COULD BE ALREADY LOST HERE. WE HAVE BUG AROUND THAT CODE
24
- send_to_app('locatineconfirmed', 'ok')
25
- mass_highlight_turn(element, false) if element
26
- element, attributes = working_on_selected(tag, index, vars, attributes)
27
- return element, attributes
28
- end
29
-
30
- def show_element(element, attributes, name, scope)
31
- found = find_in_data(attributes)
32
- mass_highlight_turn(element)
33
- send_selected(element.length, name, scope) unless found
34
- send_same_entry(element.length, name, scope, found) if found
35
- end
36
-
37
- def decline(element, name, scope)
38
- mass_highlight_turn(element, false) if element
39
- send_to_app('locatineconfirmed', 'ok')
40
- send_clear(name, scope)
41
- return nil, {}
42
- end
43
-
44
- def user_selection(els, attrs, vars, name, scope)
45
- case get_from_app('locatineconfirmed')
46
- when 'selected'
47
- els, attrs = what_was_selected(els, attrs, vars)
48
- name = suggest_name(name, attrs, vars)
49
- show_element(els, attrs, name, scope) if els
50
- when 'declined'
51
- els, attrs = decline(els, name, scope)
52
- end
53
- return els, attrs
54
- end
55
-
56
- # get_from_app('locatineconfirmed') 'selected' or 'declined' or 'true'
57
- # or 'abort' or 'new' or anything else (ok or false)
58
- def listening(els, attrs, vars, name, scope)
59
- sleep(0.1)
60
- result = hearing
61
- els, attrs = understanding(els, attrs, vars, name, scope, result)
62
- if (!result[:done] || !els) && !result[:abort]
63
- return listening(els, attrs, vars, name, scope)
64
- end
65
-
66
- return els, attrs
67
- end
68
-
69
- def understanding(els, attrs, vars, name, scope, result)
70
- if result[:selected]
71
- els, attrs = user_selection(els, attrs, vars, name, scope)
72
- else
73
- start_listening(scope, name) if result[:new]
74
- els, attrs = decline(els, name, scope) if result[:declined]
75
- end
76
- return els, attrs
77
- end
78
-
79
- def hearing
80
- answer = {}
81
- result = get_from_app('locatineconfirmed')
82
- answer[:selected] = ((result == 'selected') || (result == 'true'))
83
- answer[:new] = result == 'new'
84
- answer[:done] = result == 'true'
85
- answer[:abort] = result == 'abort'
86
- answer[:declined] = ((result == 'new') ||
87
- (result == 'declined') ||
88
- (result == 'abort'))
89
- answer
90
- end
91
-
92
- ##
93
- # request send and waiting for an answer
94
- def ask(scope, name, element, vars)
95
- start_listening(scope, name)
96
- element, attributes = suggest_element(element, vars, name, scope)
97
- @cold_time = 0
98
- element, attributes = listening(element, attributes, vars, name, scope)
99
- @cold_time = nil
100
- name_from_app = get_from_app('locatine_name')
101
- name = name_from_app unless name_from_app.to_s.empty?
102
- response_action(element)
103
- { element: element, attributes: attributes, name: name }
104
- end
105
- end
106
- end
107
- end