marta 0.26150

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +49 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +299 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/example_project/p_object/test_page.rb +31 -0
  13. data/example_project/spec/p_object/pageobjects/MartaTestPage.json +1 -0
  14. data/example_project/spec/spec_helper.rb +11 -0
  15. data/example_project/spec/watir_test_page_spec.rb +12 -0
  16. data/example_project/tests_with_learning.sh +1 -0
  17. data/example_project/tests_without_learning.sh +1 -0
  18. data/lib/marta/black_magic.rb +147 -0
  19. data/lib/marta/classes_creation.rb +21 -0
  20. data/lib/marta/data/custom-xpath.html +22 -0
  21. data/lib/marta/data/custom-xpath.js +48 -0
  22. data/lib/marta/data/element-confirm.html +18 -0
  23. data/lib/marta/data/element-confirm.js +30 -0
  24. data/lib/marta/data/element.html +23 -0
  25. data/lib/marta/data/element.js +183 -0
  26. data/lib/marta/data/for_test.html +7 -0
  27. data/lib/marta/data/for_test.js +8 -0
  28. data/lib/marta/data/page.html +24 -0
  29. data/lib/marta/data/page.js +38 -0
  30. data/lib/marta/data/style.css +209 -0
  31. data/lib/marta/dialogs.rb +124 -0
  32. data/lib/marta/injector.rb +101 -0
  33. data/lib/marta/json_2_class.rb +145 -0
  34. data/lib/marta/lightning.rb +36 -0
  35. data/lib/marta/options_and_paths.rb +140 -0
  36. data/lib/marta/public_methods.rb +51 -0
  37. data/lib/marta/read_write.rb +44 -0
  38. data/lib/marta/simple_element_finder.rb +84 -0
  39. data/lib/marta/user_values_prework.rb +26 -0
  40. data/lib/marta/version.rb +4 -0
  41. data/lib/marta/x_path.rb +170 -0
  42. data/lib/marta.rb +62 -0
  43. data/marta.gemspec +28 -0
  44. metadata +156 -0
