locatine 0.02007 → 0.02247

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
  SHA1:
3
- metadata.gz: 7d489c3b40e3742d4a0133a1280587c338879b7c
4
- data.tar.gz: 3347799276e7b897802781ce57cfc1d480c61b77
3
+ metadata.gz: 023773fde5af096ee6f8b04948dbeadcee35f3d2
4
+ data.tar.gz: 2071bcae7bf758afc1196a82f04f74690931f9c0
5
5
  SHA512:
6
- metadata.gz: 794115b0c100ed8724bce73059ec80c8b39e2d91022ce4a0710838e976faba02be568096477c6b3482a0b591d0cdda90e7a09c3ad15b41b0323286ebd271ea24
7
- data.tar.gz: 457935ca593e60dd278cfd18c8aad043f366c7fb8f79197139ddcea79d1cd196b78f2063e7e8f9be0455693568d6a787a7b9ada4e1aa28ce320de739194bdb63
6
+ metadata.gz: c3c8e5959c2fd4b850608ee0d998357c32ce9af253e6726c3077f6eafeeef4625a85fa0e5c70f10564d14c1d46756efe61a9823f4e68f2ac37dd5000d008d1bb
7
+ data.tar.gz: 99f44eb1de8f7158f8b108edc971c2682322fc2fb60db7e2729da318a73729e21f1dece359616bdfd14e9703a8277b6372c968cac73725fd82e930a85d61fa80
data/README.md CHANGED
@@ -16,7 +16,7 @@ That's it.
16
16
 
17
17
  ## Stage of development:
18
18
 
19
- Version of Locatine is **0.02007** only. It means so far this is an alfa. You can use it in a real project if you are a risky person.
19
+ Version of Locatine is **0.02247** only. It means so far this is an alfa. You can use it in a real project if you are a risky person.
20
20
 
21
21
  ## Installation
22
22
 
@@ -95,7 +95,8 @@ Locatine::Search.new(json: "./Locatine_files/default.json",
95
95
  stability_limit: 1000,
96
96
  scope: "Default",
97
97
  tolerance: 33,
98
- visual_search: false)
98
+ visual_search: false,
99
+ no_fail: false)
99
100
  ```
100
101
 
101
102
  ### json
@@ -142,6 +143,10 @@ Position and size for element will be stored for the current resolution only. St
142
143
 
143
144
  Be careful! Set true only if appearance of your page is pretty stable.
144
145
 
146
+ ### no_fail
147
+
148
+ When element is lost and no_fail is true you will get nil for single element and [] for collection. If no_fail is false (which is default) and locatine cannot find something you will face an error.
149
+
145
150
  ## Changing options on fly
146
151
 
147
152
  You can get or set these values on fly. Like:
@@ -164,7 +169,8 @@ s.find(name: "some name",
164
169
  iframe: nil,
165
170
  return_locator: false,
166
171
  collection: false,
167
- tolerance: nil)
172
+ tolerance: nil,
173
+ no_fail: nil)
168
174
  ```
169
175
  ### name
170
176
 
@@ -174,26 +180,6 @@ should be always provided. Name of element to look for. Must be uniq one per sco
174
180
 
175
181
  group of elements. Must be uniq per file. This is to help to store elements with same names from different pages in one file
176
182
 
177
- ### exact
178
-
179
- unless it is true locatine will always try to find lost element using all the power it has. Use exact: true if you want element to be lost in case of any significant change. If it is impossible to find element when exact: true locatine will return nil.
180
-
181
- Be carefull: exact is working only when element is stable (has at least one parameter persistent for stability_limit times == well known by locatine). If element is not stable yet locatine will search for it anyway and maybe it will find something. So if you want to ensure that element does not exist you should use locator and exact at the same time. You may also set zero tolerance. Check it:
182
-
183
- ```ruby
184
- # Will return nil if there is no element id = 'not welcome'
185
- s.find(name: "unexpected element", locator:{id: "not welcome"}, exact: true)
186
-
187
- # Will return nil if well known element "unexpected element" is not present
188
- # Will try to find and return at least something if "unexpected element" is not stable (well known)
189
- # If there is nothing similar to "unexpected element" returns nil
190
- s.find(name: "unexpected something", exact: true)
191
-
192
- # Will return element only if the same element is present
193
- # Changing of any attribute which is trusted by locatine will produce nil
194
- s.find(name: "unexpected something", exact: true, tolerance: 0)
195
- ```
196
-
197
183
  ### locator
