taft 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bd9ae23e1324c24c5a99e25a21858ea93ade0f8f1993379501fdfaf76c67ea19
4
+ data.tar.gz: 5efce5a842f8a21f3b9c75a3a8edce0211aab23ac006f683fb7a562f1193ab31
5
+ SHA512:
6
+ metadata.gz: b4cc3d8926584f3b14c60f99475c85c5ecdb9265a1d2258c4b9e827037b8bdb25f640ab944fd309bfbb7c40f84da3c4a9237424ce8e390f540b324b18f07c37b
7
+ data.tar.gz: cf13e673c7f5d6abb4594e42ab55006a3adad34492b3b7bae2f9e9e1bae6f1be702c97e446e6f47820de837fcfa803bff83cf4c4c974b245f8e72879bdeac6b1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Richard Morrisby
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,17 @@
1
+ ### Test Automation Framework Template
2
+
3
+ This gem will deploy/install a skeleton code framework for the automated testing of applications with APIs and/or web-UIs.
4
+
5
+ Languages : Ruby
6
+
7
+ ## How to use
8
+
9
+ Command line : `ruby -e "require 'taft'; Taft.install"`
10
+
11
+
12
+
13
+
14
+ ## TODO
15
+
16
+ * More languages : Java
17
+ * Ruby installation will also install some gems (bundled within TAFT)
@@ -0,0 +1,51 @@
1
+ # Simple build script
2
+ # Deletes the existing gem file (if present)
3
+ # Uninstalls the gem
4
+ # Builds the gem
5
+ # Installs the new gem
6
+
7
+ # Note : when calling system (or backticks, etc.) th enew process starts at the system default, not the current working directory.
8
+ # Therefore we need to use a syntax of : system "cd #{gem_dir} && #{i_cmd}"
9
+
10
+ # Run from this directory!
11
+
12
+ gem_dir = Dir.getwd
13
+
14
+ # Delete existing .gem files in the dir
15
+
16
+ gemfiles = Dir.entries(gem_dir).collect {|q| q if q =~ /.gem$/}.compact
17
+
18
+ gemfiles.each do |q|
19
+ File.delete q
20
+ puts "Deleted #{q}"
21
+ end
22
+
23
+ gemfiles = Dir.entries(gem_dir).collect {|q| q if q =~ /.gem$/}.compact
24
+ raise "Gem has not been deleted" unless gemfiles.size == 0
25
+
26
+ # Uninstall, build, install
27
+ gemspecs = Dir.entries(gem_dir).collect {|q| q if q =~ /.gemspec$/}.compact
28
+
29
+ raise "Did not find a .gemspec in #{gem_dir}" if gemspecs.size < 1
30
+ raise "Found more than one .gemspec in #{gem_dir}" if gemspecs.size > 1
31
+
32
+ gemspec = gemspecs[0]
33
+
34
+ gemname = File.basename(gemspec, File.extname(gemspec))
35
+
36
+ u_cmd = "gem uninstall #{gemname}"
37
+ system u_cmd
38
+
39
+ b_cmd = "gem build #{gemspec}"
40
+ system "cd #{gem_dir} && #{b_cmd}"
41
+
42
+ gemfiles = Dir.entries(gem_dir).collect {|q| q if q =~ /.gem$/}.compact
43
+ raise "Gem was not built" unless gemfiles.size == 1
44
+
45
+ gemfile = gemfiles[0]
46
+ raise "Gem file is not for the expected gem, expected a #{gemname} gem but found #{gemfile}" unless gemfile =~ /^#{gemname}/
47
+
48
+ i_cmd = "gem install #{gemfile}"
49
+ system "cd #{gem_dir} && #{i_cmd}"
50
+
51
+ puts "Gem #{gemname} built & installed"
@@ -0,0 +1,286 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require 'more_ruby'
4
+
5
+ def pd(s)
6
+ puts s if $TAFT_DEBUGGING
7
+ end
8
+
9
+ class Taft
10
+ TEMPLATE_PROJECT_NAME_REGEX = /(zznamezz)/ # e.g. redsky if one word, red_sky if two # regex to use when matching a template file name
11
+ TEMPLATE_PROJECT_NAME_UPPERCASE_REGEX = /(ZZnamezz)/ # e.g. Redsky if one word, RedSky if two # regex to use when matching a template file name
12
+ TEMPLATE_PROJECT_ABBREV_REGEX = /(xxabbrevxx)/ # e.g. bs # regex to use when matching a template file name
13
+ TEMPLATE_PROJECT_ABBREV_UPPERCASE_REGEX = /(xxabbrevupperxx)/i # e.g. BS # regex to use when matching some template text
14
+ TEMPLATE_PROJECT_RAW_NAME_REGEX = /(yyrawnameyy)/i # e.g. RED SKY # regex to use when matching some template text
15
+
16
+ NAMES_AND_ABBREVS_REGEXES = [TEMPLATE_PROJECT_ABBREV_REGEX, TEMPLATE_PROJECT_ABBREV_UPPERCASE_REGEX, TEMPLATE_PROJECT_NAME_REGEX, TEMPLATE_PROJECT_NAME_UPPERCASE_REGEX]
17
+ TEMPLATE_GEM_NAME_REGEX = /-\d+.\d+.\d+.gem/
18
+
19
+ LANGUAGES = [:ruby]#, :java] # Java not yet supported
20
+
21
+ @project_name_part = nil
22
+ @project_name_uppercase_part = nil
23
+ @project_abbrev_part = nil
24
+ @project_abbrev_uppercase_part = nil
25
+
26
+ def self.install_ruby(debugging = false, dest = "", overwrite_ok = false, project_name = "", project_abbrev = "")
27
+ install(:ruby, debugging, dest, overwrite_ok, project_name, project_abbrev)
28
+ end
29
+
30
+ def self.install_java(debugging = false, dest = "", overwrite_ok = false, project_name = "", project_abbrev = "")
31
+ install(:java, debugging, dest, overwrite_ok, project_name, project_abbrev)
32
+ end
33
+
34
+ def self.install(lang = nil, debugging = false, dest = "", overwrite_ok = false, project_name = "", project_abbrev = "")
35
+ $TAFT_DEBUGGING = true if debugging
36
+
37
+ unless dest.empty?
38
+ puts "Taft.install has been called with the following parameters :"
39
+ puts "Language : #{lang}"
40
+ puts "Project name : #{project_name}"
41
+ puts "Project abbreviation : #{project_abbrev}"
42
+ puts "Destination folder (relative to #{Dir.getwd} if a relative path) : #{dest}"
43
+ puts "Press Enter to continue..."
44
+ gets
45
+ end
46
+
47
+ base_wd = Dir.getwd
48
+ dest_base_folder = ""
49
+
50
+ if lang == nil
51
+ puts "\nPlease enter the language of this project : #{LANGUAGES.join(", ")}"
52
+ lang = gets.chomp.downcase.to_sym
53
+ raise "TAFT cannot install a new project in that language" unless LANGUAGES.include?(lang)
54
+ end
55
+
56
+ if dest.empty?
57
+ puts "\nPlease enter the path of the base folder that TAFT should create, up to and including the name of the base folder"
58
+ puts "TAFT will create this folder if it does not exist"
59
+ puts "If a relative path is entered, it will be taken as being relative to path : #{Dir.getwd}"
60
+ dest = gets.chomp
61
+ raise "The base folder path entered was empty" if dest.empty?
62
+
63
+ puts "Does this folder already exist? Entering Y will grant TAFT permission to write into that folder, overwriting any files with matching names that are aready present."
64
+ folder_exists = gets.chomp
65
+
66
+ overwrite_ok = (folder_exists == "Y")
67
+ end
68
+ # if dest has been specified in the call, then overwrite_ok has as well
69
+
70
+ case lang
71
+ when :ruby
72
+ raw_file_path = "#{File.expand_path(File.dirname(__FILE__))}/taft_files"
73
+ # TODO determine list of gems & put in folder
74
+ # Might be better to output a list of gem install commands instead? What if people are using earlier/later versions of Ruby?
75
+ # bundled_gem_path = "#{File.expand_path(File.dirname(__FILE__))}/bundled_gems"
76
+ # install_gems(bundled_gem_path)
77
+ when :java
78
+ raw_file_path = "#{File.expand_path(File.dirname(__FILE__))}/java_taft_files"
79
+ end
80
+
81
+ # TODO does this handle dests like "~/foo" ?
82
+ if (Pathname.new dest).absolute?
83
+ dest_base_folder = dest
84
+ else
85
+ dest_base_folder = File.join(Dir.getwd, dest)
86
+ end
87
+ dest_base_folder = File.expand_path(dest_base_folder)
88
+ puts "TAFT will install to #{dest_base_folder}"
89
+
90
+ raise "Folder #{dest_base_folder} already exists, and you did not grant TAFT permission to write into the folder" if Dir.exists?(dest_base_folder) && !overwrite_ok
91
+
92
+ # Create the base folder
93
+ begin
94
+ Dir.mkdir(dest_base_folder) unless Dir.exists?(dest_base_folder)
95
+ ensure
96
+ raise "The base folder '#{dest_base_folder}' did not exist" if folder_exists && !Dir.exists?(dest_base_folder)
97
+ raise "The base folder '#{dest_base_folder}' could not be created" unless Dir.exists?(dest_base_folder)
98
+ end
99
+
100
+ # Copy the raw files into the base folder, preserving the structure
101
+ FileUtils.copy_entry(raw_file_path, dest_base_folder, false, false, true)
102
+
103
+ puts "\nFiles have been copied"
104
+ if project_name.empty?
105
+ puts "\nPlease enter the name of your project (e.g. RED SKY) :"
106
+ project_name = gets.chomp
107
+ raise "The project name entered was empty" if project_name.empty?
108
+ end
109
+
110
+ if project_abbrev.empty?
111
+ puts "\nPlease enter the abbreviation of your project (e.g. RS) :"
112
+ project_abbrev = gets.chomp
113
+ raise "The project abbreviation entered was empty" if project_abbrev.empty?
114
+ end
115
+
116
+
117
+ @project_name_part = project_name.gsub(/[\s-]+/, "_").downcase # TODO use .snakecase ?
118
+ @project_name_uppercase_part = @project_name_part.upcase
119
+ @project_abbrev_part = project_abbrev.gsub(/[\s-]+/, "_").delete("_").downcase # TODO use .snakecase ?
120
+ @project_abbrev_uppercase_part = @project_abbrev_part.upcase
121
+
122
+ # Now sweep over the copied files, adjusting the names accordingly
123
+ Taft.adjust_file_names(dest_base_folder, project_name, project_abbrev)
124
+
125
+ # Now sweep over the copied files, adjusting the contents accordingly
126
+ Taft.adjust_file_contents(dest_base_folder, project_name, project_abbrev)
127
+
128
+ puts "\nFiles have been tailored to your project."
129
+
130
+ puts "\nTAFT has installed a tailored copy of the #{lang.capitalize} Automation Framework to #{dest_base_folder}"
131
+ puts "Installation complete."
132
+ end
133
+
134
+ # Looks at the names of each file & folder within dest_base_folder and renames them, applying the project_name or project_abbrev as appropriate
135
+ def self.adjust_file_names(dest_base_folder, project_name, project_abbrev)
136
+ pd "Now in #{__method__}; #{dest_base_folder}; #{project_name}; #{project_abbrev}"
137
+ project_file_name_part = project_name.gsub(/[\s-]+/, "_").downcase # TODO use .snakecase ?
138
+ project_file_abbrev_part = project_abbrev.gsub(/[\s-]+/, "_").delete("_").downcase # TODO use .snakecase ?
139
+
140
+ pd "project_file_name_part : #{project_file_name_part}" # snakecase
141
+ pd "project_file_abbrev_part : #{project_file_abbrev_part}" # lowercase
142
+ Dir.chdir(dest_base_folder) do
143
+ entries = Dir.entries(dest_base_folder)
144
+ entries.delete(".")
145
+ entries.delete("..")
146
+ entries.each do |f|
147
+ f = File.expand_path(f)
148
+ pd "Now looking at #{f}; is dir? #{Dir.exists?(f)}"
149
+ if Dir.exists?(f) # if this is a dir, call recursively
150
+ Taft.adjust_file_names(f, project_name, project_abbrev)
151
+ end
152
+
153
+ # After processing the contents of the directory, rename it
154
+ # Or if the entry was actually a file, rename it
155
+ basename = File.basename(f, ".*")
156
+ NAMES_AND_ABBREVS_REGEXES.each do |regex|
157
+ if basename =~ regex
158
+ ext = File.extname(f)
159
+ dir = File.split(f)[0]
160
+
161
+ # For the given regex, work out what the replacement text should be
162
+ case regex.inspect
163
+ when TEMPLATE_PROJECT_NAME_REGEX
164
+ replacement = @project_name_part
165
+ when TEMPLATE_PROJECT_NAME_UPPERCASE_REGEX
166
+ replacement = @project_name_uppercase_part
167
+ when TEMPLATE_PROJECT_ABBREV_REGEX
168
+ replacement = @project_abbrev_part
169
+ when TEMPLATE_PROJECT_ABBREV_UPPERCASE_REGEX
170
+ replacement = @project_abbrev_uppercase_part
171
+ end
172
+
173
+ new_f = basename.gsub(regex, replacement)
174
+ new_f += ext # must add the extension back on
175
+ new_f = File.join(dir, new_f) # this is the full path
176
+ pd "Will rename #{f}\n to #{new_f}"
177
+ Taft.delete_file(new_f)
178
+ File.rename(f, new_f)
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+
186
+ # Looks at the contents of each file within dest_base_folder and edits their contents, applying the project_name or project_abbrev as appropriate
187
+ def self.adjust_file_contents(dest_base_folder, project_name, project_abbrev)
188
+ pd "Now in #{__method__}; #{dest_base_folder}; #{project_name}; #{project_abbrev}"
189
+ raw_name = project_name # should have been entered in form like RED SKY
190
+ project_class_name_part = project_name.gsub(/[\s-]+/, "_").downcase # TODO use .snakecase ?
191
+ project_class_name_uppercase_part = project_name.pascalcase
192
+ project_class_abbrev_part = project_abbrev.gsub(/[\s-]+/, "_").delete("_").downcase # TODO use .snakecase ?
193
+
194
+ pd "project_class_name_part : #{project_class_name_part}" # snakecase
195
+ pd "project_class_name_uppercase_part : #{project_class_name_uppercase_part}" # pascalcase
196
+ pd "project_class_abbrev_part : #{project_class_abbrev_part}" # lowercase
197
+
198
+ Dir.chdir(dest_base_folder) do
199
+ entries = Dir.entries(dest_base_folder)
200
+ entries.delete(".")
201
+ entries.delete("..")
202
+ entries.each do |f|
203
+ f = File.expand_path(f)
204
+ pd "Now looking at #{f}; is dir? #{Dir.exists?(f)}"
205
+ if Dir.exists?(f) # if this is a dir, call recursively
206
+ Taft.adjust_file_contents(f, project_name, project_abbrev)
207
+ next
208
+ end
209
+
210
+ lines = []
211
+ File.open(f, "r") do |file_obj|
212
+ lines = file_obj.readlines
213
+ end
214
+
215
+
216
+ # Each line may match more than one regex
217
+ # Hence each line should be passed through all of the regexes, not stopping after the first one it matches
218
+ # i.e. separate if-ends, not one big case-when or if-elsif routine
219
+ lines.each do |line|
220
+ if line =~ TEMPLATE_PROJECT_NAME_REGEX
221
+ line.gsub!(TEMPLATE_PROJECT_NAME_REGEX, project_class_name_part)
222
+ end
223
+ if line =~ TEMPLATE_PROJECT_NAME_UPPERCASE_REGEX
224
+ line.gsub!(TEMPLATE_PROJECT_NAME_UPPERCASE_REGEX, project_class_name_uppercase_part)
225
+ end
226
+ if line =~ TEMPLATE_PROJECT_ABBREV_REGEX
227
+ line.gsub!(TEMPLATE_PROJECT_ABBREV_REGEX, project_class_abbrev_part)
228
+ end
229
+ if line =~ TEMPLATE_PROJECT_ABBREV_UPPERCASE_REGEX
230
+ line.gsub!(TEMPLATE_PROJECT_ABBREV_UPPERCASE_REGEX, project_class_abbrev_part.upcase)
231
+ end
232
+ if line =~ TEMPLATE_PROJECT_RAW_NAME_REGEX
233
+ line.gsub!(TEMPLATE_PROJECT_RAW_NAME_REGEX, raw_name)
234
+ end
235
+ end
236
+
237
+ File.open(f, "w") do |file_obj|
238
+ file_obj.puts lines
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ def self.delete_file(abs_file_path)
245
+ if Dir.exists?(abs_file_path)
246
+ FileUtils.remove_dir(abs_file_path)
247
+ elsif File.exists?(abs_file_path)
248
+ File.delete(abs_file_path)
249
+ end
250
+ end
251
+
252
+ def self.install_gems(bundled_gem_path)
253
+ puts "\nWill first install all gems bundled in with the TAFT gem."
254
+
255
+ gem_list = Dir.entries(bundled_gem_path)
256
+ gem_list.delete(".")
257
+ gem_list.delete("..")
258
+ gems_to_install = []
259
+ gem_list.each do |gem_name|
260
+ # For each gem, try to require it. Only install those that couldn't be required.
261
+ begin
262
+ gem_base_name = gem_name.gsub(TEMPLATE_GEM_NAME_REGEX, "")
263
+ require gem_base_name
264
+ rescue LoadError
265
+ puts "#{gem_base_name} could not be required; will install #{gem_name}"
266
+ gems_to_install << gem_name
267
+ end
268
+ end
269
+
270
+ if gems_to_install.empty?
271
+ puts "All required gems are already installed"
272
+ else
273
+ puts "Will install the following gems :"
274
+ gems_to_install.each {|gem_name| puts gem_name }
275
+
276
+ Dir.chdir(bundled_gem_path) # set this to be the working directory while installing the gems
277
+ gems_to_install.each do |gem_name|
278
+ puts "\nNow installing #{gem_name}..."
279
+ system("gem install #{gem_name}")
280
+ puts "Gem installed."
281
+ end
282
+ Dir.chdir(base_wd) # reset the working directory
283
+ end
284
+ end
285
+
286
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+
3
+ # Add a require line for every file within framework/zznamezz
4
+
5
+ require "zznamezz/api_helpers/general"
6
+ require "zznamezz/api_helpers/rest"
7
+
8
+ require "zznamezz/ui_helpers/ui_general"
@@ -0,0 +1,140 @@
1
+ require "test/unit/assertions" # required for the assert_ methods
2
+
3
+ require "json-schema"
4
+ require "avro"
5
+ require "csv"
6
+ require "net/ssh"
7
+ require "net/sftp"
8
+
9
+
10
+ class XXabbrevupperxxHelper
11
+ include Test::Unit::Assertions
12
+ include FrameworkHelpers
13
+
14
+ # initialize and method_missing are necessary for for allowing this class to access outside methods
15
+ attr_accessor :xxabbrevxx_context
16
+ def initialize(xxabbrevxx_context)
17
+ @xxabbrevxx_context = xxabbrevxx_context
18
+ end
19
+
20
+ def method_missing(meth, *args)
21
+ case meth.to_s
22
+ when /^xxabbrevxx/
23
+ @xxabbrevxx_context.send(meth, *args)
24
+ else
25
+ super
26
+ end
27
+ end
28
+
29
+ # Reads in a file of CSV test data, e.g for use in data-driven tests
30
+ def read_csv_test_data(filename)
31
+ path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../../tests/data", filename)
32
+ read_csv_data_from_file(path)
33
+ end
34
+
35
+ # Reads in a CSV
36
+ def read_csv_data_from_file(full_file_path)
37
+ data = []
38
+ CSV.open(full_file_path, "r") do |csv|
39
+ data = csv.readlines
40
+ end
41
+ data
42
+ end
43
+
44
+ # Reads in a JSON schema
45
+ def read_json_schema(schema_filename)
46
+ path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../../tests/data", schema_filename)
47
+ data = []
48
+ File.open(path, "r") do |f|
49
+ data = f.readlines
50
+ end
51
+ schema = JSON.parse(data.chomp) # there may be trailing whitespace
52
+ schema
53
+ end
54
+
55
+ # Reads in a serialised AVRO file
56
+ # Returns an array of the deserialised data rows
57
+ def read_avro_file(filename)
58
+ lines = []
59
+ File.open(path, "rb") do |f|
60
+ reader = Avro::IO::DatumReader.new
61
+ dr = Avro::DataFile::Reader.new(f, reader)
62
+ dr.each do |record|
63
+ lines << record
64
+ end
65
+ end
66
+ lines
67
+ end
68
+
69
+ # Validates the supplied hash against the JSON schema
70
+ def validate_hash_against_json_schema(hash, schema_filename)
71
+ raise "Must supply a hash to #{__method__}" unless hash.class == Hash
72
+
73
+ schema = read_json_schema(schema_filename)
74
+ errors = JSON::Validator.fully_validate(schema, hash)
75
+ errors
76
+ end
77
+
78
+ # Calls the build_number REST method
79
+ # This is an example of how to use get_rest_client
80
+ def get_version_number_from_api(cert_symbol = :regular)
81
+ client = get_rest_client(:build_number, cert_symbol)
82
+ json = client.get # {"message":"1.8.0"}
83
+ parsed = JSON.parse(json)
84
+ parsed["message"]
85
+ end
86
+
87
+ # Forms a .tar.gz archive from the specified source file
88
+ # Creates the file in the working directory
89
+ # Creates the .tar.gz via a call to system
90
+ def create_tar_gz_file(gz_base_file_name, source_file)
91
+ gz_name = "#{gz_base_file_name}.tar.gz"
92
+ cmd = "tar -czf #{gz_name} #{source_file}"
93
+ system(cmd)
94
+ gz_name
95
+ end
96
+
97
+ # Renames the specified file on the Linux server
98
+ # Needs the full path
99
+ def rename_linux_file(old_file, new_file, cert_symbol = :regular)
100
+ # Derive the FTP host & path from the URL in config
101
+ host = ZZnamezzConfig::SERVER[:zznamezz_url].split("//")[1].split(":")[0]
102
+ host_short_form = host.split(".")[0]
103
+ user = get_user_id(cert_symbol)
104
+ pass = get_user_cert_pw(cert_symbol)
105
+
106
+ Net::SFTP.start(host, user, :password => pass) do |sftp|
107
+ puts "Renaming file : #{old_file} -> #{new_file}"
108
+ sftp.rename(old_file, new_file)
109
+ end
110
+ end
111
+
112
+ # Sets 777 permissions to the Linux server file
113
+ # Need the file name & dir
114
+ def chmod_linux_file(host, user, pass, path, file_name)
115
+ Net::SSH.start(host, user, :password => pass) do |ssh|
116
+ ssh.exec!("cd #{path}; chmod 777 #{file_name}")
117
+ end
118
+ end
119
+
120
+ # Executes the supplied curl command on the server
121
+ def submit_curl_command(cmd, cert_symbol = :regular)
122
+ # Derive the FTP host & path from the URL in config
123
+ host = ZZnamezzConfig::SERVER[:zznamezz_url].split("//")[1].split(":")[0]
124
+ host_short_form = host.split(".")[0]
125
+ user = get_user_id(cert_symbol)
126
+ pass = get_user_cert_pw(cert_symbol)
127
+
128
+ output = ""
129
+ Net::SSH.start(host, user, :password => pass) do |ssh|
130
+ output = ssh.exec!(cmd)
131
+ end
132
+
133
+ # We expect a JSON response from the server
134
+ # The recorded output will contain this inside curl's own SDTOUT, so we need to extract the JSON
135
+ output = output[output.index("{") .. output.index("}")]
136
+ JSON.parse(output)
137
+ end
138
+
139
+
140
+ end
@@ -0,0 +1,249 @@
1
+ require "rest_client"
2
+ require "uri"
3
+ require "openssl"
4
+ require "json"
5
+
6
+ # File contains methods conductive to the execution of tests and scripts that call REST interfaces
7
+
8
+
9
+ class XXabbrevupperxxHelper
10
+
11
+ # Returns a RestClient::Resource object pointing to the URL of the requested service
12
+ def get_rest_client(service, cert_symbol = :regular, parameter_array_or_hash = [], base_url = ZZnamezzConfig::SERVER[:zznamezz_url], version = nil, timeout = 150)
13
+
14
+ separator = "/"
15
+ api_version_string = separator + ZZnamezzConfig::API_VERSION.to_s # as the version parameter can be entirely absent, let's build the separator into the term
16
+ api_version_string = "" if ZZnamezzConfig::API_VERSION == :none # special case
17
+
18
+ api_version_string = separator + version if version # override always wins
19
+
20
+ parameter_array_or_hash = [parameter_array_or_hash] if parameter_array_or_hash.class != Array && parameter_array_or_hash.class != Hash # convert to array if a non-array/hash was supplied
21
+
22
+ # If common headers are needed
23
+ # headers = {"foo" => bar}
24
+
25
+ # Build up the path-string, then append it to the base URL
26
+ s = "" # initialise before manipulating it
27
+
28
+ if service.class == String
29
+ s = service
30
+ else
31
+ case service
32
+ when :options
33
+ s = "options#{api_version_string}"
34
+ s += "/#{parameter_array_or_hash[0]}"
35
+ when :build_number
36
+ s = "query/info#{api_version_string}/buildnumber"
37
+ else
38
+ raise "Unknown service #{service} supplied to #{__method__}"
39
+ end
40
+ end
41
+
42
+ encoded = encode_uri(s).to_s # Generates a URI::Generic object; we want a string
43
+ url = base_url + encoded
44
+
45
+ puts url
46
+
47
+ #######################################################
48
+ # Get certificate and other parameters needed for valid credentials
49
+ #######################################################
50
+
51
+ OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] = "SSLv3" # this may or may not be needed
52
+
53
+ cert_path = File.expand_path(ZZnamezzConfig::CERTIFICATE_DIR) # this must be an absolute filepath
54
+ cert_extension = get_user_cert_ext(cert_symbol).to_s
55
+
56
+ cert_name = get_user_p12_cert_name(cert_symbol)
57
+ cert_pw = get_user_cert_pw(cert_symbol)
58
+
59
+ # ca_file = ZZnamezzConfig::CA_CERTIFICATE_FILE # needed for VERIFY_PEER mode # VERIFY_PEER mode currently disabled
60
+
61
+ if cert_extension.to_sym == :pem
62
+ # If PEM, the credentials are in two parts - the certs.pem file and the key.pem file
63
+ # Need to read in the two separate files & construct OpenSSL::X509::Certificate & OpenSSL::PKey::RSA objects
64
+ cert_key_name = get_user_pem_cert_key_name(cert_symbol)
65
+ cert_key_pw = get_user_cert_key_pw(cert_symbol)
66
+ pem = File.read(File.join(cert_path, cert_name))
67
+ key_pem = File.read(File.join(cert_path, cert_key_name))
68
+
69
+ cert = OpenSSL::X509::Certificate.new(pem)
70
+
71
+ begin
72
+ key = OpenSSL::PKey::RSA.new(key_pem, cert_key_pw)
73
+ rescue
74
+ raise "Could not form OpenSSL::PKey::RSA object for the corresponding key.pem file. Does it have the right password?"
75
+ end
76
+ return RestClient::Resource.new(url, {:ssl_client_cert => cert, :ssl_client_key => key, :verify_ssl => OpenSSL::SSL::VERIFY_NONE, :timeout => timeout})
77
+ else
78
+ # If P12 or PFX, only need to construct the one object - the certificate and key are both stored within it
79
+ begin
80
+ p12 = OpenSSL::PKCS12.new(File.read(File.join(cert_path, cert_name), :binmode => true), cert_pw)
81
+ rescue OpenSSL::PKCS12::PKCS12Error => e
82
+ if e.to_s.include?("mac verify failure")
83
+ raise "Could not create PKCS12 object from certificate #{cert_name}; please specify a password for the certificate"
84
+ else
85
+ raise e
86
+ end
87
+ end
88
+
89
+ # Use if performing SSL Peer verification - needs a ca certificate
90
+ return RestClient::Resource.new(url, {:ssl_client_cert => p12.certificate, :ssl_client_key => p12.key, :ssl_ca_file => ca_file, :verify_ssl => OpenSSL::SSL::VERIFY_PEER, :headers => headers, :timeout => timeout})
91
+
92
+ # Use if not performing SSL Peer verification - does not need a ca certificate
93
+ return RestClient::Resource.new(url, {:ssl_client_cert => p12.certificate, :ssl_client_key => p12.key, :verify_ssl => OpenSSL::SSL::VERIFY_NONE, :timeout => timeout})
94
+ end
95
+
96
+ end
97
+
98
+ # Method to encode the URI
99
+ # Takes a string or an array of path fragments. If an array, the contents will be joined using / characters
100
+ def encode_uri(uri)
101
+ uri = uri.join("/") if uri.class == Array
102
+ additional_encoding(URI.parse(URI.encode(uri)).to_s)
103
+ end
104
+
105
+
106
+ # Method to perform additional encoding
107
+ # URI.encode does not convert the following chars: : +
108
+ def additional_encoding(s)
109
+ encoding_hash = {":" => "%3A", "+" => "%2B"}
110
+ encoding_hash.each_pair do |k, v|
111
+ s.gsub!(k, v)
112
+ end
113
+ s
114
+ end
115
+
116
+ # Converts a string or int representing the number of microseconds since the Time epoch (1970/01/01) into a DateTime object
117
+ def read_epoch_time(microseconds_since_epoch)
118
+ Time.at(microseconds_since_epoch.to_i/1000)
119
+ end
120
+
121
+ # Converts the body of the response object from JSON to Ruby, and sets the defaults for the main hash and all sub-hashes
122
+ def get_response_body(response)
123
+ raise "REST response was nil" if response == nil
124
+ raise "REST response had no attached body" if response.body == nil
125
+ begin
126
+ body = JSON.parse(response.body, {:max_nesting => 100})
127
+ set_all_defaults(body)
128
+ rescue JSON::ParserError => e
129
+ puts "rescued : ParserError"
130
+ puts e
131
+ body = response.body
132
+ end
133
+ body
134
+ end
135
+
136
+
137
+ # Converts the header of the response object from JSON to Ruby, and sets the defaults for the main hash and all sub-hashes
138
+ def get_response_header(response)
139
+ raise "REST response was nil" if response == nil
140
+ raise "REST response had no attached header" if response.headers == nil
141
+ begin
142
+ header = response.headers # already in Ruby Hash format
143
+ set_all_defaults(body)
144
+ rescue JSON::ParserError => e
145
+ puts "rescued : ParserError"
146
+ puts e
147
+ header = response.headers
148
+ end
149
+ header
150
+ end
151
+
152
+ # Takes a hash a recursively sets the default of the hash and all sub-hashes
153
+ def set_all_defaults(hash, default = nil)
154
+ return unless hash.class == Hash
155
+ hash.default = default
156
+ hash.each_pair do |k, v|
157
+ set_all_defaults(v) if v.class == Hash
158
+ if v.class == Array
159
+ v.each {|z| set_all_defaults(z) if z.class == Hash}
160
+ end
161
+ end
162
+ end
163
+
164
+ # Method to perform a POST request. Requires the RESTClient Resource client and a hash of the information to be sent in the POST body. This hash is converted to JSON for the POST.
165
+ # Optionally also takes an additional hash which contains desired headers for the POST request.
166
+ # Returns a RESTClient::Response object
167
+ def post_request(client, post_information_hash, additional_hash = nil)
168
+ new_hash = {:content_type => "application/json"}
169
+ additional_hash ||= {}
170
+ new_hash.merge!(additional_hash)
171
+
172
+ begin
173
+ client.post(JSON.generate(post_information_hash, {:max_nesting => 100}), new_hash)
174
+ rescue OpenSSL::SSL::SSLError => e
175
+ raise "SSLError occurred when calling REST service; #{e}"
176
+ rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
177
+ puts "RestClient::Exception hit when calling REST service"
178
+ puts e
179
+ puts e.response
180
+ return e.response
181
+ rescue => e
182
+ raise "Unexpected error occurred when calling REST service; #{e}"
183
+ end
184
+ end
185
+
186
+ # Method to perform a POST request that sends a file. Requires the RESTClient Resource client and a hash of the information to be sent in the POST body.
187
+ # Assumes that all file information (including the File object itself) is included in the supplied hash
188
+ # Optionally also takes an additional hash which contains desired headers for the POST request.
189
+ # Returns a RESTClient::Response object
190
+ def post_file_request(client, post_information_hash, additional_hash = nil)
191
+ new_hash = {}
192
+ additional_hash ||= {}
193
+ new_hash.merge!(additional_hash)
194
+
195
+ begin
196
+ client.post(post_information_hash, new_hash)
197
+ rescue OpenSSL::SSL::SSLError => e
198
+ raise "SSLError occurred when calling REST service; #{e}"
199
+ rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
200
+ puts "RestClient::Exception hit when calling REST service"
201
+ puts e
202
+ puts e.response
203
+ return e.response
204
+ rescue => e
205
+ raise "Unexpected error occurred when calling REST service; #{e}"
206
+ end
207
+ end
208
+
209
+
210
+ # Method to perform a PUT request. Requires the RESTClient Resource client and a hash of the information to be sent in the PUT body. This hash is converted to JSON for the PUT.
211
+ # Optionally also takes an additional hash which contains desired headers for the PUT request, e.g. {:content_type => "application/json"}
212
+ # Returns a RESTClient::Response object
213
+ def put_request(client, put_information_hash, additional_hash = nil)
214
+ new_hash = {:content_type => "application/json"}
215
+ additional_hash ||= {}
216
+ new_hash.merge!(additional_hash)
217
+
218
+ begin
219
+ client.put(JSON.generate(put_information_hash, {:max_nesting => 100}), new_hash)
220
+ rescue OpenSSL::SSL::SSLError => e
221
+ raise "SSLError occurred when calling REST service; #{e}"
222
+ rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
223
+ puts "RestClient::Exception hit when calling REST service"
224
+ puts e
225
+ puts e.response
226
+ return e.response
227
+ rescue => e
228
+ raise "Unexpected error occurred when calling REST service; #{e}"
229
+ end
230
+ end
231
+
232
+
233
+ # Method to perform a DELETE request. Requires the RESTClient Resource client.
234
+ # Returns a RESTClient::Response object
235
+ def delete_request(client)
236
+ begin
237
+ client.delete
238
+ rescue OpenSSL::SSL::SSLError => e
239
+ raise "SSLError occurred when calling REST service; #{e}"
240
+ rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
241
+ puts "RestClient::Exception hit when calling REST service"
242
+ puts e
243
+ puts e.response
244
+ return e.response
245
+ rescue => e
246
+ raise "Unexpected error occurred when calling REST service; #{e}"
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,16 @@
1
+
2
+ # This class holds parameters that may frequently change between test runs, e.g the test environment
3
+ class 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
+ RESULTS_CSV = "results.csv"
14
+
15
+ end
16
+
@@ -0,0 +1,22 @@
1
+ # Holds system configuration parameters
2
+
3
+ require_relative 'runtime_constants.rb'
4
+
5
+ class ZZnamezzConfig
6
+ include RuntimeConstants
7
+
8
+ CERTIFICATE_DIR = "certs"
9
+
10
+ API_VERSION = "latest"
11
+
12
+ SERVERS = {
13
+ :test_1 => {:zznamezz_url = "https://"},
14
+ :ref_1 => {:zznamezz_url = "https://"},
15
+ }
16
+
17
+ SERVER = SERVERS[$TEST_ENV]
18
+
19
+
20
+ PASSED = "Passed"
21
+ FAILED = "Failed"
22
+ end
@@ -0,0 +1,212 @@
1
+
2
+ # This file defines a module to be included in all test cases for the testing of yyrawnameyy.
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.dirname(__FILE__) + "/..")
9
+
10
+ gem 'test-unit'
11
+ require 'test/unit'
12
+ require 'tmpdir'
13
+ require 'time'
14
+ require 'fileutils'
15
+ require 'timeout'
16
+
17
+ # Config
18
+ require 'config/zznamezz_config'
19
+
20
+ # Helpers
21
+ require 'framework/zznamezz.rb'
22
+
23
+
24
+
25
+ STDOUT.sync = true
26
+
27
+ if ZZnamezzConfig::WRITE_CI_REPORTS
28
+ require 'ci/reporter/rake/test_unit_loader'
29
+
30
+ ENV["CI_REPORTS"] = $CI_REPORTS_PATH # supplied in invokation to test
31
+ puts "Will create XML reports in #{ENV["CI_REPORTS"]}"
32
+ end
33
+
34
+ module ZZnamezzTestCase
35
+
36
+ include ZZnamezz
37
+
38
+ attr_accessor :browser_has_been_opened
39
+
40
+ # optional field
41
+ # If the cause of a test's failure is already likely to be known, the contents of this variable
42
+ # will automatically be added to the test result's Notes field, to help with reporting.
43
+ # If there are multiple tests in a file, this variable needs to be set within each test
44
+ # method (if they have any relevent failure notes).
45
+ attr_accessor :failure_notes
46
+
47
+ # By default, unknown methods (e.g. xxabbrevupperxxPage names) are sent to the different contexts
48
+ # for resolution. This allows pages to be accessed as xxabbrevxxHomePage rather than
49
+ # @xxabbrevxx_context.xxabbrevxxHomePage
50
+ def method_missing(meth, *args)
51
+ case meth.to_s
52
+ when /^xxabbrevxx/
53
+ @xxabbrevxx_context.send(meth, *args)
54
+ # when /^some_other_app/
55
+ # @some_other_app_context.send(meth, *args)
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+
62
+ if $WRITE_RESULTS # supplied from invokation
63
+ WRITE_RESULTS = true
64
+ else
65
+ WRITE_RESULTS = false
66
+ end
67
+
68
+ # Close the current browser and log in again
69
+ def re_login
70
+ browser.close
71
+
72
+ new_browser_on_login_page
73
+ # Reinitialise the contexd and @help
74
+ reinitialisexxabbrevupperxxContext(browser)
75
+ end
76
+
77
+ # Connect to yyrawnameyy and reinitialise the context, etc.
78
+ def xxabbrevxx_login(url = ZZnamezzConfig::SERVER[:zznamezz_url])
79
+ puts url
80
+ new_browser_on_login_page(url)
81
+ reinitialisexxabbrevupperxxContext(browser)
82
+ end
83
+
84
+ # Reinitialise xxabbrevupperxx context only
85
+ def reinitialisexxabbrevupperxxContext(new_browser)
86
+ @xxabbrevxx_context = ZZnamezz::Context.new(new_browser)
87
+ @help = xxabbrevupperxxHelper.new(@xxabbrevxx_context)
88
+ end
89
+
90
+ # Return to the previous xxabbrevupperxx session
91
+ def return_to_xxabbrevxx
92
+ self.browser = @xxabbrevxx_context.browser
93
+ end
94
+
95
+ # Close the current browser
96
+ def close_browser
97
+ self.browser.close
98
+ end
99
+
100
+ def close(browser)
101
+ if browser.exists? && ((ZZnamezzConfig::CLOSE_BROWSER_AFTER_TEST && passed?) || ZZnamezzConfig::FORCE_CLOSE_BROWSER_AFTER_TEST)
102
+ browser.close
103
+ $browsers.delete_at($current_browser_position - 1) # array indexing
104
+ self.browser = $browsers[-1] # set browser to the last one that is still in the array
105
+ end
106
+ end
107
+
108
+ def close_all_browsers
109
+ if (ZZnamezzConfig::CLOSE_BROWSER_AFTER_TEST && passed?) || ZZnamezzConfig::FORCE_CLOSE_BROWSER_AFTER_TEST
110
+ until $browsers.empty?
111
+ self.browser = $browsers.shift
112
+ browser.close
113
+ end
114
+ end
115
+ end
116
+
117
+ # Ensure that every test (that wants one) has a browser that is already logged in to the system
118
+ def setup
119
+
120
+ Watir.always_locate = true # default is true; setting to false speeds up Watir to a degree
121
+
122
+ # Get start time for later output in results
123
+ @test_start_time = Time.now
124
+
125
+ # Get the directory that the specific test lives in, so that it can be included in the results file
126
+ @test_file_dir = @test_file.split(File::SEPARATOR)[-2]
127
+
128
+ # Select default certificate if none is configured
129
+ @certificate ||= :regular
130
+
131
+ @timeout = ZZnamezzConfig::CERTIFICATE_POPUP_TIMEOUT
132
+
133
+ # Open the browser & ensure page contenxt and helper are available
134
+ $browsers = [] # global array containing all browser objects
135
+ # $current_browser_position = nil # global variable to track the position in $browsers of the active browser # TODO used?
136
+ # When that browser is closed, we can ensure that the corresponding browser object is removed from the array
137
+ if @initialBrowser == :xxabbrevxx
138
+ xxabbrevxx_login
139
+ elsif (@initialBrowser == :none || @initialBrowser == nil)
140
+ browser = nil
141
+ reinitialisexxabbrevupperxxContext(browser)
142
+ end
143
+
144
+ end # end setup
145
+
146
+ # Close all browsers and write the result of the test to the results CSV
147
+ def teardown
148
+
149
+ begin
150
+ # Get end time
151
+ @test_end_time = Time.now
152
+ elapsed_time = (@test_end_time - @test_start_time).to_s
153
+ elapsed_time_in_minutes = (elapsed_time.to_i/60.0).to_s
154
+
155
+ test_name = self.to_s.split("(")[0] # self.to_s gives output like test_ABC5_01(TC_ABC5_01)
156
+
157
+ puts "Test has now finished; #{test_name} : #{passed?}"
158
+
159
+ if WRITE_RESULTS
160
+ puts "Will now write results to #{ZZnamezzConfig::RESULTS_BASE_DIR}"
161
+
162
+ notes = ""
163
+ success_text = passed? ? ZZnamezzConfig::PASSED : ZZnamezzConfig::FAILED
164
+
165
+ unless passed?
166
+ begin
167
+ if ZZnamezzConfig::MAKE_ERROR_SCREENSHOTS
168
+ puts "Now taking error screenshots"
169
+ dir_2 = ZZnamezzConfig::ERROR_SCREENSHOT_LOCATION
170
+ Dir.mkdir(dir_2) unless File.exists?(dir_2)
171
+ $browsers.each do |browser|
172
+ browser.screenshot.save(ZZnamezzConfig::ERROR_SCREENSHOT_LOCATION + "/#{test_name}_Time_#{@test_end_time.strftime("%H-%M-%S")}_Browser_#{$browsers.index(browser)}.png")
173
+ end
174
+ end
175
+ rescue
176
+ puts "Failed to make screenshot"
177
+ end
178
+ notes = @failure_notes
179
+ puts "Notes : #{notes}"
180
+ end # end unless passed?
181
+
182
+ close_all_browsers
183
+
184
+ # Write to the results file
185
+ begin
186
+ File.open(ZZnamezzConfig::RESULTS_CSV, "a") do |f|
187
+ 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]
188
+ f.puts row.join(",")
189
+ puts "Result for test #{test_name} written"
190
+ end
191
+ rescue
192
+ puts "Had to rescue from writing results to file #{ZZnamezzConfig::RESULTS_CSV}"
193
+ end
194
+ end # end if WRITE_RESULTS
195
+ rescue Timeout::Error => t_error
196
+ puts "Timeout::Error :"
197
+ puts t_error
198
+ puts "Backtrace :"
199
+ puts t_error.backtrace
200
+ rescue Exception => error
201
+ puts "Error :"
202
+ puts error
203
+ puts "Backtrace :"
204
+ puts error.backtrace
205
+ end # end begin
206
+ end
207
+
208
+
209
+
210
+ end
211
+
212
+
@@ -0,0 +1,112 @@
1
+ $LOAD_PATH.unshift("#{File.expand_path(File.dirname(__FILE__))}/../../lib")
2
+
3
+ require "zznamezz_test_case"
4
+
5
+ class TC_R001_01_AN_EXAMPLE_TEST < Test::Unit::TestCase
6
+ include ZZnamezzTestCase
7
+
8
+ def setup
9
+ # specify setup parameters
10
+ @certificate = :regular # this is the default user for this test
11
+ @initialBrowser = :none # if you want this test to navigate to your webapp automatically as part of setup, change this value to the value referring to your webapp
12
+
13
+ super # must call super so that the common setup method in ZZnamezzTestCase is called
14
+ end
15
+
16
+ def test_r001_01_an_example_test
17
+
18
+ ############################################################################################
19
+ # PURPOSE :
20
+ # Verify that <description of your test's intent>
21
+ #
22
+ # PRECONDITIONS :
23
+ # <list your preconditions>
24
+ ############################################################################################
25
+
26
+ filename = "data_for_example_test.csv" # file must be in the data/ directory
27
+ data = @help.read_csv_test_data(filename)
28
+ header = data.shift
29
+
30
+ # Step 1 :
31
+ # Send a request to the yyrawnameyy API Options method
32
+
33
+ random_row = data.random
34
+ search_term = random_row[0]
35
+ expected_result_count = random_row[1]
36
+
37
+ # This is too raw - it would be better to bundle these lines into a separate "search_options" method,
38
+ # with additional validation (e.g. to throw a clean error if the request failed)
39
+ @client = @help.get_rest_client(:options, @certificate, search_term)
40
+ json = client.get
41
+ response = JSON.pretty_unparse(json)
42
+
43
+ # Expected Result :
44
+ # The request has succeeded & returned the expected results
45
+
46
+ # This is quite brittle
47
+ # A better approach is to create a new class which would parse the response & convert
48
+ # it into a bespoke Object, so that the various values could be accessed in a better OO-fashion.
49
+ # E.g. response.number_of_results. The object could also have extra methods,
50
+ # e.g. response.check_results_are_valid, and so on.
51
+ assert_equal(expected_result_count, response["number_of_results"], "The search request did not return the expected number of results")
52
+
53
+
54
+ # Step 2 :
55
+ # Log in to yyrawnameyy
56
+
57
+ xxabbrevxx_login
58
+
59
+ # Expected Result :
60
+ # The yyrawnameyy homepage is displayed
61
+
62
+ assert(xxabbrevxxHomepage.displayed?, "The yyrawnameyy homepage is not displayed")
63
+
64
+
65
+ # Step 3 :
66
+ # Enter in a search term and click the Search button.
67
+
68
+ data.each do |row|
69
+ search_term = row[0]
70
+ expected_result_text = row[2]
71
+ puts "Will now search for '#{term}'; expect to see '#{expected_result_text}'"
72
+
73
+ xxabbrevxxHomepage.term = search_term
74
+ xxabbrevxxHomepage.click_search
75
+
76
+
77
+ # Expected Result :
78
+ # Results are displayed
79
+
80
+ assert(xxabbrevxxSearchResults.displayed?, "The yyrawnameyy search results page is not displayed")
81
+ assert_equal(expected_result_text, xxabbrevxxSearchResults.result, "The yyrawnameyy search results page did not display the expected result")
82
+
83
+
84
+ # Step 4 :
85
+ # Return to the previous page
86
+
87
+ browser.back
88
+
89
+
90
+
91
+ # Expected Result :
92
+ # The yyrawnameyy homepage is displayed
93
+
94
+ assert(xxabbrevxxHomepage.displayed?, "The yyrawnameyy homepage is not displayed")
95
+
96
+
97
+ # Step 5 :
98
+ # Repeat steps 3 and 4 for a few more search terms
99
+
100
+ # Actions performed in above steps
101
+
102
+
103
+ # Expected Result :
104
+ # Results are displayed for each term
105
+
106
+ # Assertions performed in above steps
107
+
108
+ end # end .each
109
+
110
+ end
111
+
112
+ end
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'taft'
3
+ s.version = '0.1.0'
4
+ s.licenses = ['MIT']
5
+ s.summary = "Test Automation Framework Template"
6
+ s.description = "This gem will deploy/install a skeleton code framework for the automated testing of applications with APIs and/or web-UIs"
7
+ s.authors = ["Richard Morrisby"]
8
+ s.email = 'rmorrisby@gmail.com'
9
+ s.files = ["lib/taft.rb"]
10
+ s.homepage = 'https://rubygems.org/gems/taft'
11
+ s.required_ruby_version = '>=1.9'
12
+ s.files = Dir['**/**']
13
+ s.test_files = Dir["test/test*.rb"]
14
+ end
@@ -0,0 +1,10 @@
1
+ require "test/unit"
2
+ require_relative "../lib/ex"
3
+
4
+ class TestEx < Test::Unit::TestCase
5
+
6
+ def test_ex
7
+
8
+ end
9
+
10
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: taft
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Richard Morrisby
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This gem will deploy/install a skeleton code framework for the automated
14
+ testing of applications with APIs and/or web-UIs
15
+ email: rmorrisby@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENCE.txt
21
+ - README.md
22
+ - build.rb
23
+ - lib/taft.rb
24
+ - lib/taft_files/framework/zznamezz.rb
25
+ - lib/taft_files/framework/zznamezz/api_helpers/general.rb
26
+ - lib/taft_files/framework/zznamezz/api_helpers/rest.rb
27
+ - lib/taft_files/framework/zznamezz/ui_helpers/ui_general.rb
28
+ - lib/taft_files/lib/config/runtime_constants.rb
29
+ - lib/taft_files/lib/config/zznamezz_config.rb
30
+ - lib/taft_files/lib/zznamezz_test_case.rb
31
+ - lib/taft_files/tests/v1/tc_r001_01_an_example_test.rb
32
+ - taft.gemspec
33
+ - test/test_example.rb
34
+ homepage: https://rubygems.org/gems/taft
35
+ licenses:
36
+ - MIT
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '1.9'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubygems_version: 3.0.3
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Test Automation Framework Template
57
+ test_files:
58
+ - test/test_example.rb