locatine 0.01084 → 0.01100

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 38885391980f7e8d2b0cef65643f998edf5074cf
4
- data.tar.gz: f321d064c113b65f024d8d22bd52bfd0ab6a56d8
3
+ metadata.gz: 8ca422d8fbe87acacb5b19639d98c509fbdb04a2
4
+ data.tar.gz: b81058cdc3aa26f76a5521312de44f11f5b299bd
5
5
  SHA512:
6
- metadata.gz: 110afe53c901b20d93cdc7c34c2846e82c5b361d96068e368a42ad907278bb124eed0fdc53bc993a77f87afae72b744a03bd41e7e7156679a62604a6a76a115b
7
- data.tar.gz: 02105771e43ba72453ebbb238be198408037c11fd90e2169f0e79f44d96efc49a1c4bed2c08dcf8e5068e34c08c2725bb015343475074b9a48707e9a52937764
6
+ metadata.gz: f3435a0ae9f55f95e2419d47f37e066c9af65c4cc630b222229a5057aec35060a4a3d24504a5bb1eed21bee6c2c59611b692eb14dec12a945648da1f75bb8fd0
7
+ data.tar.gz: 96236870dffc079e8fa474b8fab27d5276c57ddbb1655ff0b8edf598a7eea1e45476e8cfb41b27e6feb16fc992c0f66bca6f80a84afdfe45df623ae75f9b9cc2
@@ -3,7 +3,7 @@ chrome.browserAction.onClicked.addListener(
3
3
  console.log("WAS here");
4
4
  chrome.windows.create( {'url': 'popup.html',
5
5
  'type': 'popup',
6
- 'width': 800,
7
- 'height': 600});
6
+ 'width': 640,
7
+ 'height': 480});
8
8
 
9
9
  });
@@ -29,6 +29,10 @@ async function refreshData(){
29
29
  await set_value('magic_div', true);
30
30
  magicDiv.setAttribute("locatinestyle", "true");
31
31
  };
