marta 0.26150

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.
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: []