taft 0.1.0 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -3
  3. data/examples/ruby/rs/framework/red_sky.rb +11 -0
  4. data/examples/ruby/rs/framework/red_sky/api_helpers/general.rb +140 -0
  5. data/examples/ruby/rs/framework/red_sky/api_helpers/rest.rb +249 -0
  6. data/examples/ruby/rs/framework/red_sky/ui_helpers/ui_general.rb +36 -0
  7. data/examples/ruby/rs/framework/red_sky/watir/custom/all.rb +4 -0
  8. data/examples/ruby/rs/framework/red_sky/watir/custom/rs_custom.rb +32 -0
  9. data/examples/ruby/rs/framework/red_sky/watir/pages/page_objects.rb +166 -0
  10. data/examples/ruby/rs/framework/red_sky/watir/pages/rs_pages.rb +68 -0
  11. data/examples/ruby/rs/lib/config/red_sky_config.rb +27 -0
  12. data/examples/ruby/rs/lib/config/runtime_constants.rb +20 -0
  13. data/examples/ruby/rs/lib/red_sky_test_case.rb +218 -0
  14. data/examples/ruby/rs/tests/v1/tc_r001_01_an_example_test.rb +112 -0
  15. data/examples/ruby/rs/tests/v1/tc_r001_01_google_search.rb +64 -0
  16. data/lib/taft.rb +2 -0
  17. data/lib/taft_files/framework/zznamezz.rb +3 -0
  18. data/lib/taft_files/framework/zznamezz/api_helpers/general.rb +13 -13
  19. data/lib/taft_files/framework/zznamezz/ui_helpers/ui_general.rb +26 -0
  20. data/lib/taft_files/framework/zznamezz/watir/custom/all.rb +4 -0
  21. data/lib/taft_files/framework/zznamezz/watir/custom/xxabbrevxx_custom.rb +32 -0
  22. data/lib/taft_files/framework/zznamezz/watir/pages/page_objects.rb +166 -0
  23. data/lib/taft_files/framework/zznamezz/watir/pages/xxabbrevxx_pages.rb +101 -0
  24. data/lib/taft_files/lib/config/runtime_constants.rb +5 -1
  25. data/lib/taft_files/lib/config/zznamezz_config.rb +7 -2
  26. data/lib/taft_files/lib/zznamezz_test_case.rb +43 -42
  27. data/lib/taft_files/tests/v1/tc_r001_01_an_example_test.rb +1 -1
  28. data/taft.gemspec +5 -5
  29. metadata +23 -6
