locatine 0.02327 → 0.02432

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: a584853859a41d1442f3037bef100dec0bb1d09e
4
- data.tar.gz: 298cabc4969b4e454bb3d6bd9f5f2b5d091ff53c
3
+ metadata.gz: 2938862d7ec4f9e5db28711a7f40764d1911ea73
4
+ data.tar.gz: e6a0775a26dd2d7bd5516a8b0b198a6f4d4f7097
5
5
  SHA512:
6
- metadata.gz: 4a317d9efb1aab542d551d90272ee912edb9b7ee36df13ad74292d1ac377848995d19a786104a5db89480f636bf14d77c3b3f1271d4b408732729d8f0498baa8
7
- data.tar.gz: 99dbade69774c044b519d78e5c3ec3b0ba7469eb803e9cff80eee1fa3549bd566460ffaaf2c3c95e7a7817bd83c6dd2254101ef50666a76503a91a19a06b117f
6
+ metadata.gz: 131784b53b1c62a289587e7c7fc8faf44abce5d5121ecbd08aa6c58a2bfce1bdd05712d31aa9e2e3cafc3f76d4a390728c41a96da0635ad1b4ae44573737a858
7
+ data.tar.gz: 0c80e987bb31e5991dc917849b4069d727f6f4902688e975a03c9248f6823e827b59545f0ed59e49b78dcd400f501d097db064ee51a87a518a07532628173e29
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.02327** 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.02432** 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
 
@@ -361,3 +361,131 @@ s.exact(name: "something") == s.find(name: "something", exact: true)
361
361
  s.check(name: "something") == s.find(name: "something", tolerance: 0)
362
362
  s.check_collection(name: "something") == s.collect(name: "something", tolerance: 0)