198
184
 
199
185
  you may provide your own locator to use. Same syntax as in Watir:
@@ -263,6 +249,14 @@ if true array of elements will be returned. If false only the one element (the f
263
249
 
264
250
  You can state custom tolerance for the element.
265
251
 
252
+ ### exact
253
+
254
+ It is disabling attempts to find element by advanced algorithms. If locator is provided find method will use only locator. If there is no locator only the basic search will be performed.
255
+
256
+ ### no_fail
257
+
258
+ no_fail option that will work for that search only.
259
+
266
260
  ## Scope
267
261
 
268
262
  If you want to define a whole bunch of elements at once you can do:
@@ -302,7 +296,8 @@ search.get_scope(name: "Name of scope").all
302
296
  # => {"element name": {
303
297
  # elements: Array of Watir::Element,
304
298
  # locator: valid xpath locator
305
- # }...
299
+ # },
300
+ # "next element name":...
306
301
  # }
307
302
  ```
308
303
 
@@ -343,3 +338,12 @@ s.collect("group of elements") # Will return an array
343
338
  # or
344
339
  s.collect(name: "group of elements")
345
340
  ```
341
+
342
+ Also:
343
+
344
+ ```ruby
345
+ s.exact_collection(name: "something") == s.collect(exact: true, name: "something")
346
+ s.exact(name: "something") == s.find(name: "something", exact: true)
347
+ s.check(name: "something") == s.find(name: "something", tolerance: 0)
348
+ s.check_collection(name: "something") == s.collect(name: "something", tolerance: 0)
349
+ ```
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Locatine app",
3
- "version": "0.02007",
3
+ "version": "0.02247",
4
4
  "description": "Messaging from browser to main app",
5
5
  "devtools_page": "devtools.html",
6
6
  "permissions": ["activeTab", "storage", "contextMenus", "tabs"],
@@ -18,50 +18,6 @@ module Locatine
18
18
  return element, attributes
19
19
  end
20
20
 
21
- def add_selected_attributes(new_attributes, attributes)
22
- if get_from_app('locatinecollection') == 'true'
23
- get_commons(new_attributes, attributes.to_h)
24
- else
25
- new_attributes
26
- end
27
- end
28
-
29
- def selected_element_attributes(tag, index, vars)
30
- generate_data([engine.elements(tag_name: tag)[index]], vars).to_h
31
- end
32
-
33
- def selected_element(tag, index, vars, attributes)
34
- new_attributes = selected_element_attributes(tag, index, vars)
35
- new_attributes = add_selected_attributes(new_attributes, attributes)
36
- element = find_by_data(new_attributes, vars)
37
- return element, new_attributes
38
- end
39
-
40
- def working_on_selected(tag, index, vars, attributes)
41
- send_working(tag, index)
42
- element, new_attributes = selected_element(tag, index, vars, attributes)
43
- warn_dropping(tag, index) unless element
44
-
45
- warn_type(tag) if @type && !element
46
-
47
- return_selected(element, attributes, new_attributes, vars)
48
- end
49
-
50
- def return_old_selection(attrs, vars)
51
- return find_by_data(attrs, vars).to_a, attrs.to_h if attrs.to_h != {}
52
-
53
- return nil, {}
54
- end
55
-
56
- def return_selected(element, attributes, new_attributes, vars)
57
- if !element && new_attributes.to_h != {}
58
- send_lost
59
- return return_old_selection(attributes, vars)
60
-
61
- end
62
- return element, new_attributes
63
- end
64
-
65
21
  def what_was_selected(element, attributes, vars)
66
22
  tag, index = tag_index
67
23
  send_to_app('locatineconfirmed', 'ok')
@@ -0,0 +1,80 @@
1
+ module Locatine
2
+ module ForSearch
3
+ ##
4
+ # Cooking element data for dialog
5
+ module ElementSelection
6
+ private
7
+
8
+ def add_selected_attributes(new_attributes, attributes)
9
+ if get_from_app('locatinecollection') == 'true'
10
+ get_commons(new_attributes, attributes.to_h)
11
+ else
12
+ new_attributes
13
+ end
14
+ end
15
+
16
+ def simple_attrs(tag, index, vars)
17
+ element = engine.elements(tag_name: tag)[index]
18
+ attrs = generate_data([element], vars).to_h
19
+ return element, attrs
20
+ end
21
+
22
+ def negative_needed(element, vars, old_depth)
23
+ @depth = old_depth
24
+ warn_no_negatives
25
+ generate_data([element], vars).to_h
26
+ end
27
+
28
+ def complex_attrs(element, vars, old_depth = @depth)
29
+ attrs = get_family_info(element, vars).to_h
30
+ return negative_needed(element, vars, old_depth) if attrs.length < @depth
31
+
32
+ if find_by_data(attrs, vars).length > 1
33
+ @depth +=1
34
+ return complex_attrs(element, vars, old_depth)
35
+ end
36
+ @depth = old_depth
37
+ attrs
38
+ end
39
+
40
+ def selected_element_attributes(tag, index, vars)
41
+ element, attrs = simple_attrs(tag, index, vars)
42
+ length = find_by_data(attrs, vars).to_a.length
43
+ attrs = complex_attrs(element, vars) if length > 1
44
+ attrs
45
+ end
46
+
47
+ def selected_element(tag, index, vars, attributes)
48
+ new_attributes = selected_element_attributes(tag, index, vars)
49
+ new_attributes = add_selected_attributes(new_attributes, attributes)
50
+ element = find_by_data(new_attributes, vars)
51
+ return element, new_attributes
52
+ end
53
+
54
+ def working_on_selected(tag, index, vars, attributes)
55
+ send_working(tag, index)
56
+ element, new_attributes = selected_element(tag, index, vars, attributes)
57
+ warn_dropping(tag, index) unless element
58
+
59
+ warn_type(tag) if @type && !element
60
+
61
+ return_selected(element, attributes, new_attributes, vars)
62
+ end
63
+
64
+ def return_old_selection(attrs, vars)
65
+ return find_by_data(attrs, vars).to_a, attrs.to_h if attrs.to_h != {}
66
+
67
+ return nil, {}
68
+ end
69
+
70
+ def return_selected(element, attributes, new_attributes, vars)
71
+ if !element && new_attributes.to_h != {}
72
+ send_lost
73
+ return return_old_selection(attributes, vars)
74
+
75
+ end
76
+ return element, new_attributes
77
+ end
78
+ end
79
+ end
80
+ end
@@ -35,6 +35,7 @@ module Locatine
35
35
  # Setting stability
36
36
  def set_stability(first, second)
37
37
  second = first if second.to_h == {}
38
+ first = second.merge first
38
39
  final = Hash.new { |hash, key| hash[key] = [] }
39
40
  first.each_pair do |depth, array|
40
41
  final[depth] = same_entries(array, second, depth, true).uniq
@@ -54,6 +55,7 @@ module Locatine
54
55
  ##
55
56
  # Saving json
56
57
  def store(attributes, scope, name)
58
+ @data[scope][name] = {} if @learn
57
59
  @data[scope][name] = set_stability(attributes, @data[scope][name])
58
60
  to_write = { 'data' => @data }
59
61
  File.open(@json, 'w') do |f|
@@ -7,13 +7,13 @@ module Locatine
7
7
 
8
8
  ##
9
9
  # Getting all the elements via black magic
10
- def find_by_magic(name, scope, data, vars, exact)
10
+ def find_by_magic(name, scope, data, vars)
11
11
  warn_element_lost(name, scope)
12
12
  @cold_time = 0
13
13
  all = all_options(data, vars)
14
14
  @cold_time = nil
15
- raise_not_found(name, scope) if all.empty? && !exact
16
- suggest_by_all(all, data, vars, name, scope, exact)
15
+ raise_not_found(name, scope) if all.empty? && !@current_no_f
16
+ suggest_by_all(all, data, vars, name, scope)
17
17
  end
18
18
 
19
19
  def similar_enough(data, attributes)
@@ -30,11 +30,10 @@ module Locatine
30
30
  return suggest, attributes
31
31
  end
32
32
 
33
- def suggest_by_all(all, data, vars, name, scope, exact)
33
+ def suggest_by_all(all, data, vars, name, scope)
34
34
  suggest, attributes = best_of_all(all, vars)
35
35
  ok = similar_enough(data, attributes) unless suggest.nil?
36
- spawn = !ok && !exact
37
- raise_not_similar(name, scope) if spawn
36
+ raise_not_similar(name, scope) if !ok && !@current_no_f
38
37
  if ok
39
38
  warn_lost_found(name, scope)
40
39
  return suggest, attributes
@@ -11,20 +11,12 @@ module Locatine
11
11
  name
12
12
  end
13
13
 
14
- def stable?(attributes)
15
- s = []
16
- attributes.each_pair do |_depth, array|
17
- s.push array.max_by { |i| i['stability'].to_i }['stability'].to_i
18
- end
19
- s.max >= @stability_limit
20
- end
21
-
22
14
  def data_search(name, scope, vars, exact)
23
15
  result = find_by_data(@data[scope][name], vars)
24
16
  attributes = generate_data(result, vars) if result
25
- if !result && (!exact || !stable?(@data[scope][name]))
17
+ if !result && !exact
26
18
  result, attributes = find_by_magic(name, scope,
27
- @data[scope][name], vars, exact)
19
+ @data[scope][name], vars)
28
20
  end
