locatine 0.02327 → 0.02432

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: 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