@@ -0,0 +1,4 @@
1
+ # simple require class for the Custom folder
2
+
3
+ # use require_relative, not require
4
+ require_relative 'rs_custom'
@@ -0,0 +1,32 @@
1
+
2
+ # All methods in this module will be added to those classes. If methods with the
3
+ # same names exist, these methods will overwrite the pre-existing ones.
4
+
5
+ module RedSkyCustom
6
+
7
+ # Example code :
8
+ #
9
+ # class RSPage
10
+ #
11
+ # # All page titles exist in the same-named element
12
+ # def title_field
13
+ # browser.h1(:id => "page_title")
14
+ # end
15
+ #
16
+ # def title
17
+ # title_field.value
18
+ # end
19
+ #
20
+ # end
21
+ #
22
+ # class RSHomepage
23
+ #
24
+ # def displayed?
25
+ # puts "In #{__method__}"
26
+ # title == "Welcome to RedSky"
27
+ # end
28
+ #
29
+ # end
30
+ #
31
+
32
+ end
@@ -0,0 +1,166 @@
1
+ # Base class that every defined page will inherit from
2
+ class Page
3
+
4
+ attr_accessor :name, :displayed_field, :displayed_value
5
+ attr_accessor :browser
6
+ attr_accessor :field_parameters_array # stores parameters of each field added to the page
7
+
8
+ # Name : the name of this page, e.g. rsHomepage
9
+ # Field : the field used to determine if the page is displayed. More precisely,
10
+ # the name of the method that accesses the field. E.g. if the page has a field called 'page_title'
11
+ # defined, then its accessor method 'page_title_field' will have been generated .
12
+ # If the displayed? check is against an expected value, specify the field name corresponding to
13
+ # the read-method (e.g. page_title), and specify the value (String or Regexp).
14
+ # If the displayed? check is for a field to exist, specify the field's accessor method name
15
+ # (e.g. page_title_field), and keep value nil.
16
+ def initialize(name, field, value = nil)
17
+ @name = name
18
+ @displayed_field = field
19
+ @displayed_value = value
20
+ @field_parameters_array = []
21
+ end
22
+
23
+ def displayed?(wait = true)
24
+ displayed = false
25
+ puts "in displayed? for page #{@name}"
26
+ if wait
27
+ puts "will wait for page to be loaded"
28
+ wait_until_displayed
29
+ end
30
+
31
+ puts "about to send to #{@displayed_field.to_sym.inspect}"
32
+ begin
33
+ field_or_value = self.send(@displayed_field.to_sym)
34
+ rescue Watir::Exception::UnknownObjectException
35
+ # cannot find the field on the page
36
+ # do nothing, displayed will stay false
37
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError
38
+ # TODO : fix! wait then call displayed? again?
39
+ puts "hit StaleElementReferenceError for page #{@name}"
40
+ end
41
+
42
+ puts "field_or_value retrieved is of class #{field_or_value.class}"
43
+ p field_or_value
44
+ if @displayed_value == nil
45
+ displayed = true if field_or_value.exists?
46
+ else
47
+ if @displayed_value.class == Regexp
48
+ displayed = true if field_or_value =~ @displayed_value
49
+ else
50
+ displayed = true if field_or_value == @displayed_value
51
+ end
52
+ end
53
+ displayed
54
+ end
55
+
56
+ # Method to wait for the page to be displayed, up to <timeout> seconds
57
+ # Returns displayed status (true/false)
58
+ def wait_until_displayed(timeout = 5)
59
+ max = timeout * 10
60
+ count = 0
61
+ displayed = false
62
+ while count < max
63
+ displayed = displayed?(false)
64
+ break if displayed
65
+ sleep 0.2
66
+ count += 2
67
+ end
68
+ displayed
69
+ end
70
+
71
+ # Defines methods to access the field of specified type, by specified key & value
72
+ def add_field(name, type, key, value)
73
+ field_parameters_array << [name, type, key, value]
74
+ add_field_using_constructor_class(name, type, key, value)
75
+ end
76
+
77
+ # Add to self all fields that were defined on page_object
78
+ # E.g. the supplied page_object represents part of a panel/page that is common to several pages
79
+ def add_page(page_object)
80
+ page_object.field_parameters_array.each do |field_parameters|
81
+ add_field(field_parameters[0], field_parameters[1], field_parameters[2], field_parameters[3])
82
+ end
83
+ end
84
+
85
+ # Defines methods to access the field of specified type, by specified key & value
86
+ def add_field_using_constructor_class(name, type, key, value)
87
+ PageFieldConstructor.add_fields(self, name, type, key, value)
88
+ end
89
+
90
+ end # end Page
91
+
92
+ class PageFieldConstructor
93
+
94
+ # Defines methods to access the field of specified type, by specified key & value
95
+ def PageFieldConstructor.add_fields(page_object, name, type, key, value)
96
+
97
+ # Fields cannot have the following names : name
98
+ raise "Field on page #{page_object.name} with name of #{name} is not allowed" if RedSkyConfig::DISALLOWED_FIELD_NAMES.include?(name)
99
+
100
+ case type
101
+ when :button
102
+ real_type = :input
103
+ else
104
+ real_type = type
105
+ end
106
+
107
+ # add accessor to field
108
+ s = <<-METHOD
109
+ def page_object.#{name}_field
110
+ # puts "in #{name} method"
111
+ @browser.#{real_type}(#{key.inspect} => "#{value}")
112
+ end
113
+ METHOD
114
+ # page_object.class.module_eval(s) # do not do this - want to add methods (field) to the object, not the class!
115
+ eval(s)
116
+
117
+ case type
118
+ when :text_field
119
+ add_read_method(page_object, name)
120
+ add_write_method(page_object, name)
121
+ when :button
122
+ add_click_method(page_object, name)
123
+ when :link
124
+ add_read_method(page_object, name)
125
+ add_click_method(page_object, name)
126
+ else
127
+ add_read_method(page_object, name)
128
+ end
129
+
130
+ end
131
+
132
+ def PageFieldConstructor.add_read_method(page_object, name)
133
+ s = <<-READ
134
+ def page_object.#{name}
135
+ # puts "in #{name} read method"
136
+ #{name}_field.text # value
137
+ end
138
+ READ
139
+ # page_object.class.module_eval(s) # do not do this - want to add methods (field) to the object, not the class!
140
+ eval(s)
141
+ end
142
+
143
+ def PageFieldConstructor.add_write_method(page_object, name)
144
+ s = <<-WRITE
145
+ def page_object.#{name}=(v)
146
+ # puts "in #{name} write method"
147
+ #{name}_field.set(v)
148
+ end
149
+ WRITE
150
+ # page_object.class.module_eval(s) # do not do this - want to add methods (field) to the object, not the class!
151
+ eval(s)
152
+ end
153
+
154
+ def PageFieldConstructor.add_click_method(page_object, name)
155
+ s = <<-CLICK
156
+ def page_object.click_#{name}
157
+ # puts "in #{name} click method"
158
+ #{name}_field.click
159
+ end
160
+ CLICK
161
+ # page_object.class.module_eval(s) # do not do this - want to add methods (field) to the object, not the class!
162
+ eval(s)
163
+ end
164
+
165
+ end
166
+
@@ -0,0 +1,68 @@
1
+ # Class that holds definitions for all of the pages in RedSky
2
+ # These can be used to determine if the browser is currently displaying that page
3
+ #
4
+ # Field types :
5
+ # Use :text_field instead of :input if it's a text-field
6
+ # Use :button instead of :input if it's a button
7
+ # Otherwise, use the actual HTML element type
8
+
9
+ require_relative 'page_objects'
10
+
11
+ class RSPages
12
+
13
+ @@browser = nil
14
+ @@pages = [] # an array of Page objects
15
+ @@page_names = []
16
+
17
+ def self.make_pages(browser)
18
+ @@browser = browser
19
+
20
+ # Google Search
21
+ page = Page.new("googleSearch", "search_term_field")
22
+
23
+ page.add_field("search_term", :text_field, :name, "q")
24
+ page.add_field("search_button", :button, :name, "btnK")
25
+
26
+ self.add_page(page)
27
+
28
+
29
+ # Google Search Results
30
+ page = Page.new("googleSearchResults", "result_stats_field")
31
+
32
+ page.add_field("result_stats", :div, :id, "resultStats")
33
+
34
+ self.add_page(page)
35
+ end
36
+
37
+ ##################################################################################################
38
+
39
+
40
+ def self.add_page(page)
41
+ page.browser = @@browser # set the browser object for each page
42
+ # TODO have only one browser object (here in RSPages), and have each page know how to find it, instead of taking
43
+ # their own copy of the object
44
+ @@pages << page
45
+ @@page_names << page.name
46
+ end
47
+
48
+ # Outputs info on the pages currently stored
49
+ def self.info
50
+ s = ""
51
+ s += "#{@@pages.size} pages defined. Names :"
52
+ @@page_names.each {|f| s += "\n#{f}" }
53
+ s
54
+ end
55
+
56
+ # Will convert name to a string
57
+ def self.page_known?(name)
58
+ @@page_names.include?(name.to_s)
59
+ end
60
+
61
+ # Retrieves the specific page; raises if it cannot be found
62
+ # Will convert name to a string
63
+ def self.find(name)
64
+ raise "Could not locate page '#{name}'" unless self.page_known?(name)
65
+ @@pages[@@page_names.index(name.to_s)]
66
+ end
67
+ end
68
+
@@ -0,0 +1,27 @@
1
+ # Holds system configuration parameters
2
+
3
+ require_relative 'runtime_constants.rb'
4
+
5
+ class RedSkyConfig
6
+ include RuntimeConstants
7
+
8
+ CERTIFICATE_DIR = "certs"
9
+ CERTIFICATE_POPUP_TIMEOUT = 15
10
+
11
+ API_VERSION = "latest"
12
+
13
+ SERVERS = {
14
+ :test_1 => {:red_sky_url => "https://www.google.co.uk"},
15
+ :ref_1 => {:red_sky_url => "https://"},
16
+ }
17
+
18
+ SERVER = SERVERS[$TEST_ENV]
19
+
20
+
21
+ PASSED = "Passed"
22
+ FAILED = "Failed"
23
+
24
+ DISALLOWED_FIELD_NAMES = ["name"]
25
+
26
+ ALL_USER_ROLES = ["all"]
27
+ end
@@ -0,0 +1,20 @@
1
+
2
+ # This class holds parameters that may frequently change between test runs, e.g the test environment
3
+ module RuntimeConstants
4
+
5
+ $TEST_ENV = :test_1
6
+
7
+ CLOSE_BROWSER_AFTER_TEST = true # close the browser if the test passed?
8
+ FORCE_CLOSE_BROWSER_AFTER_TEST = false # always close the browser?
9
+
10
+ MAKE_ERROR_SCREENSHOTS = true
11
+ ERROR_SCREENSHOT_LOCATION = "screenshots"
12
+
13
+ WRITE_CI_REPORTS = false
14
+
15
+ BROWSER = :chrome
16
+
17
+ RESULTS_CSV = "results.csv"
18
+
19
+ end
20
+
@@ -0,0 +1,218 @@
1
+
2
+ # This file defines a module to be included in all test cases for the testing of RED SKY.
3
+ # This module contains a general setup and teardown method that each test should run.
4
+ # If tests wish to perform their own specific seup and/or teardown routines, they
5
+ # should implement their own methods and call super within them to trigger these common
6
+ # setup/teardown methods at the right time.
7
+
8
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/.."))
9
+
10
+ gem 'test-unit'
11
+ require 'test/unit'
12
+ require 'tmpdir'
13
+ require 'time'
14
+ require 'fileutils'
15
+ require 'timeout'
16
+ require 'watir'
17
+
18
+ # Config
19
+ require 'config/red_sky_config.rb'
20
+
21
+ # Helpers
22
+ require 'framework/red_sky.rb'
23
+
24
+
25
+
26
+ STDOUT.sync = true
27
+
28
+ if RedSkyConfig::WRITE_CI_REPORTS
29
+ require 'ci/reporter/rake/test_unit_loader'
30
+
31
+ ENV["CI_REPORTS"] = $CI_REPORTS_PATH # supplied in invokation to test
32
+ puts "Will create XML reports in #{ENV["CI_REPORTS"]}"
33
+ end
34
+
35
+ module RedSkyTestCase
36
+
37
+ attr_accessor :browser_has_been_opened
38
+
39
+ # optional field
40
+ # If the cause of a test's failure is already likely to be known, the contents of this variable
41
+ # will automatically be added to the test result's Notes field, to help with reporting.
42
+ # If there are multiple tests in a file, this variable needs to be set within each test
43
+ # method (if they have any relevent failure notes).
44
+ attr_accessor :failure_notes
45
+
46
+ # E.g. calling homepage.displayed? from a test script :
47
+ # Test cannot see homepage so its call is routed through method_missing
48
+ # If method_missing returns an instance of the class, .displayed? can be called on it (seamlessly)
49
+ # At present this will happen for every call to a page from a test script
50
+ def method_missing(name, *args, &block)
51
+ #puts "RedSkyTestCase method_missing called; name = #{name.inspect}; #{name.class}"
52
+
53
+ case name.to_s
54
+ when /^browser$/
55
+ browser
56
+ when /^rs/i, /^google/
57
+ RSPages.find(name.to_s) # return the page so that the helper-method can use it
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+ if $WRITE_RESULTS # supplied from invokation
64
+ WRITE_RESULTS = true
65
+ else
66
+ WRITE_RESULTS = false
67
+ end
68
+
69
+ # Connect to RED SKY and reinitialise the context, etc.
70
+ def rs_login(url = RedSkyConfig::SERVER[:red_sky_url])
71
+ browser = @help.new_browser_at_url(url)
72
+ load_pages(browser)
73
+ end
74
+
75
+ # Connect to RED SKY and reinitialise the context, etc.
76
+ def google_login(url = RedSkyConfig::SERVER[:red_sky_url])
77
+ browser = @help.new_browser_at_url(url)
78
+ load_pages(browser)
79
+ end
80
+
81
+ def load_pages(browser)
82
+ RSPages.make_pages(browser) # cannot have pages without a browser object
83
+ @browser_has_been_opened = true
84
+ end
85
+
86
+ # Close the current browser
87
+ def close_browser
88
+ browser.close
89
+ end
90
+
91
+ def close(browser)
92
+ if browser.exists? && ((RedSkyConfig::CLOSE_BROWSER_AFTER_TEST && passed?) || RedSkyConfig::FORCE_CLOSE_BROWSER_AFTER_TEST)
93
+ browser.close
94
+ $browsers.delete_at($current_browser_position - 1) # array indexing
95
+ browser = $browsers[-1] # set browser to the last one that is still in the array
96
+ end
97
+ end
98
+
99
+ def close_all_browsers
100
+ if (RedSkyConfig::CLOSE_BROWSER_AFTER_TEST && passed?) || RedSkyConfig::FORCE_CLOSE_BROWSER_AFTER_TEST
101
+ until $browsers.empty?
102
+ browser = $browsers.shift
103
+ browser.close
104
+ end
105
+ end
106
+ end
107
+
108
+
109
+ @@browser = nil
110
+
111
+ def browser
112
+ @@browser
113
+ end
114
+
115
+ def browser=(b)
116
+ @@browser = b
117
+ end
118
+ alias set_browser browser= # note : calls of "browser = " do not work, calls of "browser=" do
119
+
120
+ # Ensure that every test (that wants one) has a browser that is already logged in to the system
121
+ def setup
122
+
123
+ @help = RSHelper.new
124
+
125
+ Watir.always_locate = true # default is true; setting to false speeds up Watir to a degree
126
+
127
+ # Get start time for later output in results
128
+ @test_start_time = Time.now
129
+
130
+ # Get the directory that the specific test lives in, so that it can be included in the results file
131
+ @test_file_dir = @test_file.split(File::SEPARATOR)[-2] if @test_file
132
+
133
+ # Select default certificate if none is configured
134
+ @certificate ||= :regular
135
+
136
+ @timeout = RedSkyConfig::CERTIFICATE_POPUP_TIMEOUT
137
+
138
+ # Open the browser & ensure page contenxt and helper are available
139
+ $browsers = [] # global array containing all browser objects
140
+ # $current_browser_position = nil # global variable to track the position in $browsers of the active browser # TODO used?
141
+ # When that browser is closed, we can ensure that the corresponding browser object is removed from the array
142
+ if @initialBrowser == :rs
143
+ rs_login
144
+ elsif (@initialBrowser == :none || @initialBrowser == nil)
145
+ browser = nil
146
+ end
147
+
148
+ end # end setup
149
+
150
+ # Close all browsers and write the result of the test to the results CSV
151
+ def teardown
152
+
153
+ begin
154
+ # Get end time
155
+ @test_end_time = Time.now
156
+ elapsed_time = (@test_end_time - @test_start_time).to_s
157
+ elapsed_time_in_minutes = (elapsed_time.to_i/60.0).to_s
158
+
159
+ test_name = self.to_s.split("(")[0] # self.to_s gives output like test_ABC5_01(TC_ABC5_01)
160
+
161
+ puts "Test has now finished; #{test_name} : #{passed?}"
162
+
163
+ if WRITE_RESULTS
164
+ puts "Will now write results to #{RedSkyConfig::RESULTS_BASE_DIR}"
165
+
166
+ notes = ""
167
+ success_text = passed? ? RedSkyConfig::PASSED : RedSkyConfig::FAILED
168
+
169
+ unless passed?
170
+ begin
171
+ if RedSkyConfig::MAKE_ERROR_SCREENSHOTS
172
+ puts "Now taking error screenshots"
173
+ dir_2 = RedSkyConfig::ERROR_SCREENSHOT_LOCATION
174
+ Dir.mkdir(dir_2) unless File.exists?(dir_2)
175
+ $browsers.each do |browser|
176
+ browser.screenshot.save(RedSkyConfig::ERROR_SCREENSHOT_LOCATION + "/#{test_name}_Time_#{@test_end_time.strftime("%H-%M-%S")}_Browser_#{$browsers.index(browser)}.png")
177
+ end
178
+ end
179
+ rescue
180
+ puts "Failed to make screenshot"
181
+ end
182
+ notes = @failure_notes
183
+ puts "Notes : #{notes}"
184
+ end # end unless passed?
185
+
186
+
187
+ # Write to the results file
188
+ begin
189
+ File.open(RedSkyConfig::RESULTS_CSV, "a") do |f|
190
+ row = [@test_file_dir, test_name, success_text, @test_start_time.strftime("%Y-%m-%d %H:%M:%S"), @test_end_time.strftime("%Y-%m-%d %H:%M:%S"), elapsed_time, elapsed_time_in_minutes, notes]
191
+ f.puts row.join(",")
192
+ puts "Result for test #{test_name} written"
193
+ end
194
+ rescue
195
+ puts "Had to rescue from writing results to file #{RedSkyConfig::RESULTS_CSV}"
196
+ end
197
+ end # end if WRITE_RESULTS
198
+
199
+ close_all_browsers
200
+
201
+ rescue Timeout::Error => t_error
202
+ puts "Timeout::Error :"
203
+ puts t_error
204
+ puts "Backtrace :"
205
+ puts t_error.backtrace
206
+ rescue Exception => error
207
+ puts "Error :"
208
+ puts error
209
+ puts "Backtrace :"
210
+ puts error.backtrace
211
+ end # end begin
212
+ end
213
+
214
+
215
+
216
+ end
217
+
218
+