32
+ if (magicDiv.getAttribute("locatinestyle") === "set_false") {
33
+ await set_value('magic_div', false);
34
+ magicDiv.setAttribute("locatinestyle", "false");
35
+ };
32
36
  if (magicDiv.getAttribute("locatinetitle") != "ok") {
33
37
  await set_value('locatine_title', magicDiv.getAttribute("locatinetitle"));
34
38
  await set_value('locatine_hint', magicDiv.getAttribute("locatinehint"));
@@ -43,7 +47,6 @@ async function refreshData(){
43
47
  magicDiv.removeAttribute("tag");
44
48
  magicDiv.removeAttribute("index");
45
49
  await set_value("locatine_confirm", false);
46
- await set_value('magic_div', false);
47
50
  }
48
51
  const confirmed = await get_value('locatine_confirm');
49
52
  magicDiv.setAttribute("locatineconfirmed", confirmed);
@@ -52,21 +55,27 @@ async function refreshData(){
52
55
  magic_cover.onclick = function(e) {locatine_magic_click(e)};
53
56
  };
54
57
 
55
- function getSelected(value){
58
+ async function getSelected(value){
59
+ const magic_div = document.getElementById("locatine_magic_div");
56
60
  const tagName = value.tagName;
57
61
  const array = Array.prototype.slice.call( document.getElementsByTagName(tagName) );
58
62
  const index = array.indexOf(value);
59
- document.getElementById("locatine_magic_div").setAttribute("tag", tagName);
60
- document.getElementById("locatine_magic_div").setAttribute("index", index);
63
+ if (document.locatine_selected != value) {
64
+ document.locatine_selected = value;
65
+ await set_value("locatine_confirm", "selected");
66
+ magic_div.setAttribute("tag", tagName);
67
+ magic_div.setAttribute("index", index);
68
+ }
61
69
  };
62
70
 
63
- function locatine_magic_click(e) {
71
+ async function locatine_magic_click(e) {
64
72
  document.getElementById("locatine_magic_div").setAttribute("locatinestyle", "blocked");
65
73
  const value = document.elementFromPoint(e.clientX, e.clientY);
66
74
  document.getElementById("locatine_magic_div").setAttribute("locatinestyle", "true");
67
75
  const tagName = value.tagName;
68
76
  const array = Array.prototype.slice.call( document.getElementsByTagName(tagName) );
69
77
  const index = array.indexOf(value);
78
+ await set_value("locatine_confirm", "selected");
70
79
  document.getElementById("locatine_magic_div").setAttribute("TAG", tagName);
71
80
  document.getElementById("locatine_magic_div").setAttribute("INDEX", index);
72
81
  };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Locatine app",
3
- "version": "0.01084",
3
+ "version": "0.01100",
4
4
  "description": "Messaging from browser to main app",
5
5
  "devtools_page": "devtools.html",
6
6
  "permissions": ["activeTab", "storage", "contextMenus", "tabs"],
@@ -0,0 +1,91 @@
1
+ module Locatine
2
+ ##
3
+ # Generating locatine json info from element itself
4
+ module DataGenerate
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
+ def get_dynamic_tag(element, vars)
19
+ tag = element.tag_name
20
+ tag = "\#{tag}" if vars[:tag] == tag
21
+ { 'name' => 'tag', 'value' => tag, 'type' => 'tag' }
22
+ end
23
+
24
+ def real_text_of(element)
25
+ element.text == element.inner_html ? element.text : ''
26
+ end
27
+
28
+ def get_dynamic_text(element, vars)
29
+ attrs = []
30
+ real_text_of(element).split(' ').each do |word|
31
+ final_word = if !vars[:text].to_s.strip.empty?
32
+ word.gsub(vars[:text].to_s, "\#{text}")
33
+ else
34
+ word
35
+ end
36
+ attrs.push('name' => 'text', 'value' => final_word, 'type' => 'text')
37
+ end
38
+ attrs
39
+ end
40
+
41
+ ##
42
+ # Generating array of hashes representing data of the element
43
+ def get_element_info(element, vars)
44
+ attrs = get_dynamic_attributes(element, vars)
45
+ attrs.push get_dynamic_tag(element, vars)
46
+ attrs += get_dynamic_text(element, vars)
47
+ attrs
48
+ end
49
+
50
+ ##
51
+ # Generating data for group of elements
52
+ def generate_data(result, vars)
53
+ family = {}
54
+ result.each do |item|
55
+ family = get_commons(get_family_info(item, vars), family)
56
+ end
57
+ family
58
+ end
59
+
60
+ ##
61
+ # Getting element\\parents information
62
+ def get_family_info(element, vars)
63
+ current_depth = 0
64
+ attributes = {}
65
+ while current_depth != @depth
66
+ attributes[current_depth.to_s] = get_element_info(element, vars)
67
+ current_depth += 1
68
+ element = element.parent
69
+ # Sometimes watir is not returning a valid parent that's why:
70
+ current_depth = @depth unless element.parent.exists?
71
+ end
72
+ attributes
73
+ end
74
+
75
+ ##
76
+ # Collecting attributes of the element
77
+ def get_attributes(element)
78
+ attributes = element.attributes
79
+ array = []
80
+ attributes.each_pair do |name, value|
81
+ next if name.to_s == 'locatineclass'
82
+
83
+ value.split(' ').uniq.each do |part|
84
+ array.push('name' => name.to_s, 'type' => 'attribute',
85
+ 'value' => part)
86
+ end
87
+ end
88
+ array
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,71 @@
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
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
+ send_to_app('locatinestyle', 'blocked', @browser) if @iframe
45
+ send_to_app('locatinehint', 'Toggle single//collection mode button if '\
46
+ 'you need. If you want to do some actions on the page toggle Locatine'\
47
+ ' waiting button. You also can select element on devtools -> Elements.'\
48
+ ' Do not forget to confirm your selection.')
49
+ send_to_app('locatinestyle', 'set_true')
50
+ sleep 0.5
51
+ end
52
+
53
+ def tag_index
54
+ tag = get_from_app('tag')
55
+ tag = tag.downcase unless tag.nil?
56
+ index = get_from_app('index').to_i
57
+ return tag, index
58
+ end
59
+
60
+ def response_action(element)
61
+ send_to_app('locatineconfirmed', 'ok')
62
+ send_to_app('locatinetitle', 'Right now you are defining nothing. '\
63
+ '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 0.5
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,94 @@
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 find_by_data(attributes, vars).to_a, attributes.to_h unless element
47
+
48
+ return element, new_attributes
49
+ end
50
+
51
+ def what_was_selected(element, attributes, vars, name, scope)
52
+ send_to_app('locatineconfirmed', 'ok')
53
+ tag, index = tag_index
54
+ mass_highlight_turn(element, false) if element
55
+ element, attributes = working_on_selected(tag, index, vars, attributes)
56
+ mass_highlight_turn(element) if element
57
+ push_title "#{element.length} elements were selected as #{name} in "\
58
+ "#{scope}. If it is correct - confirm the selection."
59
+ return element, attributes
60
+ end
61
+
62
+ def decline(element, name, scope)
63
+ mass_highlight_turn(element, false) if element
64
+ send_to_app('locatineconfirmed', 'ok')
65
+ push_title "Nothing is selected as #{name} in #{scope}"
66
+ return nil, {}
67
+ end
68
+
69
+ def listening(els, attrs, vars, name, scope)
70
+ until get_from_app('locatineconfirmed') == 'true'
71
+ sleep(0.1)
72
+ case get_from_app('locatineconfirmed')
73
+ when 'selected'
74
+ els, attrs = what_was_selected(els, attrs, vars, name, scope)
75
+ when 'declined'
76
+ els, attrs = decline(els, name, scope)
77
+ end
78
+ end
79
+ return els, attrs
80
+ end
81
+
82
+ ##
83
+ # request send and waiting for an answer
84
+ def ask(scope, name, element, vars)
85
+ start_listening(scope, name)
86
+ element, attributes = suggest_element(element, vars, name, scope)
87
+ @cold_time = 0
88
+ element, attributes = listening(element, attributes, vars, name, scope)
89
+ @cold_time = nil
90
+ response_action(element)
91
+ return element, attributes
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,54 @@
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 create_json_file
19
+ f = File.new(@json, 'w')
20
+ f.puts '{"data" : {}}'
21
+ f.close
22
+ end
23
+
24
+ ##
25
+ # Setting stability
26
+ def set_stability(first, second)
27
+ second = first if second.to_h == {}
28
+ final = Hash.new { |hash, key| hash[key] = [] }
29
+ first.each_pair do |depth, array|
30
+ final[depth] = same_entries(array, second, depth, true).uniq
31
+ end
32
+ final
33
+ end
34
+
35
+ def stability_bump(to_add, hash)
36
+ if to_add.empty? # new ones
37
+ hash['stability'] = '1'
38
+ elsif to_add[0]['stability'].to_i < @stability_limit # old ones
39
+ to_add[0]['stability'] = (to_add[0]['stability'].to_i + 1).to_s
40
+ end
41
+ to_add.empty? ? [hash] : to_add
42
+ end
43
+
44
+ ##
45
+ # Saving json
46
+ def store(attributes, scope, name)
47
+ @data[scope][name] = set_stability(attributes, @data[scope][name])
48
+ to_write = { 'data' => @data }
49
+ File.open(@json, 'w') do |f|
50
+ f.write(JSON.pretty_generate(to_write))
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,62 @@
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
+ guess, guess_data = check_guess(all, vars, name, scope)
55
+ else
56
+ push_title "Locatine has no guess for #{name} in #{scope}."
57
+ end
58
+ @cold_time = nil
59
+ return guess, guess_data.to_h
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,98 @@
1
+ module Locatine
2
+ ##
3
+ # Methods related to the most simple search by ready locator.
4
+ module FindByLocator
5
+ private
6
+
7
+ def collection?(the_class)
8
+ case the_class.superclass.to_s
9
+ when 'Object'
10
+ nil
11
+ when 'Watir::Element'
12
+ false
13
+ when 'Watir::ElementCollection'
14
+ true
15
+ else
16
+ collection?(the_class.superclass)
17
+ end
18
+ end
19
+
20
+ ##
21
+ # Getting all the elements matching a locator
22
+ def find_by_locator(locator)
23
+ method = @type.nil? ? :elements : @type
24
+ results = engine.send(method, locator)
25
+ case collection?(results.class)
26
+ when nil
27
+ wrong_method_detected(method)
28
+ when true
29
+ return correct_method_detected(results)
30
+ when false
31
+ return acceptable_method_detected(results, method)
32
+ end
33
+ end
34
+
35
+ def wrong_method_detected(method)
36
+ @type = nil
37
+ raise ArgumentError, "#{method} is not good for :look_in property. Use"\
38
+ ' a method of Watir::Browser that returns a collection (like :divs,'\
39
+ ' :links, etc.)'
40
+ end
41
+
42
+ def correct_method_detected(results)
43
+ all = []
44
+ begin
45
+ results[0].wait_until(timeout: @cold_time, &:present?)
46
+ rescue StandardError
47
+ nil
48
+ end
49
+ results.each { |item| all.push item if item.present? }
50
+ return all unless all.empty?
51
+ return nil if all.empty?
52
+ end
53
+
54
+ def acceptable_method_detected(results, method, locator)
55
+ warn "#{method} works for :look_in. But it is better to use a method of"\
56
+ ' Watir::Browser that returns a collection (like :divs, :links, etc.)'
57
+ the_class = results.class
58
+ results = engine.elements(locator)
59
+ .to_a.select { |item| item.to_subtype.class == the_class }
60
+ correct_method_detected(results)
61
+ end
62
+
63
+ ##
64
+ # Getting elements by tag
65
+ def find_by_tag(hash, vars, depth = 0)
66
+ correction = '/*' * depth.to_i
67
+ xpath = "//*[self::#{process_string(hash['value'], vars)}]"
68
+ find_by_locator(xpath: "#{xpath}#{correction}#{not_magic_div}")
69
+ end
70
+
71
+ ##
72
+ # Getting elements by text
73
+ def find_by_text(hash, vars, depth = 0)
74
+ correction = '/*' * depth.to_i
75
+ xpath = "//*[contains(text(), '#{process_string(hash['value'], vars)}')]"
76
+ find_by_locator(xpath: "#{xpath}#{correction}#{not_magic_div}")
77
+ end
78
+
79
+ ##
80
+ # Getting elements by attribute
81
+ def find_by_attribute(hash, vars, depth = 0)
82
+ correction = '/*' * depth.to_i
83
+ full_part = '//*[@*'
84
+ hash['name'].split('_').each do |part|
85
+ full_part += "[contains(name(), '#{part}')]"
86
+ end
87
+ value = process_string(hash['value'], vars)
88
+ xpath = full_part + "[contains(., '#{value}')]]"
89
+ find_by_locator(xpath: "#{xpath}#{correction}#{not_magic_div}")
90
+ end
91
+
92
+ ##
93
+ # Getting all the elements via stored information
94
+ def find_by_data(data, vars)
95
+ find_by_locator(xpath: generate_xpath(data, vars))
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,43 @@
1
+ module Locatine
2
+ ##
3
+ # Logic for finding lost element
4
+ module FindByMagic
5
+ private
6
+
7
+ ##
8
+ # Getting all the elements via black magic
9
+ def find_by_magic(name, scope, data, vars)
10
+ warn "#{name} in #{scope} is lost. Looking for it."
11
+ @cold_time = 0
12
+ all = all_options(data, vars)
13
+ @cold_time = nil
14
+ raise "Unable to find element #{name} in #{scope}" if all.empty?
15
+
16
+ max = all.count(all.max_by { |i| all.count(i) })
17
+ suggestion = (all.select { |i| all.count(i) == max }).uniq
18
+ attributes = generate_data(suggestion, vars)
19
+ return suggestion, attributes
20
+ end
21
+
22
+ def all_options(data, vars)
23
+ all = []
24
+ data.each_pair do |depth, array|
25
+ get_trusted(array).each do |hash|
26
+ all += one_option_array(hash, vars, depth)
27
+ end
28
+ end
29
+ all
30
+ end
31
+
32
+ def one_option_array(hash, vars, depth)
33
+ case hash['type']
34
+ when 'tag'
35
+ find_by_tag(hash, vars, depth).to_a
36
+ when 'text'
37
+ find_by_text(hash, vars, depth).to_a
38
+ when 'attribute'
39
+ find_by_attribute(hash, vars, depth).to_a
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,61 @@
1
+ module Locatine
2
+ ##
3
+ # Methods explaining find logic
4
+ module FindLogic
5
+ private
6
+
7
+ def set_name(simple_name, name)
8
+ name ||= simple_name
9
+ raise ArgumentError, ':name should be provided' unless name
10
+
11
+ name
12
+ end
13
+
14
+ def core_search(result, name, scope, vars, exact)
15
+ if @data[scope][name].to_h != {}
16
+ result = find_by_data(@data[scope][name], vars)
17
+ attributes = generate_data(result, vars) if result
18
+ if !result && !exact
19
+ result, attributes = find_by_magic(name, scope,
20
+ @data[scope][name], vars)
21
+ end
22
+ end
23
+ return result, attributes
24
+ end
25
+
26
+ def full_search(name, scope, vars, locator, exact)
27
+ result, attributes = locator_search(locator, vars)
28
+ unless result
29
+ result, attributes = core_search(result, name, scope,
30
+ vars, exact)
31
+ end
32
+ result, attributes = ask(scope, name, result, vars) if @learn
33
+ raise "Nothing was found for #{scope} #{name}" if !result && !exact
34
+
35
+ store(attributes, scope, name) if result
36
+ return result, attributes
37
+ end
38
+
39
+ def locator_search(locator, vars)
40
+ result = find_by_locator(locator) if locator != {}
41
+ attributes = generate_data(result, vars) if result
42
+ return result, attributes
43
+ end
44
+
45
+ ##
46
+ # Returning subtype of the only element of collection OR collection
47
+ #
48
+ # Params:
49
+ # +result+ must be Watir::HTMLElementCollection or Array
50
+ #
51
+ # +collection+ nil, true or false
52
+ def to_subtype(result, collection)
53
+ case collection
54
+ when true
55
+ result
56
+ when false
57
+ result.first.to_subtype
58
+ end
59
+ end
60
+ end
61
+ end