363
363
  ```
364
+
365
+ ## Using as a daemon
366
+
367
+ Locatine daemon is a web server based on sinatra. You can run it from your code like:
368
+
369
+ ```ruby
370
+ require 'locatine'
371
+ Locatine::Daemon.set :port, 7733 #Your port goes here
372
+ Locatine::Daemon.run!
373
+ ```
374
+
375
+ Also you can do it with terminal:
376
+
377
+ ```bash
378
+ locatine-daemon.rb -port=7733
379
+ ```
380
+
381
+ You can see a python3 example in the [example](https://github.com/sseleznevqa/locatine/tree/master/example) folder. Main idea is
382
+
383
+ 1. Run daemon
384
+ 2. Ask daemon for the app path
385
+ 3. Run your browser with the app as extension
386
+ 4. Turn on the learn
387
+ 5. Provide data to the daemon for connect (browser name, session_id, connect url, proxy)
388
+ 6. Use API calls to teach daemon how to find elements
389
+ 7. After that you can start browser without the app
390
+ 8. Provide data for connect
391
+ 9. Now you can ask daemon to find your element via API call. And it will answer with a valid xpath you can use.
392
+
393
+ ### API
394
+
395
+ #### GET call to /app
396
+
397
+ returns path to locatine application in order to start chrome with it.
398
+
399
+ Example of response:
400
+
401
+ ```
402
+ {"app": "/some/path/to/app"}
403
+ ```
404
+
405
+ #### GET call to /stop
406
+
407
+ stops Locatine daemon.
408
+
409
+ Returns:
410
+
411
+ ```
412
+ {"result": "dead"}
413
+ ```
414
+
415
+ #### POST call to /connect
416
+
417
+ allows Locatine Daemon to connect existing browser instance
418
+
419
+ POST data:
420
+
421
+ ```
422
+ {'browser': 'chrome', 'session_id': session_id, 'url': 'http://whatever_is_browser_ip:port_opened_by_browser_for_selenium', 'proxy': 'optionally' }
423
+ ```
424
+
425
+ Answer:
426
+
427
+ ```
428
+ {"result": "true"}
429
+ ```
430
+
431
+ #### POST call to /set
432
+
433
+ is to control options of locatine search. Sending to set data ==
434
+
435
+ ```
436
+ {"learn": "true"}
437
+ ```
438
+
439
+ Answer:
440
+
441
+ ```
442
+ {"result": "true"}
443
+ ```
444
+
445
+ is the same as
446
+
447
+ ```ruby
448
+ search.learn = true
449
+ ```
450
+
451
+ #### POST call to /lctr
452
+
453
+ is to find and return locator of an element found by locatine
454
+
455
+ POST data just the same as for find or lctr method. It's like:
456
+
457
+ ```
458
+ {"name": "some name", "scope": "Default", "exact": "false" ...}
459
+ ```
460
+
461
+ Answer:
462
+
463
+ ```
464
+ {"xpath": "//YOUR[@xpath='goes here']"}
465
+ ```
466
+
467
+ ### GET /chromedriver || /geckodriver || /iedriver
468
+
469
+ returns path to the binary retrieved by locatine (using webdrivers gem)
470
+
471
+ Answer:
472
+
473
+ ```
474
+ {"path": "path/to/the/binary"}
475
+ ```
476
+
477
+ ### POST call to /chromedriver || /geckodriver || /iedriver
478
+
479
+ is to force locatine to use your webdriver (for example for using old version of browser)
480
+
481
+ POST data:
482
+
483
+ ```
484
+ {"version": "2.46"}
485
+ ```
486
+
487
+ Answer:
488
+
489
+ ```
490
+ {"version": "2.46"}
491
+ ```
@@ -0,0 +1,8 @@
1
+ #!Locatine-daemon...
2
+ require 'locatine'
3
+ args = Hash[ ARGV.join(' ').scan(/--?([^=\s]+)(?:=(\S+))?/) ]
4
+ args = args.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
5
+ args.each_pair do |key, value|
6
+ Locatine::Daemon.set key, value
7
+ end
8
+ Locatine::Daemon.run!
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Locatine app",
3
- "version": "0.02327",
3
+ "version": "0.02432",
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,93 @@
1
+ require 'sinatra/base'
2
+ require 'json'
3
+ require 'locatine/daemon_helpers'
4
+
5
+ module Locatine
6
+ #
7
+ # Locatine daemon based on sinatra
8
+ #
9
+ # run Locatine::Daemon.run!
10
+ class Daemon < Sinatra::Base
11
+ include Locatine::DaemonHelpers
12
+ configure do
13
+ set :search, nil
14
+ end
15
+
16
+ get '/app' do
17
+ { app: File.join(Locatine::HOME, 'app').to_s }.to_json
18
+ end
19
+
20
+ get '/' do
21
+ redirect 'https://github.com/sseleznevqa/locatine#using-as-a-daemon'
22
+ end
23
+
24
+ get '/stop' do
25
+ Locatine::Daemon.quit!
26
+ { result: 'dead' }.to_json
27
+ end
28
+
29
+ post '/chromedriver' do
30
+ Webdrivers::Chromedriver.required_version = params['version']
31
+ { version: Webdrivers::Chromedriver.required_version }.to_json
32
+ end
33
+
34
+ get '/chromedriver' do
35
+ { path: Webdrivers::Chromedriver.update }.to_json
36
+ end
37
+
38
+ post '/geckodriver' do
39
+ Webdrivers::Geckodriver.required_version = params['version']
40
+ { version: Webdrivers::Geckodriver.required_version }.to_json
41
+ end
42
+
43
+ get '/geckodriver' do
44
+ { path: Webdrivers::Geckodriver.update }.to_json
45
+ end
46
+
47
+ post 'iedriver' do
48
+ Webdrivers::IEdriver.required_version = params['version']
49
+ { version: Webdrivers::IEdriver.required_version }.to_json
50
+ end
51
+
52
+ get '/iedriver' do
53
+ { path: Webdrivers::IEdriver.update }.to_json
54
+ end
55
+
56
+ post '/connect' do
57
+ steal
58
+ { result: true }.to_json
59
+ end
60
+
61
+ post '/lctr' do
62
+ data = Hash[params.map { |k, v| [k.to_sym, v] }]
63
+ data.each { |k, v| data[k] = false if v == 'false' }
64
+ search.lctr(data).to_json
65
+ end
66
+
67
+ post '/set' do
68
+ hash = params
69
+ search.json = hash['json'] if hash['json']
70
+ warn 'You cannot set browser like this. Use /connect' if hash['browser']
71
+ params.each_pair do |key, value|
72
+ unless (key == 'browser') || (key == 'json')
73
+ value = false if value == 'false'
74
+ search.instance_variable_set("@#{key}", value)
75
+ end
76
+ end
77
+ { result: true }.to_json
78
+ end
79
+
80
+ def search
81
+ return settings.search unless settings.search.nil?
82
+
83
+ settings.search = Locatine::Search.new
84
+ settings.search.browser.quit
85
+ settings.search
86
+ end
87
+
88
+ def params
89
+ request.body.rewind
90
+ JSON.parse request.body.read
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,52 @@
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
@@ -0,0 +1,45 @@
1
+ module Locatine
2
+ module ForSearch
3
+ ##
4
+ # Default settings for search are living here
5
+ module Defaults
6
+ private
7
+ def default_init_config
8
+ { json: './Locatine_files/default.json',
9
+ depth: 3,
10
+ browser: nil,
11
+ learn: ENV['LEARN'].nil? ? false : true,
12
+ stability_limit: 1000,
13
+ scope: 'Default',
14
+ tolerance: 67,
15
+ visual_search: false,
16
+ no_fail: false,
17
+ trusted: [],
18
+ untrusted: []
19
+ }
20
+ end
21
+
22
+ def import_browser(browser)
23
+ selenium = browser.class.superclass == Selenium::WebDriver::Driver
24
+ b = right_browser unless browser
25
+ b = browser if browser.class == Watir::Browser
26
+ b = Watir::Browser.new(browser) if selenium
27
+ @browser = b
28
+ @default_styles = default_styles.to_a
29
+ end
30
+
31
+ def import_file(json)
32
+ @json = json
33
+ @folder = File.dirname(@json)
34
+ @name = File.basename(@json)
35
+ @data = read_create
36
+ end
37
+
38
+ def import_config(config)
39
+ config.each_pair do |key, value|
40
+ self.instance_variable_set("@#{key.to_s}", value)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -17,13 +17,6 @@ module Locatine
17
17
  hash.merge(JSON.parse(File.read(@json))['data'])
18
18
  end
19
19
 
20
- def import_file(json)
21
- @json = json
22
- @folder = File.dirname(@json)
23
- @name = File.basename(@json)
24
- @data = read_create
25
- end
26
-
27
20
  def create_json_file
28
21
  f = File.new(@json, 'w')
29
22
  f.puts '{"data" : {}}'
@@ -64,15 +64,6 @@ module Locatine
64
64
  Watir::Browser.new(:chrome, switches: ["--load-extension=#{HOME}/app"])
65
65
  end
66
66
 
67
- def import_browser(browser)
68
- selenium = browser.class.superclass == Selenium::WebDriver::Driver
69
- b = right_browser unless browser
70
- b = browser if browser.class == Watir::Browser
71
- b = Watir::Browser.new(browser) if selenium
72
- @browser = b
73
- @default_styles = default_styles.to_a
74
- end
75
-
76
67
  def css_text_to_hash(text)
77
68
  almost_hash = []
78
69
  array = text[0..-2].split('; ')
@@ -28,28 +28,21 @@ module Locatine
28
28
  # to the lost one. Default is 67 which means that if less than 33% of
29
29
  # metrics of alternative elements are the same as of the lost element
30
30
  # will not be returned
31
- def initialize(json: './Locatine_files/default.json',
32
- depth: 3,
33
- browser: nil,
34
- learn: ENV['LEARN'].nil? ? false : true,
35
- stability_limit: 1000,
36
- scope: 'Default',
37
- tolerance: 67,
38
- visual_search: false,
39
- no_fail: false,
40
- trusted: [],
41
- untrusted: [])
42
- import_browser browser
43
- import_file(json)
44
- @depth = depth
45
- @learn = learn
46
- @stability_limit = stability_limit
47
- @scope = scope
48
- @tolerance = tolerance
49
- @visual_search = visual_search
50
- @no_fail = no_fail
51
- @trusted = trusted
52
- @untrusted = untrusted
31
+ #
32
+ # +visual_search+ locatine will use position and style if true
33
+ #
34
+ # +no_fail+ if true locatine is not producing errors on element loss.
35
+ #
36
+ # +trusted+ array of names of attributes and element params to use
37
+ # in search always.
38
+ #
39
+ # +untrusted+ array of names of attributes and element params to use
40
+ # in search never.
41
+ def initialize(config = {})
42
+ init_config = default_init_config.merge(config)
43
+ import_browser init_config.delete :browser
44
+ import_file init_config.delete :json
45
+ import_config init_config
53
46
  end
54
47
 
55
48
  ##
@@ -84,6 +77,14 @@ module Locatine
84
77
  #
85
78
  # +tolerance+ It is possible to set a custom tolerance for every find. See
86
79
  # examples in README
80
+ #
81
+ # +no_fail+ if true locatine is not producing errors on element loss.
82
+ #
83
+ # +trusted+ array of names of attributes and element params to use
84
+ # in search always.
85
+ #
86
+ # +untrusted+ array of names of attributes and element params to use
87
+ # in search never.
87
88
  def find(simple_name = nil,
88
89
  name: nil,
89
90
  scope: nil,
@@ -15,7 +15,7 @@ module Locatine
15
15
  end
16
16
 
17
17
  def max_stability(array)
18
- max = (array.max_by { |i| i['stability'].to_i })
18
+ max = (array.max_by { |i| i['stability'].to_i }) if array
19
19
  return max['stability'] if max
20
20
 
21
21
  return 0
@@ -8,6 +8,7 @@ require 'locatine/for_search/merge'
8
8
  require 'locatine/for_search/public'
9
9
  require 'locatine/for_search/saying'
10
10
  require 'locatine/for_search/helpers'
11
+ require 'locatine/for_search/defaults'
11
12
  require 'locatine/for_search/file_work'
12
13
  require 'locatine/for_search/listening'
13
14
  require 'locatine/for_search/highlight'
@@ -33,6 +34,7 @@ module Locatine
33
34
  include Locatine::ForSearch::Public
34
35
  include Locatine::ForSearch::Saying
35
36
  include Locatine::ForSearch::Helpers
37
+ include Locatine::ForSearch::Defaults
36
38
  include Locatine::ForSearch::FileWork
37
39
  include Locatine::ForSearch::DataLogic
38
40
  include Locatine::ForSearch::Listening
@@ -1,6 +1,6 @@
1
1
  module Locatine
2
2
  # constants here...
3
- VERSION = '0.02327'.freeze
3
+ VERSION = '0.02432'.freeze
4
4
  NAME = 'locatine'.freeze
5
5
  HOME = if File.readable?("#{Dir.pwd}/lib/#{Locatine::NAME}")
6
6
  "#{Dir.pwd}/lib/#{Locatine::NAME}"
data/lib/locatine.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  require 'locatine/search'
2
2
  require 'locatine/scope'
3
3
  require 'locatine/version'
4
+ require 'locatine/daemon'
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.02327'
4
+ version: '0.02432'
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-05-13 00:00:00.000000000 Z
11
+ date: 2019-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,27 +100,43 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '3.8'
103
+ version: '4.0'
104
104
  - - ">="
105
105
  - !ruby/object:Gem::Version
106
- version: 3.8.0
106
+ version: 4.0.1
107
107
  type: :runtime
108
108
  prerelease: false
109
109
  version_requirements: !ruby/object:Gem::Requirement
110
110
  requirements:
111
111
  - - "~>"
112
112
  - !ruby/object:Gem::Version
113
- version: '3.8'
113
+ version: '4.0'
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
- version: 3.8.0
116
+ version: 4.0.1
117
+ - !ruby/object:Gem::Dependency
118
+ name: sinatra
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: 2.0.5
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: 2.0.5
117
131
  description: The main goal to write locators never
118
132
  email: s_seleznev_qa@hotmail.com
119
- executables: []
133
+ executables:
134
+ - locatine-daemon.rb
120
135
  extensions: []
121
136
  extra_rdoc_files: []
122
137
  files:
123
138
  - README.md
139
+ - bin/locatine-daemon.rb
124
140
  - lib/locatine.rb
125
141
  - lib/locatine/app/background.js
126
142
  - lib/locatine/app/content.css
@@ -131,9 +147,12 @@ files:
131
147
  - lib/locatine/app/popup.css
132
148
  - lib/locatine/app/popup.html
133
149
  - lib/locatine/app/popup.js
150
+ - lib/locatine/daemon.rb
151
+ - lib/locatine/daemon_helpers.rb
134
152
  - lib/locatine/for_search.rb
135
153
  - lib/locatine/for_search/data_generate.rb
136
154
  - lib/locatine/for_search/data_logic.rb
155
+ - lib/locatine/for_search/defaults.rb
137
156
  - lib/locatine/for_search/dialog_logic.rb
138
157
  - lib/locatine/for_search/element_selection.rb
139
158
  - lib/locatine/for_search/file_work.rb