29
21
  return result, attributes
30
22
  end
@@ -38,7 +30,7 @@ module Locatine
38
30
 
39
31
  def full_search(name, scope, vars, locator, exact)
40
32
  result, attributes = search_steps(name, scope, vars, locator, exact)
41
- raise_not_found(name, scope) if !result && !exact
33
+ raise_not_found(name, scope) if !result && !@current_no_f
42
34
  store(attributes, scope, name) if result
43
35
  return result, attributes
44
36
  end
@@ -69,11 +61,13 @@ module Locatine
69
61
  #
70
62
  # +collection+ nil, true or false
71
63
  def to_subtype(result, collection)
64
+ result = result.to_a
65
+ to_return = result.map(&:to_subtype)
72
66
  case collection
73
67
  when true
74
- result
68
+ to_return
75
69
  when false
76
- result.first.to_subtype
70
+ to_return.first
77
71
  end
78
72
  end
79
73
  end
@@ -26,10 +26,11 @@ module Locatine
26
26
  @iframe = @browser.iframe(@iframe.selector) if @iframe && @iframe.stale?
27
27
  end
28
28
 
29
- def set_env_for_search(look_in, iframe, tolerance)
29
+ def set_env_for_search(look_in, iframe, tolerance, no_fail)
30
30
  @type = look_in