@@ -0,0 +1,84 @@
1
+ require 'marta/x_path'
2
+
3
+ module Marta
4
+
5
+ # Marta uses simple algorithm for element location when possible
6
+ # Or when method has _exact ending
7
+ module SimpleElementFinder
8
+
9
+ private
10
+
11
+ #
12
+ # That class is about simle element location strategy
13
+ #
14
+ # @note It is believed that no user will use it
15
+ # The main idea is not to find an element but to find an xpath that leads
16
+ # to a valid element.
17
+ class BasicFinder
18
+
19
+ include XPath
20
+
21
+ def initialize(meth, engine, requestor)
22
+ @requestor = requestor
23
+ @meth = meth
24
+ @xpath = xpath_by_meth
25
+ @engine = engine
26
+ end
27
+
28
+ # Maybe our element is defined as a collection?
29
+ def collection?
30
+ @meth['options']['collection']
31
+ end
32
+
33
+ # Maybe our element has user provided xpath?
34
+ def forced_xpath?
35
+ !@meth['options']['xpath'].nil?
36
+ end
37
+
38
+ # Getting an xpath
39
+ def xpath_by_meth
40
+ if forced_xpath?
41
+ @meth['options']['xpath']
42
+ else
43
+ XPathFactory.new(@meth, @requestor).generate_xpath
44
+ end
45
+ end
46
+
47
+ # element prefinding
48
+ def prefind
49
+ @engine.element(xpath: @xpath)
50
+ end
51
+
52
+ # collection prefinding
53
+ def prefind_collection
54
+ @engine.elements(xpath: @xpath)
55
+ end
56
+
57
+ # Transforming an element to a subtype
58
+ def subtype_of(element)
59
+ element = @engine.element(xpath: @xpath).to_subtype
60
+ #https://github.com/watir/watir/issues/537
61
+ if element.class == Watir::IFrame
62
+ element = @engine.iframe(xpath: @xpath)
63
+ end
64
+ element
65
+ end
66
+
67
+ # Main logic. We are returning a prefinded collection
68
+ # or subtyped prefind
69
+ def find
70
+ if collection?
71
+ prefind_collection
72
+ else
73
+ subtype_of prefind
74
+ end
75
+ end
76
+ end
77
+
78
+ # We can simply find something
79
+ def marta_simple_finder(meth)
80
+ finder = BasicFinder.new(meth, engine, self)
81
+ finder.find
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,26 @@
1
+ module Marta
2
+
3
+ # Marta can parse strings like "hello #{value}"
4
+ module UserValuePrework
5
+
6
+ private
7
+
8
+ # Marta can parse strings like "hello #{value}"
9
+ def process_string(str='', requestor = self)
10
+ position1 = 0
11
+ # Not pretty. When you will see it again rewrite it
12
+ while (position1 != nil) and (str != nil) do
13
+ position1, position2 = str.index("\#{@"), str.index("}")
14
+ if position1 != nil
15
+ first_part = str[0, position1]
16
+ var_part = str[position1 + 2..position2 - 1]
17
+ last_part = str[position2 + 1..-1]
18
+ str = first_part +
19
+ requestor.instance_variable_get(var_part).to_s +
20
+ last_part
21
+ end
22
+ end
23
+ str.nil? ? '' : str
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ module Marta
2
+ VERSION = "0.26150"
3
+ NAME = "marta"
4
+ end
@@ -0,0 +1,170 @@
1
+ require 'marta/user_values_prework'
2
+
3
+ module Marta
4
+
5
+ # That module is about creating xpaths for element searching
6
+ module XPath
7
+
8
+ private
9
+
10
+ #
11
+ # Here we are crating xpath including arrays of xpaths with one-two-...-x
12
+ # parts that are not known
13
+ #
14
+ # @note It is believed that no user will use it
15
+ # All xpaths for Marta are constructed out of three parts:
16
+ # granny, pappy, and self. Where self is a xpath for DOM element itself,
17
+ # pappy is for father element, granny is for grandfather.
18
+ # For example //DIV/SPAN/INPUT: //DIV = granny, /SPAN = pappy,
19
+ # /INPUT = self.
20
+ #
21
+ # We are generating special arrays of hashes at first for each part.
22
+ # And then we are constructing final xpaths
23
+ class XPathFactory
24
+
25
+ include UserValuePrework
26
+
27
+ attr_accessor :granny, :pappy
28
+ def initialize(meth, requestor)
29
+ @meth = meth
30
+ @granny = @pappy = true
31
+ @requestor = requestor
32
+ end
33
+
34
+ # Getting a part (by data or empty=any)
35
+ def get_xpaths(todo, what)
36
+ if todo
37
+ form_array_hash(@meth['options'][what], @meth[what])
38
+ else
39
+ [make_hash("//", "//"), make_hash("*", "*")]
40
+ end
41
+ end
42
+
43
+ # Creating the granny part of xpath
44
+ def create_granny
45
+ # We are suggesting that granny is not a very first element
46
+ result = get_xpaths(@granny, 'granny')
47
+ result[0] = make_hash("//", "//")
48
+ result
49
+ end
50
+
51
+ # Creating the pappy part of xpath
52
+ def create_pappy
53
+ get_xpaths(@pappy, 'pappy')
54
+ end
55
+
56
+ # Creating self part of xpath
57
+ def create_self
58
+ get_xpaths(true, 'self')
59
+ end
60
+
61
+ # Full array of hashes to transform into xpath
62
+ def create_xpath
63
+ result_array = Array.new
64
+ result_array = create_granny + create_pappy + create_self
65
+ end
66
+
67
+ # Creating hash arrays from base array
68
+ def form_variants(depth)
69
+ work_array = [create_xpath]
70
+ depth.times do
71
+ temp_array = Array.new
72
+ work_array.each do |one_array|
73
+ temp_array = temp_array + form_xpaths_from_array(one_array)
74
+ end
75
+ work_array = (work_array + temp_array).uniq
76
+ end
77
+ work_array
78
+ end
79
+
80
+ #
81
+ # Creating an array of xpaths
82
+ #
83
+ # When depth is 1 we will create out of xpath = //DIV/SPAN/INPUT
84
+ # variants = //*/SPAN/INPUT, //DIV//SPAN/INPUT, //DIV/*/INPUT,
85
+ # //DIV/SPAN//INPUT, //DIV/SPAN/* and //DIV/SPAN/INPUT as well
86
+ def generate_xpaths(depth)
87
+ result_array = Array.new
88
+ form_variants(depth).each do |variant|
89
+ xpath = String.new
90
+ variant.each do |part|
91
+ xpath = xpath + part[:full]
92
+ end
93
+ result_array.push process_string(xpath, @requestor)
94
+ end
95
+ result_array
96
+ end
97
+
98
+ # Special method to get the single xpath only. Without unknowns
99
+ def generate_xpath
100
+ generate_xpaths(0).join
101
+ end
102
+
103
+ # Getting array of hashes from the raw data
104
+ def form_xpaths_from_array(array)
105
+ result_array = Array.new
106
+ array.each_with_index do |item, index|
107
+ temp_array = Array.new
108
+ array.each_with_index do |item2, index2|
109
+ if index == index2
110
+ temp_array.push make_hash(item2[:empty],item2[:empty])
111
+ else
112
+ temp_array.push make_hash(item2[:full],item2[:empty])
113
+ end
114
+ end
115
+ result_array = result_array.push temp_array
116
+ end
117
+ result_array
118
+ end
119
+
120
+ # Creating a small part of array hash for tag
121
+ def form_array_hash_for_tag(tag)
122
+ result_array = Array.new
123
+ result_array.push make_hash("/", "//")
124
+ result_array.push make_hash(tag, "*")
125
+ result_array
126
+ end
127
+
128
+ # Creating an array hash
129
+ def form_array_hash(tag, attrs)
130
+ result_array = form_array_hash_for_tag(tag)
131
+ attrs.each_pair do |attribute, value|
132
+ if attribute.include?('class')
133
+ result_array = result_array +
134
+ form_array_hash_for_class(attribute, value)
135
+ else
136
+ result_array.push form_hash_for_attribute(attribute, value)
137
+ end
138
+ end
139
+ result_array
140
+ end
141
+
142
+ # Creating a small part of array hash for attribute
143
+ def form_hash_for_attribute(attribute, value)
144
+ result_array = Array.new
145
+ if attribute == 'retrieved_by_marta_text'
146
+ make_hash("[contains(text(),'#{value}')]", "")
147
+ else
148
+ make_hash("[@#{attribute}='#{value}']", "")
149
+ end
150
+ end
151
+
152
+ # Creating a small part of array hash for attribute contains 'class'
153
+ def form_array_hash_for_class(attribute, value)
154
+ result_array = Array.new
155
+ value.each do |value_part|
156
+ if value_part.gsub(' ','') != ''
157
+ result_array.push make_hash("[contains(@#{attribute},"\
158
+ "'#{value_part}')]", "")
159
+ end
160
+ end
161
+ result_array
162
+ end
163
+
164
+ # Creating the smallest possible part of array hash
165
+ def make_hash(full, empty)
166
+ {full: "#{full}", empty: "#{empty}"}
167
+ end
168
+ end
169
+ end
170
+ end
data/lib/marta.rb ADDED
@@ -0,0 +1,62 @@
1
+ require "marta/version"
2
+ require 'marta/public_methods'
3
+ require 'marta/options_and_paths'
4
+ require 'marta/read_write'
5
+ require 'marta/user_values_prework'
6
+ require 'marta/dialogs'
7
+ require 'marta/classes_creation'
8
+ require 'marta/lightning'
9
+ require 'marta/injector'
10
+ require 'marta/json_2_class'
11
+ require 'marta/black_magic'
12
+ require 'marta/simple_element_finder'
13
+ require 'marta/x_path'
14
+ require "watir"
15
+ require 'fileutils'
16
+ require 'json'
17
+
18
+ #
19
+ # Marta class is providing three simple methods.
20
+ #
21
+ # const_missing is hijacked. And in a learn mode marta will treat any unknown
22
+ # constant as an unknown pageobject and will try to ask about using browser
23
+ module Marta
24
+
25
+ include OptionsAndPaths, ReadWrite, Json2Class
26
+
27
+ class SmartPage
28
+ include BlackMagic, XPath, SimpleElementFinder, ClassesCreation,
29
+ PublicMethods, Dialogs, Injector, Lightning, OptionsAndPaths,
30
+ Json2Class, ReadWrite, UserValuePrework
31
+ end
32
+
33
+ # That is how Marta connected to the world
34
+
35
+ # We will ask user about completely new class
36
+ def Object.const_missing(const, *args, &block)
37
+ if !SettingMaster.learn_status
38
+ raise NameError, "#{const} is not defined."
39
+ else
40
+ data, data['vars'], data['meths'] = Hash.new, Hash.new, Hash.new
41
+ SmartPageCreator.json_2_class(ReaderWriter.file_write(const.to_s, data))
42
+ end
43
+ end
44
+
45
+ # Marta is returning an engine (it should be a browser instance)
46
+ # Watir::Browser.new(:chrome) by default
47
+ def engine
48
+ SettingMaster.engine
49
+ end
50
+
51
+ # dance_with is for creating settings to be used later.
52
+ # Settings can be changed at any time by calling dance with.
53
+ # Read more in the README
54
+ def dance_with(browser: nil, folder: nil, learn: nil, tolerancy: nil)
55
+ SettingMaster.set_engine browser
56
+ SettingMaster.set_folder folder
57
+ SettingMaster.set_learn learn
58
+ SmartPageCreator.create_all
59
+ SettingMaster.set_tolerancy tolerancy
60
+ engine
61
+ end
62
+ end
data/marta.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'marta/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = Marta::NAME
8
+ spec.version = Marta::VERSION
9
+ spec.authors = ["Sergei Seleznev"]
10
+ spec.email = ["s_seleznev_qa@hotmail.com"]
11
+
12
+ spec.summary = "That will be an another one watir-webdriver wrap"
13
+ spec.description = "It's nothing to describe now."
14
+ spec.homepage = "https://github.com/sseleznevqa/marta"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + Dir.glob("lib/marta/data/*")
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_dependency "watir"
26
+ #spec.add_dependency "fileutils"
27
+ spec.add_dependency "json"
28
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: marta
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.26150'
5
+ platform: ruby
6
+ authors:
7
+ - Sergei Seleznev
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: watir
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: It's nothing to describe now.
84
+ email:
85
+ - s_seleznev_qa@hotmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - CODE_OF_CONDUCT.md
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/console
99
+ - bin/setup
100
+ - example_project/p_object/test_page.rb
101
+ - example_project/spec/p_object/pageobjects/MartaTestPage.json
102
+ - example_project/spec/spec_helper.rb
103
+ - example_project/spec/watir_test_page_spec.rb
104
+ - example_project/tests_with_learning.sh
105
+ - example_project/tests_without_learning.sh
106
+ - lib/marta.rb
107
+ - lib/marta/black_magic.rb
108
+ - lib/marta/classes_creation.rb
109
+ - lib/marta/data/custom-xpath.html
110
+ - lib/marta/data/custom-xpath.js
111
+ - lib/marta/data/element-confirm.html
112
+ - lib/marta/data/element-confirm.js
113
+ - lib/marta/data/element.html
114
+ - lib/marta/data/element.js
115
+ - lib/marta/data/for_test.html
116
+ - lib/marta/data/for_test.js
117
+ - lib/marta/data/page.html
118
+ - lib/marta/data/page.js
119
+ - lib/marta/data/style.css
120
+ - lib/marta/dialogs.rb
121
+ - lib/marta/injector.rb
122
+ - lib/marta/json_2_class.rb
123
+ - lib/marta/lightning.rb
124
+ - lib/marta/options_and_paths.rb
125
+ - lib/marta/public_methods.rb
126
+ - lib/marta/read_write.rb
127
+ - lib/marta/simple_element_finder.rb
128
+ - lib/marta/user_values_prework.rb
129
+ - lib/marta/version.rb
130
+ - lib/marta/x_path.rb
131
+ - marta.gemspec
132
+ homepage: https://github.com/sseleznevqa/marta
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.5.1
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: That will be an another one watir-webdriver wrap
156
+ test_files: []