locatine 0.00695 → 0.01084

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: 243bb8f7b9d129d5e150c06fedde26e259b6ab3b
4
- data.tar.gz: 12bbfbb7c9a0e02b17354b925a824f1a933434f5
3
+ metadata.gz: 38885391980f7e8d2b0cef65643f998edf5074cf
4
+ data.tar.gz: f321d064c113b65f024d8d22bd52bfd0ab6a56d8
5
5
  SHA512:
6
- metadata.gz: bf8572d806425b259429a81b2e4461f295396e3af8bf69c1f2eda4d638f959f78b636a9a44001c812d1079ea86d51b32079b26c924f283ae78c700e2245f9ba9
7
- data.tar.gz: 5d317c2c22853ed9a74ace1e01cdfd1dfc3c4665df1d98b5f946f74fe2e39116a81b0394ffa219ea52a7776ff377f134552e82f7d3684af855542ebc621b6396
6
+ metadata.gz: 110afe53c901b20d93cdc7c34c2846e82c5b361d96068e368a42ad907278bb124eed0fdc53bc993a77f87afae72b744a03bd41e7e7156679a62604a6a76a115b
7
+ data.tar.gz: 02105771e43ba72453ebbb238be198408037c11fd90e2169f0e79f44d96efc49a1c4bed2c08dcf8e5068e34c08c2725bb015343475074b9a48707e9a52937764
@@ -0,0 +1,9 @@
1
+ chrome.browserAction.onClicked.addListener(
2
+ function(tab) {
3
+ console.log("WAS here");
4
+ chrome.windows.create( {'url': 'popup.html',
5
+ 'type': 'popup',
6
+ 'width': 800,
7
+ 'height': 600});
8
+
9
+ });
@@ -0,0 +1,40 @@
1
+ @keyframes locatine_found {
2
+ 0% {border: 4px dashed #6495ED;}
3
+ 20% {border: 4px dashed #FF7F50;}
4
+ 40% {border: 4px dashed #8FBC8F;}
5
+ 60% {border: 4px dashed #FFA500;}
6
+ 80% {border: 4px dashed #DDA0DD;}
7
+ 100% {border: 4px dashed #6495ED;}
8
+ }
9
+
10
+ div[locatinestyle=true] {
11
+ position:fixed;
12
+ padding:0;
13
+ margin:0;
14
+ top:0;
15
+ left:0;
16
+ opacity: 0;
17
+ background: black;
18
+ height: 100%;
19
+ width: 100%;
20
+ pointer-events: visible;
21
+ display: block;
22
+ z-index: 2147483646;
23
+ }
24
+
25
+ div[locatinestyle=false] {
26
+ height: 0%;
27
+ width: 0%;
28
+ }
29
+
30
+ div[locatinestyle=blocked] {
31
+ height: 0%;
32
+ width: 0%;
33
+ }
34
+
35
+ [locatineclass=foundbylocatine]
36
+ {animation: locatine_found 6s infinite;
37
+ -webkit-appearance: none;
38
+ -moz-appearance: none;
39
+ appearance: none;
40
+ }
@@ -0,0 +1,94 @@
1
+ async function set_value(name, value){
2
+ let temp = {};
3
+ temp[name] = value;
4
+ await chrome.storage.sync.set(temp, function() {});
5
+ };
6
+
7
+ async function get_value(name) {
8
+   let x = await new Promise((resolve, reject) => chrome.storage.sync.get([name], resolve));
9
+ return x[name];
10
+ };
11
+
12
+ document.addEventListener("locatine_send", async function(e) {
13
+ await set_value(e.detail.varname, e.detail.varvalue);
14
+ });
15
+
16
+ async function refreshData(){
17
+ if (!document.getElementById("locatine_magic_div")){
18
+ const options = {
19
+ "locatineclass": "locatine_smthing",
20
+ "id":"locatine_magic_div",
21
+ "locatinestyle": await get_value('magic_div') || "false",
22
+ "locatinetitle": "ok",
23
+ "locatinehint": "ok"
24
+ };
25
+ locatine_create_element(document.body, "div", options, "");
26
+ } else {
27
+ const magicDiv = document.getElementById("locatine_magic_div");
28
+ if (magicDiv.getAttribute("locatinestyle") === "set_true") {
29
+ await set_value('magic_div', true);
30
+ magicDiv.setAttribute("locatinestyle", "true");
31
+ };
32
+ if (magicDiv.getAttribute("locatinetitle") != "ok") {
33
+ await set_value('locatine_title', magicDiv.getAttribute("locatinetitle"));
34
+ await set_value('locatine_hint', magicDiv.getAttribute("locatinehint"));
35
+ magicDiv.setAttribute("locatinetitle", "ok");
36
+ }
37
+ let status = await get_value('magic_div');
38
+ if (magicDiv.getAttribute("locatinestyle") != "set_true"){
39
+ magicDiv.setAttribute("locatinestyle", status);
40
+ }
41
+ magicDiv.setAttribute("locatinecollection", await get_value("locatine_collection"))
42
+ if (magicDiv.getAttribute("locatineconfirmed") === "ok") {
43
+ magicDiv.removeAttribute("tag");
44
+ magicDiv.removeAttribute("index");
45
+ await set_value("locatine_confirm", false);
46
+ await set_value('magic_div', false);
47
+ }
48
+ const confirmed = await get_value('locatine_confirm');
49
+ magicDiv.setAttribute("locatineconfirmed", confirmed);
50
+ };
51
+ const magic_cover = document.getElementById('locatine_magic_div');
52
+ magic_cover.onclick = function(e) {locatine_magic_click(e)};
53
+ };
54
+
55
+ function getSelected(value){
56
+ const tagName = value.tagName;
57
+ const array = Array.prototype.slice.call( document.getElementsByTagName(tagName) );
58
+ const index = array.indexOf(value);
59
+ document.getElementById("locatine_magic_div").setAttribute("tag", tagName);
60
+ document.getElementById("locatine_magic_div").setAttribute("index", index);
61
+ };
62
+
63
+ function locatine_magic_click(e) {
64
+ document.getElementById("locatine_magic_div").setAttribute("locatinestyle", "blocked");
65
+ const value = document.elementFromPoint(e.clientX, e.clientY);
66
+ document.getElementById("locatine_magic_div").setAttribute("locatinestyle", "true");
67
+ const tagName = value.tagName;
68
+ const array = Array.prototype.slice.call( document.getElementsByTagName(tagName) );
69
+ const index = array.indexOf(value);
70
+ document.getElementById("locatine_magic_div").setAttribute("TAG", tagName);
71
+ document.getElementById("locatine_magic_div").setAttribute("INDEX", index);
72
+ };
73
+
74
+ function locatine_create_element(dom, tag, attrs, inner) {
75
+ const element = document.createElement(tag);
76
+ dom.appendChild(element);
77
+ for (var key in attrs) {
78
+ element.setAttribute(key, attrs[key])
79
+ };
80
+ element.innerHTML = inner;
81
+ return element;
82
+ };
83
+
84
+ //set_value('magic_div','off');
85
+
86
+ setInterval(async function(){
87
+ if (document.getElementById("locatine_magic_div")) {
88
+ if (document.getElementById("locatine_magic_div").getAttribute("locatinestyle") != "blocked") {
89
+ await refreshData()
90
+ }
91
+ } else {
92
+ await refreshData()
93
+ }
94
+ }, 100);
@@ -0,0 +1 @@
1
+ <script src="devtools.js"></script>
@@ -0,0 +1,3 @@
1
+ setInterval(function(){
2
+ chrome.devtools.inspectedWindow.eval("getSelected($0)", { useContentScriptContext: true });
3
+ }, 100);
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "Locatine app",
3
+ "version": "0.01084",
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
+ }
@@ -0,0 +1,41 @@
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
+ .green {
14
+ background-color: #4CAF50
15
+ }
16
+
17
+ .red {
18
+ background-color: #AF4C50
19
+ }
20
+
21
+ .blue {
22
+ background-color: #4C50AF
23
+ }
24
+
25
+ .header {
26
+ padding: 10px 5px 10px 5px;
27
+ text-align: center;
28
+ color: black;
29
+ font-size: 25px;
30
+ }
31
+
32
+ .hint {
33
+ padding: 10px 5px 10px 5px;
34
+ text-align: center;
35
+ background-color: #EFFA93;
36
+ box-shadow: 5px 5px 5px;
37
+ }
38
+
39
+ .block {
40
+ padding: 30px 5px 30px 5px;
41
+ }
@@ -0,0 +1,17 @@
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 class="blue button" id="watchSwitch" type="button" value="Do not watch"/>
11
+ <input class="blue button" id="mode" type="button" value="Adding mode is enabled"/>
12
+ <input class="red button" id="clearMark" type="button" value="Clear selection"/>
13
+ <input class="green button" id="confirm" type="button" value="Confirm selection"/>
14
+ </div>
15
+ <script src="popup.js"></script>
16
+ </body>
17
+ </html>
@@ -0,0 +1,50 @@
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
+ document.getElementById("mainTitle").innerText = await get_value("locatine_title");
24
+ document.getElementById("hint").innerText = await get_value("locatine_hint");
25
+ }
26
+
27
+ async function watch() {
28
+ await set_value("magic_div", !(await get_value("magic_div")));
29
+ }
30
+
31
+ function clear() {
32
+ set_value("locatine_confirm", "declined");
33
+ }
34
+
35
+ function confirm() {
36
+ set_value("locatine_confirm", true);
37
+ }
38
+
39
+ async function mode() {
40
+ await set_value("locatine_collection", !(await get_value("locatine_collection")));
41
+ }
42
+
43
+ document.getElementById("watchSwitch").onclick = function() {watch()};
44
+ document.getElementById("clearMark").onclick = function() {clear()};
45
+ document.getElementById("confirm").onclick = function() {confirm()};
46
+ document.getElementById("mode").onclick = function() {mode()};
47
+
48
+ setInterval(function(){
49
+ correct_buttons();
50
+ }, 100);
@@ -67,7 +67,16 @@ module Locatine
67
67
  # +look_in+ only elements of that kind will be used. Use Watir::Browser methods returning collections (:text_fields, :links, :divs, etc.)
68
68
  #
69
69
  # +iframe+ if provided locatine will look for elements inside of it
70
- def find(simple_name = nil, name: nil, scope: nil, exact: false, locator: {}, vars: {}, look_in: nil, iframe: nil, return_locator: false)
70
+ def find(simple_name = nil,
71
+ name: nil,
72
+ scope: nil,
73
+ exact: false,
74
+ locator: {},
75
+ vars: {},
76
+ look_in: nil,
77
+ iframe: nil,
78
+ return_locator: false,
79
+ collection: false)
71
80
  name ||= simple_name
72
81
  raise ArgumentError, ":name should be provided" if !name
73
82
  @type = look_in
@@ -85,22 +94,26 @@ module Locatine
85
94
  end
86
95
  end
87
96
  result, attributes = ask(scope, name, result, vars) if @learn
88
- raise RuntimeError, "Nothing was found for #{scope} #{name}" if !result
89
- attributes = generate_data(result, vars) if !attributes
90
- @type = nil
91
- store(attributes, scope, name)
92
- return return_locator ? {xpath: generate_xpath(attributes, vars)} : to_subtype(result)
97
+ raise RuntimeError, "Nothing was found for #{scope} #{name}" if !result && !exact
98
+ if result
99
+ attributes = generate_data(result, vars) if !attributes
100
+ store(attributes, scope, name)
101
+ return return_locator ? {xpath: generate_xpath(attributes, vars)} : to_subtype(result, collection)
102
+ else
103
+ return nil
104
+ end
93
105
  end
94
106
 
95
107
  ##
96
108
  # Find alias with return_locator option enforced
97
109
  def lctr(*args)
98
- if args.last.class == Hash
99
- args.last[:return_locator] = true
100
- else
101
- args.push({return_locator: true})
102
- end
103
- find(args)
110
+ enforce(:return_locator, true, *args)
111
+ end
112
+
113
+ ##
114
+ # Find alias with collection option enforced
115
+ def collect(*args)
116
+ enforce(:collection, true, *args)
104
117
  end
105
118
 
106
119
  private
@@ -124,6 +137,18 @@ module Locatine
124
137
  end
125
138
  end
126
139
 
140
+ def enforce(what, value, *args)
141
+ if args.last.class == Hash
142
+ args.last[what] = value
143
+ find(*args)
144
+ else
145
+ temp = Hash.new
146
+ temp[what] = value
147
+ args.push(temp)
148
+ find(*args)
149
+ end
150
+ end
151
+
127
152
  def engine
128
153
  return (@iframe || @browser)
129
154
  end
@@ -180,7 +205,7 @@ module Locatine
180
205
  end
181
206
 
182
207
  def generate_xpath(data, vars)
183
- xpath = ''
208
+ xpath = "[not(@id = 'locatine_magic_div')]"
184
209
  data.each_pair do |depth, array|
185
210
  trusted = get_trusted(array)
186
211
  trusted.each do |hash|
@@ -247,21 +272,21 @@ module Locatine
247
272
  full_part = full_part + "[contains(name(), '#{part}')]"
248
273
  end
249
274
  xpath = full_part + "[., '#{process_string(hash["value"], vars)}')]]"
250
- find_by_locator(xpath: "#{full_part}[contains(., '#{process_string(hash["value"], vars)}')]]#{correction}")
275
+ find_by_locator(xpath: "#{full_part}[contains(., '#{process_string(hash["value"], vars)}')]]#{correction}[not(@id = 'locatine_magic_div')]")
251
276
  end
252
277
 
253
278
  ##
254
279
  # Getting elements by tag
255
280
  def find_by_tag(hash, vars, depth = 0)
256
281
  correction = "/*" * depth.to_i
257
- find_by_locator(xpath: "//*[self::#{process_string(hash["value"], vars)}')]#{correction}")
282
+ find_by_locator(xpath: "//*[self::#{process_string(hash["value"], vars)}')]#{correction}[not(@id = 'locatine_magic_div')]")
258
283
  end
259
284
 
260
285
  ##
261
286
  # Getting elements by text
262
287
  def find_by_text(hash, vars, depth = 0)
263
288
  correction = "/*" * depth.to_i
264
- find_by_locator(xpath: "//*[contains(text(), '#{process_string(hash["value"], vars)}')]#{correction}")
289
+ find_by_locator(xpath: "//*[contains(text(), '#{process_string(hash["value"], vars)}')]#{correction}[not(@id = 'locatine_magic_div')]")
265
290
  end
266
291
 
267
292
  ##
@@ -308,16 +333,16 @@ module Locatine
308
333
  timeout = @cold_time
309
334
  @cold_time = 0
310
335
  name.split(" ").each do |part|
311
- all = all + find_by_locator({tag_name: part}).to_a
312
- all = all + find_by_locator({xpath: "//*[contains(text(),'#{part}')]"}).to_a
313
- all = all + find_by_locator({xpath: "//*[@*[contains(., '#{part}')]]"}).to_a
336
+ all = all + find_by_locator({xpath: "//#{part}[not(@id = 'locatine_magic_div')]"}).to_a
337
+ all = all + find_by_locator({xpath: "//*[contains(text(),'#{part}')][not(@id = 'locatine_magic_div')]"}).to_a
338
+ all = all + find_by_locator({xpath: "//*[@*[contains(., '#{part}')]][not(@id = 'locatine_magic_div')]"}).to_a
314
339
  end
315
340
  if all.length>0
316
341
  max = all.count(all.max_by {|i| all.count(i)})
317
342
  guess = (all.select {|i| all.count(i) == max}).uniq
318
343
  guess_data = generate_data(guess, vars)
319
344
  by_data = find_by_data(guess_data, vars)
320
- if by_data.nil? || (engine.elements.length/find_by_data(guess_data, vars).length <=4)
345
+ if by_data.nil? || (engine.elements.length/by_data.length <=4)
321
346
  set_title "Locatine has no good guess for #{name} in #{scope}. Try to change the name. Or just define it."
322
347
  guess = nil
323
348
  guess_data = {}
@@ -336,9 +361,9 @@ module Locatine
336
361
  element, attributes, finished, old_tag, old_index, old_element = result, {}, false, nil, nil, nil
337
362
  if !element.nil?
338
363
  attributes = generate_data(element, vars)
339
- else
364
+ elsif name.length >= 5
340
365
  set_title("Locatine is trying to guess what is #{name} in #{scope}.")
341
- element, attributes = find_by_guess(scope, name, vars) if name.length >= 5
366
+ element, attributes = find_by_guess(scope, name, vars)
342
367
  end
343
368
  while !finished do
344
369
  sleep 0.1
@@ -556,11 +581,14 @@ module Locatine
556
581
  #
557
582
  # Params:
558
583
  # +result+ must be Watir::HTMLElementCollection or Array
559
- def to_subtype(result)
560
- if result.size == 1
561
- return result[0].to_subtype
562
- else
584
+ #
585
+ # +collection+ nil, true or false
586
+ def to_subtype(result, collection)
587
+ case collection
588
+ when true
563
589
  return result
590
+ when false
591
+ return result.first.to_subtype
564
592
  end
565
593
  end
566
594
  end
@@ -1,6 +1,6 @@
1
1
  module Locatine
2
2
  # constants here...
3
- VERSION = "0.00695"
3
+ VERSION = "0.01084"
4
4
  NAME = "locatine"
5
5
  HOME = File.readable?("#{Dir.pwd}/lib/#{Locatine::NAME}")? "#{Dir.pwd}/lib/#{Locatine::NAME}" : "#{Gem.dir}/gems/#{Locatine::NAME}-#{Locatine::VERSION}/lib/#{Locatine::NAME}"
6
6
  end
data/lib/locatine.rb CHANGED
@@ -1 +1,2 @@
1
- Dir.glob("./lib/locatine/*.rb").each {|it| require it}
1
+ require "locatine/search"
2
+ require "locatine/version"
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.00695'
4
+ version: '0.01084'
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-05 00:00:00.000000000 Z
11
+ date: 2019-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -115,6 +115,15 @@ extensions: []
115
115
  extra_rdoc_files: []
116
116
  files:
117
117
  - lib/locatine.rb
118
+ - lib/locatine/app/background.js
119
+ - lib/locatine/app/content.css
120
+ - lib/locatine/app/content.js
121
+ - lib/locatine/app/devtools.html
122
+ - lib/locatine/app/devtools.js
123
+ - lib/locatine/app/manifest.json
124
+ - lib/locatine/app/popup.css
125
+ - lib/locatine/app/popup.html
126
+ - lib/locatine/app/popup.js
118
127
  - lib/locatine/search.rb
119
128
  - lib/locatine/version.rb
120
129
  homepage: https://github.com/sseleznevqa/locatine