31
31
  @iframe = iframe
32
32
  @current_t = tolerance || @tolerance
33
+ @current_no_f = no_fail || @no_fail
33
34
  end
34
35
 
35
36
  def not_magic_div
@@ -27,7 +27,7 @@ module Locatine
27
27
  ##
28
28
  # We can highlight\unhighlight tons of elements at once
29
29
  def mass_highlight_turn(mass, turn_on = true)
30
- warn_much_highlight if turn_on && mass.length > 50
30
+ warn_much_highlight(mass.length) if turn_on && mass.length > 50
31
31
  mass[0..49].each do |element|
32
32
  if turn_on
33
33
  highlight element
@@ -16,7 +16,8 @@ module Locatine
16
16
  def same_entries(array, second, depth, stability_up = false)
17
17
  result = []
18
18
  array.each do |hash|
19
- to_add = select_same(second[depth], hash)
19
+ item = second[depth]
20
+ to_add = item.nil? ? [] : select_same(second[depth], hash)
20
21
  to_add = stability_bump(to_add, hash) if stability_up
21
22
  result += to_add
22
23
  end
@@ -35,7 +35,8 @@ module Locatine
35
35
  stability_limit: 1000,
36
36
  scope: 'Default',
37
37
  tolerance: 67,
38
- visual_search: false)
38
+ visual_search: false,
39
+ no_fail: false)
39
40
  import_browser browser
40
41
  import_file(json)
41
42
  @depth = depth
@@ -44,6 +45,7 @@ module Locatine
44
45
  @scope = scope
45
46
  @tolerance = tolerance
46
47
  @visual_search = visual_search
48
+ @no_fail = no_fail
47
49
  end
48
50
 
49
51
  ##
@@ -88,14 +90,16 @@ module Locatine
88
90
  iframe: nil,
89
91
  return_locator: false,
90
92
  collection: false,
91
- tolerance: nil)
93
+ tolerance: nil,
94
+ no_fail: nil)
92
95
  name = set_name(simple_name, name)
93
- set_env_for_search(look_in, iframe, tolerance)
96
+ set_env_for_search(look_in, iframe, tolerance, no_fail)
94
97
  scope ||= @scope.nil? ? 'Default' : @scope
95
98
  result, attributes = full_search(name, scope, vars, locator, exact)
96
99
  return { xpath: generate_xpath(attributes, vars) } if result &&
97
100
  return_locator
98
- return to_subtype(result, collection) if result && !return_locator
101
+
102
+ to_subtype(result, collection)
99
103
  end
100
104
 
101
105
  ##
@@ -133,6 +137,30 @@ module Locatine
133
137
  answer.define(vars) if @learn
134
138
  answer
135
139
  end
140
+
141
+ ##
142
+ # Find alias with zero tolerance option enforced
143
+ def check(*args)
144
+ enforce({ tolerance: 0 }, *args)
145
+ end
146
+
147
+ ##
148
+ # Collection alias with zero tolerance option enforced
149
+ def check_collection(*args)
150
+ enforce({ tolerance: 0, collection: true }, *args)
151
+ end
152
+
153
+ ##
154
+ # Collection alias with exact option on
155
+ def exact_collection(*args)
156
+ enforce({ exact: true, collection: true }, *args)
157
+ end
158
+
159
+ ##
160
+ # Find alias with exact option on
161
+ def exact(*args)
162
+ enforce({ exact: true }, *args)
163
+ end
136
164
  end
137
165
  end
138
166
  end
@@ -91,10 +91,25 @@ module Locatine
91
91
  push_title "#{length} #{verb(length)} selected as #{name} in #{scope}."\
92
92
  " But it was already defined #{found.length} times."
93
93
  example = found.sample
94
+ same = found.select { |i| (i[:name] == name) && (i[:scope] == scope) }
95
+ if same.empty?
96
+ send_same_entry_example(example)
97
+ else
98
+ send_fully_similar
99
+ end
100
+ end
101
+
102
+ def send_same_entry_example(example)
94
103
  send_to_app('locatinehint', "For example like #{example[:name]} in"\
95
104
  " #{example[:scope]}")
96
105
  end
97
106
 
107
+ def send_fully_similar
108
+ send_to_app('locatinehint', 'And it was defined with the same name'\
109
+ ' and in the same scope. So saving your selection will cause'\
110
+ ' deleting of all previously stored data about the element')
111
+ end
112
+
98
113
  def warn_dropping(tag, index)
99
114
  send_warn('For some reason locatine cannot proceed with'\
100
115
  " //#{tag}[#{index}] element. You've selected. Maybe element was"\
@@ -131,7 +146,19 @@ module Locatine
131
146
  end
132
147
 
133
148
  def warn_not_found(name, scope)
134
- "Locatine cannot find element #{name} in #{scope}"
149
+ send_warn "Locatine cannot find element #{name} in #{scope}"
150
+ end
151
+
152
+ def warn_totally_same(how_deep)
153
+ send_warn('There are more than one elements with totally similar'\
154
+ " attributes. Custom depth for element is set to #{how_deep}.")
155
+ end
156
+
157
+ def warn_no_negatives
158
+ send_warn 'The only way to find the selected element is to use'\
159
+ " negative expression like //*[not(@id='something')]. Locatine does"\
160
+ ' not support it. So you must to provide for element a custom locator.'\
161
+ ' Or find it as a part of collection and than return it by index'
135
162
  end
136
163
 
137
164
  def raise_not_found(name, scope)
@@ -42,7 +42,7 @@ module Locatine
42
42
  success = []
43
43
  result = find_all(vars, true)
44
44
  result.each_pair do |name, hash|
45
- success.push name if hash[:elements].nil?
45
+ success.push name if hash[:elements].empty?
46
46
  end
47
47
  raise "Check of #{@scope} failed! Lost: #{success}" unless success.empty?
48
48
 
@@ -58,7 +58,9 @@ module Locatine
58
58
  def find_one(name, hash, vars, strict)
59
59
  locator = { xpath: @search.send(:generate_xpath, hash, vars) } if strict
60
60
  elements = @search.collect(scope: @scope, name: name,
61
- locator: locator, exact: strict)
61
+ locator: locator,
62
+ exact: strict,
63
+ no_fail: strict)
62
64
  locator = { xpath: @search.send(:generate_xpath, hash, vars) }
63
65
  { elements: elements, locator: locator }
64
66
  end
@@ -1,7 +1,7 @@
1
1
  require 'watir'
2
2
  require 'json'
3
3
  require 'fileutils'
4
- require 'chromedriver-helper'
4
+ require 'webdrivers'
5
5
 
6
6
  # Internal requires
7
7
  require 'locatine/for_search/merge'
@@ -21,6 +21,7 @@ require 'locatine/for_search/find_by_guess'
21
21
  require 'locatine/for_search/data_generate'
22
22
  require 'locatine/for_search/xpath_generator'
23
23
  require 'locatine/for_search/find_by_locator'
24
+ require 'locatine/for_search/element_selection'
24
25
 
25
26
  module Locatine
26
27
  ##
@@ -45,6 +46,7 @@ module Locatine
45
46
  include Locatine::ForSearch::DataGenerate
46
47
  include Locatine::ForSearch::FindByLocator
47
48
  include Locatine::ForSearch::XpathGenerator
49
+ include Locatine::ForSearch::ElementSelection
48
50
 
49
51
  attr_accessor :data,
50
52
  :depth,
@@ -52,7 +54,8 @@ module Locatine
52
54
  :stability_limit,
53
55
  :scope,
54
56
  :tolerance,
55
- :visual_search
57
+ :visual_search,
58
+ :no_fail
56
59
  attr_reader :json,
57
60
  :browser
58
61
  end
@@ -1,6 +1,6 @@
1
1
  module Locatine
2
2
  # constants here...
3
- VERSION = '0.02007'.freeze
3
+ VERSION = '0.02247'.freeze
4
4
  NAME = 'locatine'.freeze
5
5
  HOME = if File.readable?("#{Dir.pwd}/lib/#{Locatine::NAME}")
6
6
  "#{Dir.pwd}/lib/#{Locatine::NAME}"
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.02007'
4
+ version: '0.02247'
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-04-16 00:00:00.000000000 Z
11
+ date: 2019-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -95,19 +95,25 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '2.0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: chromedriver-helper
98
+ name: webdrivers
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '2.0'
103
+ version: '3.8'
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 3.8.0
104
107
  type: :runtime
105
108
  prerelease: false
106
109
  version_requirements: !ruby/object:Gem::Requirement
107
110
  requirements:
108
111
  - - "~>"
109
112
  - !ruby/object:Gem::Version
110
- version: '2.0'
113
+ version: '3.8'
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 3.8.0
111
117
  description: The main goal to write locators never
112
118
  email: s_seleznev_qa@hotmail.com
113
119
  executables: []
@@ -129,6 +135,7 @@ files:
129
135
  - lib/locatine/for_search/data_generate.rb
130
136
  - lib/locatine/for_search/data_logic.rb
131
137
  - lib/locatine/for_search/dialog_logic.rb
138
+ - lib/locatine/for_search/element_selection.rb
132
139
  - lib/locatine/for_search/file_work.rb
133
140
  - lib/locatine/for_search/find_by_css.rb
134
141
  - lib/locatine/for_search/find_by_guess.rb