friendly-cukes 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/DETAILED_DESCRIPTION.md +235 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +108 -0
- data/Rakefile +2 -0
- data/bin/build-extractor +69 -0
- data/bin/friendly-cukes +48 -0
- data/friendly-cukes.gemspec +41 -0
- data/lib/friendly/build_extractor.rb +647 -0
- data/lib/friendly/cukes.rb +29 -0
- data/lib/friendly/cukes/framework/Gemfile +16 -0
- data/lib/friendly/cukes/framework/Gemfile.lock +113 -0
- data/lib/friendly/cukes/framework/Rakefile.rb +19 -0
- data/lib/friendly/cukes/framework/config/config.yml +87 -0
- data/lib/friendly/cukes/framework/config/cucumber.yml +49 -0
- data/lib/friendly/cukes/framework/coverage/.last_run.json +5 -0
- data/lib/friendly/cukes/framework/coverage/.resultset.json +3519 -0
- data/lib/friendly/cukes/framework/coverage/.resultset.json.lock +0 -0
- data/lib/friendly/cukes/framework/coverage/rcov/assets/0.2.3/jquery-1.3.2.min.js +19 -0
- data/lib/friendly/cukes/framework/coverage/rcov/assets/0.2.3/jquery.tablesorter.min.js +15 -0
- data/lib/friendly/cukes/framework/coverage/rcov/assets/0.2.3/print.css +12 -0
- data/lib/friendly/cukes/framework/coverage/rcov/assets/0.2.3/rcov.js +42 -0
- data/lib/friendly/cukes/framework/coverage/rcov/assets/0.2.3/screen.css +270 -0
- data/lib/friendly/cukes/framework/coverage/rcov/index.html +392 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-app_init-app_driver_rb.html +98 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-app_utils-data_file_names_rb.html +65 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-app_utils-page_utils_rb.html +533 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-generic-create_log_rb.html +521 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-generic-custom_html_report_rb.html +2522 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-generic-datetime_library_rb.html +296 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-generic-file_library_rb.html +995 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-generic-performance_report_rb.html +1613 -0
- data/lib/friendly/cukes/framework/coverage/rcov/library-generic-read_from_yml_rb.html +944 -0
- data/lib/friendly/cukes/framework/coverage/rcov/object_repository-desktop-gem_search_rb.html +773 -0
- data/lib/friendly/cukes/framework/coverage/rcov/object_repository-desktop-google_search_rb.html +230 -0
- data/lib/friendly/cukes/framework/coverage/rcov/object_repository-mobile-mobile_google_search_rb.html +230 -0
- data/lib/friendly/cukes/framework/coverage/rcov/step_definitions-desktop-gem_search_rb.html +188 -0
- data/lib/friendly/cukes/framework/coverage/rcov/step_definitions-desktop-google_search_steps_rb.html +167 -0
- data/lib/friendly/cukes/framework/coverage/rcov/step_definitions-mobile-mobile_google_search_steps_rb.html +167 -0
- data/lib/friendly/cukes/framework/coverage/rcov/support-browser_settings_rb.html +851 -0
- data/lib/friendly/cukes/framework/coverage/rcov/support-env_rb.html +242 -0
- data/lib/friendly/cukes/framework/coverage/rcov/support-hooks_rb.html +878 -0
- data/lib/friendly/cukes/framework/coverage/rcov/support-html_formatter_rb.html +230 -0
- data/lib/friendly/cukes/framework/features/desktop/google_search/google_search.feature +19 -0
- data/lib/friendly/cukes/framework/features/desktop/rubygems_search/gem_name_tc_04.yml +2 -0
- data/lib/friendly/cukes/framework/features/desktop/rubygems_search/gem_search.feature +37 -0
- data/lib/friendly/cukes/framework/features/desktop/test_data/gem_name.yml +2 -0
- data/lib/friendly/cukes/framework/features/mobile/google_search/mobile_google_search.feature +19 -0
- data/lib/friendly/cukes/framework/library/app_init/app_init.rb +13 -0
- data/lib/friendly/cukes/framework/library/app_utils/data_file_names.rb +2 -0
- data/lib/friendly/cukes/framework/library/app_utils/page_utils.rb +157 -0
- data/lib/friendly/cukes/framework/library/generic/app_logo_1.png +0 -0
- data/lib/friendly/cukes/framework/library/generic/create_log.rb +154 -0
- data/lib/friendly/cukes/framework/library/generic/custom_html_report.rb +852 -0
- data/lib/friendly/cukes/framework/library/generic/datetime_library.rb +79 -0
- data/lib/friendly/cukes/framework/library/generic/file_library.rb +311 -0
- data/lib/friendly/cukes/framework/library/generic/performance_report.rb +518 -0
- data/lib/friendly/cukes/framework/library/generic/read_from_yml.rb +294 -0
- data/lib/friendly/cukes/framework/object_repository/desktop/desktop_web_object_repo.rb +50 -0
- data/lib/friendly/cukes/framework/object_repository/mobile/mobile_web_object_repo.rb +22 -0
- data/lib/friendly/cukes/framework/page_objects/desktop/gem_search.rb +213 -0
- data/lib/friendly/cukes/framework/page_objects/desktop/google_search.rb +53 -0
- data/lib/friendly/cukes/framework/page_objects/mobile/mobile_google_search.rb +53 -0
- data/lib/friendly/cukes/framework/step_definitions/desktop/gem_search.rb +43 -0
- data/lib/friendly/cukes/framework/step_definitions/desktop/google_search_steps.rb +36 -0
- data/lib/friendly/cukes/framework/step_definitions/mobile/mobile_google_search_steps.rb +36 -0
- data/lib/friendly/cukes/framework/support/browser_settings.rb +264 -0
- data/lib/friendly/cukes/framework/support/env.rb +65 -0
- data/lib/friendly/cukes/framework/support/hooks.rb +274 -0
- data/lib/friendly/cukes/framework/support/html_formatter.rb +57 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/app_env.log +15 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/custom_report/detailed_report/app_logo_1.png +0 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/custom_report/detailed_report/desktop_gem_search.html +647 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/custom_report/detailed_report/desktop_google_search.html +590 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/custom_report/report_home.html +593 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/desktop_rubygems_search.log +84 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/report_21_05_2015-11_04_54.html +472 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_33/report_21_05_2015-11_04_54.json +299 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_37/app_env.log +15 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_37/desktop_google_search.log +22 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_37/report_21_05_2015-11_03_49.html +472 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-11_03_37/report_21_05_2015-11_03_49.json +155 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-17_28_10/app_env.log +15 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-17_28_10/mobile_google_search.log +22 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-17_28_10/report_21_05_2015-17_29_26.html +472 -0
- data/lib/friendly/cukes/framework/test_result/test_report_21_05_2015-17_28_10/report_21_05_2015-17_29_26.json +143 -0
- data/lib/friendly/cukes/version.rb +61 -0
- metadata +309 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
*Name : DateTimeLibrary
|
|
3
|
+
*Description : module that define methods for all datetime related manipulations
|
|
4
|
+
*Author : Chandra sekaran
|
|
5
|
+
*Creation Date : 23/08/2014
|
|
6
|
+
*Updation Date :
|
|
7
|
+
=end
|
|
8
|
+
|
|
9
|
+
module CUKES
|
|
10
|
+
module DateTimeLibrary
|
|
11
|
+
|
|
12
|
+
# Description : returns the current system time (datetime format)
|
|
13
|
+
# Author : Chandra sekaran
|
|
14
|
+
#
|
|
15
|
+
def get_current_datetime
|
|
16
|
+
Time.now
|
|
17
|
+
rescue Exception => ex
|
|
18
|
+
$log.error("Error in getting current time : #{ex}")
|
|
19
|
+
exit
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Description : returns the formatted system time (datetime format)
|
|
23
|
+
# Author : Chandra sekaran
|
|
24
|
+
# Arguments :
|
|
25
|
+
# date_time : datetime value that has to be formatted
|
|
26
|
+
#
|
|
27
|
+
def get_formatted_datetime(date_time)
|
|
28
|
+
date_time.strftime(DATETIME_FORMAT)
|
|
29
|
+
rescue Exception => ex
|
|
30
|
+
$log.error("Error in getting formatted time : #{ex}")
|
|
31
|
+
#exit
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Description : returns the difference between two dates in Hours:Minutes:Seconds string
|
|
35
|
+
# Author : Chandra sekaran
|
|
36
|
+
# Arguments :
|
|
37
|
+
# start_date : datetime value for start time
|
|
38
|
+
# end_date : datetime value for end time
|
|
39
|
+
#
|
|
40
|
+
def get_datetime_diff(start_time, end_time)
|
|
41
|
+
num_difference = end_time.to_i - start_time.to_i
|
|
42
|
+
num_seconds = num_difference % 60 # get seconds
|
|
43
|
+
num_difference = (num_difference - num_seconds) / 60
|
|
44
|
+
num_minutes = num_difference % 60 # get minutes
|
|
45
|
+
num_difference = (num_difference - num_minutes) / 60
|
|
46
|
+
num_hours = num_difference % 24 # get hours
|
|
47
|
+
num_difference = (num_difference - num_hours) / 24
|
|
48
|
+
num_days = num_difference % 7 # get days
|
|
49
|
+
# num_weeks = (num_difference - num_days) / 7
|
|
50
|
+
|
|
51
|
+
if num_days > 0
|
|
52
|
+
return "#{num_days}:#{num_hours}:#{num_minutes}:#{num_seconds}"
|
|
53
|
+
else
|
|
54
|
+
return "#{num_hours}:#{num_minutes}:#{num_seconds}"
|
|
55
|
+
end
|
|
56
|
+
rescue Exception => ex
|
|
57
|
+
$log.error("Error in getting datetime difference : #{ex}")
|
|
58
|
+
#exit
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Description : converts nanoseconds into DD:HH:MM:SS time format
|
|
62
|
+
# Author : Chandra sekaran
|
|
63
|
+
# Argument :
|
|
64
|
+
# num_nanoseconds : datetime value for start time
|
|
65
|
+
# Return Argument : time in DD:HH:MM:SS as string
|
|
66
|
+
#
|
|
67
|
+
def format_nonoseconds_to_time(num_nanoseconds)
|
|
68
|
+
hours = num_nanoseconds/3.6E+12
|
|
69
|
+
minutes = hours*60%60
|
|
70
|
+
seconds = (hours*3600%60).round
|
|
71
|
+
days = hours.to_i/24
|
|
72
|
+
"#{days.to_i}:#{(hours.to_i%24).to_i}:#{minutes.to_i}:#{seconds}" # returns time in DD:HH:MM:SS format
|
|
73
|
+
rescue Exception => ex
|
|
74
|
+
$log.error("Error in converting nanoseconds (#{num_nanoseconds}) to time : #{ex}")
|
|
75
|
+
exit
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
*Name : FileLibrary
|
|
3
|
+
*Description : class that define methods for file related manipulations
|
|
4
|
+
*Author : Chandra sekaran
|
|
5
|
+
*Creation Date : 23/08/2014
|
|
6
|
+
*Updation Date :
|
|
7
|
+
=end
|
|
8
|
+
|
|
9
|
+
module CUKES
|
|
10
|
+
module FileLibrary
|
|
11
|
+
include DataMagic
|
|
12
|
+
|
|
13
|
+
# Description : checks for file existance and returns the boolean result
|
|
14
|
+
# Author : Chandra sekaran
|
|
15
|
+
# Arguments :
|
|
16
|
+
# str_file_path : absolute path of file
|
|
17
|
+
# Return values :
|
|
18
|
+
# bool_file : boolean variable that hold the result of the file existence
|
|
19
|
+
#
|
|
20
|
+
def is_file_exists(str_file_path)
|
|
21
|
+
bool_file = File.exists?(str_file_path)#get_absolute_path(str_file_name) )
|
|
22
|
+
bool_file
|
|
23
|
+
rescue Exception => ex
|
|
24
|
+
$log.error("Error while checking for existence of #{str_file_path} : #{ex}")
|
|
25
|
+
exit
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Description : opens the yml file
|
|
29
|
+
# Author : Chandra sekaran
|
|
30
|
+
# Arguments :
|
|
31
|
+
# str_file_path : absolute path of yml file
|
|
32
|
+
# Return values :
|
|
33
|
+
# obj_file : hash value of the yml file content
|
|
34
|
+
#
|
|
35
|
+
def open_yml_file(str_file_path)
|
|
36
|
+
obj_file = YAML.load_file(File.open(str_file_path)) #get_absolute_path(str_file_name)) # obj_file = YAML.load_file(format_filepath(str_file_name))
|
|
37
|
+
obj_file
|
|
38
|
+
rescue Exception => ex
|
|
39
|
+
$log.error("Error while opening #{str_file_path} : #{ex}")
|
|
40
|
+
exit
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Description : opens the excel file
|
|
44
|
+
# Author : Chandra sekaran
|
|
45
|
+
# Arguments :
|
|
46
|
+
# str_file_name : absolute path of excel file
|
|
47
|
+
# Return values :
|
|
48
|
+
# obj_file : file object of the workbook
|
|
49
|
+
#
|
|
50
|
+
def open_excel_file(str_file_name)
|
|
51
|
+
Spreadsheet.client_encoding = 'UTF-8'
|
|
52
|
+
obj_file = Spreadsheet.open(get_absolute_path(str_file_name))
|
|
53
|
+
$log.success("File #{str_file_name} opened successfully.")
|
|
54
|
+
obj_file
|
|
55
|
+
rescue Exception => ex
|
|
56
|
+
$log.error("Error while opening #{str_file_name} : #{ex}")
|
|
57
|
+
exit
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Description : closes the given file object
|
|
61
|
+
# Author : Chandra sekaran
|
|
62
|
+
# Arguments :
|
|
63
|
+
# file_object : object of the file to be closed
|
|
64
|
+
#
|
|
65
|
+
def close_file(file_object)
|
|
66
|
+
file_object.close
|
|
67
|
+
#$log.success("File #{file_object} closed successfully.")
|
|
68
|
+
rescue Exception => ex
|
|
69
|
+
#file_object = nil
|
|
70
|
+
$log.error("Error while closing #{file_object} : #{ex}")
|
|
71
|
+
exit
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Description : creates a new directory under the given path
|
|
75
|
+
# Author : Chandra sekaran
|
|
76
|
+
# Arguments :
|
|
77
|
+
# str_directory_path : absolute path of directory
|
|
78
|
+
#
|
|
79
|
+
def create_directory(str_directory_path)
|
|
80
|
+
unless File.directory?(str_directory_path)
|
|
81
|
+
FileUtils.mkdir_p(str_directory_path)
|
|
82
|
+
end
|
|
83
|
+
#$log.success("New directory created : #{str_directory_path}")
|
|
84
|
+
rescue Exception => ex
|
|
85
|
+
$log.error("Error in creating directory #{str_directory_path} : #{ex}")
|
|
86
|
+
exit
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Description : deletes an object
|
|
90
|
+
# Author : Chandra sekaran
|
|
91
|
+
# Arguments :
|
|
92
|
+
# object : object to be deleted
|
|
93
|
+
#
|
|
94
|
+
def self.delete_object(object)
|
|
95
|
+
object = nil
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Description : extracts the features module and submodule names from a given file path
|
|
99
|
+
# Author : Chandra sekaran
|
|
100
|
+
# Arguments :
|
|
101
|
+
# str_file_path : absolute path of the feature file
|
|
102
|
+
# Return value :
|
|
103
|
+
# str_feature_dir: string value of module/submodule name
|
|
104
|
+
#
|
|
105
|
+
def get_feature_module_name(str_file_path)
|
|
106
|
+
str_file_path = format_file_path(str_file_path)
|
|
107
|
+
str_file_path = str_file_path.split("features/").last # extracts all strings after 'features\'
|
|
108
|
+
#puts str_file_path
|
|
109
|
+
arr_file_dirs = str_file_path.split("/") # split the strings into array based on '\'
|
|
110
|
+
str_feature_dir = ""
|
|
111
|
+
|
|
112
|
+
arr_file_dirs.pop # removes the last element i.e., feature file
|
|
113
|
+
# arr_file_dirs.pop # removes the second last element i.e., test case folder
|
|
114
|
+
(0..arr_file_dirs.size - 1).each do |num_counter|
|
|
115
|
+
str_feature_dir << "_" if num_counter > 0
|
|
116
|
+
str_feature_dir << "#{arr_file_dirs[num_counter]}" # form a new string from array values
|
|
117
|
+
end
|
|
118
|
+
str_feature_dir
|
|
119
|
+
rescue Exception => ex
|
|
120
|
+
$log.error("Error in extracting features directory : #{ex}")
|
|
121
|
+
exit
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Description : Renames the created html/json report file and moves it to the current log directory
|
|
125
|
+
# Author : Chandra sekaran
|
|
126
|
+
#
|
|
127
|
+
def create_html_report
|
|
128
|
+
str_timestamp = $log_env.get_formatted_datetime($end_time)
|
|
129
|
+
# rename and move html report file into current test report directory
|
|
130
|
+
File.rename("#{$REPORT_FILE_NAME}.html", "report_#{str_timestamp}.html")
|
|
131
|
+
FileUtils.mv("report_#{str_timestamp}.html", $current_log_dir)
|
|
132
|
+
# rename and move json report file into current test report directory
|
|
133
|
+
File.rename("#{$REPORT_FILE_NAME}.json", "report_#{str_timestamp}.json")
|
|
134
|
+
FileUtils.mv("report_#{str_timestamp}.json", $current_log_dir)
|
|
135
|
+
$log.info("Html/JSON report files created and saved in '#{$current_log_dir}'")
|
|
136
|
+
rescue Exception => ex
|
|
137
|
+
$log.error("Error in creating html report : #{ex}")
|
|
138
|
+
exit
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Description : renames all files extension under given file path
|
|
142
|
+
# Author : Chandra sekaran
|
|
143
|
+
# Arguments :
|
|
144
|
+
# str_file_path : absolute path of file
|
|
145
|
+
# str_file_type : new file extension to be created
|
|
146
|
+
#
|
|
147
|
+
def rename_file_type(str_file_path, str_file_type)
|
|
148
|
+
Dir.glob(str_file_path).each do |file|
|
|
149
|
+
FileUtils.mv file, "#{File.dirname(file)}/#{File.basename(file,'.*')}.#{str_file_type}"
|
|
150
|
+
end
|
|
151
|
+
$log.info("File type(s) under '#{str_file_path}' renamed successfully to '#{str_file_type}'")
|
|
152
|
+
rescue Exception => ex
|
|
153
|
+
$log.error("Error in renaming '#{str_file_path}' to type '#{str_file_type}': #{ex}")
|
|
154
|
+
exit
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Description : get files which are all created under given file path with extension and after given timestamp
|
|
158
|
+
# Author : Gomathi
|
|
159
|
+
# Arguments :
|
|
160
|
+
# str_file_path : absolute path of file
|
|
161
|
+
# str_file_type : file extension
|
|
162
|
+
# obj_time_stamp : execution start time as time object
|
|
163
|
+
# Return argument :
|
|
164
|
+
# arr_files : array of file path(s)
|
|
165
|
+
#
|
|
166
|
+
def get_files_absolute_path(str_file_path, str_file_type, obj_time_stamp)
|
|
167
|
+
arr_abs_path = Dir["#{str_file_path}/*/*.#{str_file_type}"]
|
|
168
|
+
arr_files = []
|
|
169
|
+
arr_abs_path.each do |file_path|
|
|
170
|
+
arr_files << file_path if File.ctime(file_path) > obj_time_stamp
|
|
171
|
+
end
|
|
172
|
+
arr_files
|
|
173
|
+
rescue Exception => ex
|
|
174
|
+
$log.error("Error in getting '#{str_file_type}' file(s) under '#{str_file_path}' for '#{obj_time_stamp}' : #{ex}")
|
|
175
|
+
exit
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Description : formats the file path by replacing "\" with "/"
|
|
179
|
+
# Author : Chandra sekaran
|
|
180
|
+
# Arguments :
|
|
181
|
+
# str_fileabs_path : absolute path of file
|
|
182
|
+
# Return value :
|
|
183
|
+
# str_file_path : formatted absolute path of file
|
|
184
|
+
#
|
|
185
|
+
def format_file_path(str_fileabs_path)
|
|
186
|
+
str_file_path = str_fileabs_path
|
|
187
|
+
str_file_path.each_char do |letter| # replace all the escape sequences
|
|
188
|
+
case letter
|
|
189
|
+
when /[\a]/
|
|
190
|
+
str_file_path[letter] = "/a"
|
|
191
|
+
when /[\e]/
|
|
192
|
+
str_file_path[letter] = "/e"
|
|
193
|
+
when /[\b]/
|
|
194
|
+
str_file_path[letter] = "/b"
|
|
195
|
+
when /[\cx]/
|
|
196
|
+
str_file_path[letter] = "/cx"
|
|
197
|
+
when /[\f]/
|
|
198
|
+
str_file_path[letter] = "/f"
|
|
199
|
+
when /[\n]/
|
|
200
|
+
str_file_path[letter] = "/n"
|
|
201
|
+
when /[\nnn]/
|
|
202
|
+
#str_file_path[letter] = "/nnn" # not required as \n is given
|
|
203
|
+
when /[\r]/
|
|
204
|
+
str_file_path[letter] = "/r"
|
|
205
|
+
when /[\s]/
|
|
206
|
+
str_file_path[letter] = "/t" # it is taking "\t" as "\s"
|
|
207
|
+
when /[\t]/
|
|
208
|
+
str_file_path[letter] = "/t"
|
|
209
|
+
when "\\"
|
|
210
|
+
str_file_path[letter] = "/"
|
|
211
|
+
#when /[\v]/ # not required due to expression error
|
|
212
|
+
#str_file_path[letter] = "/v" # not required due to expression error
|
|
213
|
+
#when /[\x]/ # not required due to expression error
|
|
214
|
+
#str_file_path[letter] = "/x" # not required due to expression error
|
|
215
|
+
#when /[\xnn]/ # not required due to expression error
|
|
216
|
+
#str_file_path[letter] = "/xnn" # not required due to expression error
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
return str_file_path
|
|
220
|
+
rescue Exception => ex
|
|
221
|
+
$log.error("Error in formatting file path (#{str_file_path}) : #{ex}")
|
|
222
|
+
exit
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Description : extracts local file name and sets the directory path for DataMagic to load the data file for the current scenario/step
|
|
226
|
+
# Author : Chandra sekaran
|
|
227
|
+
# Arguments :
|
|
228
|
+
# str_datafile_name : name of data file
|
|
229
|
+
# Return value : hash of the loaded yml file
|
|
230
|
+
#
|
|
231
|
+
def set_scenario_based_datafile(str_global_file_name)
|
|
232
|
+
str_local_file_name = str_global_file_name
|
|
233
|
+
$scenario_tags.each do |tag|
|
|
234
|
+
if tag.include? SCENARIO_ID_PREFIX.downcase
|
|
235
|
+
tag_name = tag.gsub("@", "_")
|
|
236
|
+
tmp = str_global_file_name.gsub(".", "#{tag_name}.")
|
|
237
|
+
str_local_file_name = tmp
|
|
238
|
+
break
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
str_file_name = set_datafile_path(str_local_file_name, str_global_file_name)
|
|
242
|
+
DataMagic.load(str_file_name) # returns yml content as a hash
|
|
243
|
+
rescue Exception => ex
|
|
244
|
+
$log.error("Error in setting scenario based data file for (#{str_global_file_name}) : #{ex}")
|
|
245
|
+
exit
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Description : sets the directory path for DataMagic to load the data file for the current scenario/step
|
|
249
|
+
# Author : Chandra sekaran
|
|
250
|
+
# Arguments :
|
|
251
|
+
# str_local_file_name : name of local data file
|
|
252
|
+
# str_global_file_name: name of global data file
|
|
253
|
+
# Return value :
|
|
254
|
+
# actual_file : name of the required file
|
|
255
|
+
#
|
|
256
|
+
def set_datafile_path(str_local_file_name, str_global_file_name)
|
|
257
|
+
str_feature_file_path = format_file_path($str_feature_file_path)
|
|
258
|
+
arr_temp = str_feature_file_path.split("/")
|
|
259
|
+
arr_temp.pop
|
|
260
|
+
arr_temp.push(str_local_file_name)
|
|
261
|
+
str_datafile_dir = arr_temp * "/"
|
|
262
|
+
actual_file = ""
|
|
263
|
+
if File.exists?(str_datafile_dir)
|
|
264
|
+
arr_temp_dir = str_datafile_dir.split('/')
|
|
265
|
+
arr_temp_dir.pop
|
|
266
|
+
@str_temp_dir = arr_temp_dir * "/"
|
|
267
|
+
DataMagic.yml_directory = @str_temp_dir
|
|
268
|
+
actual_file = str_local_file_name
|
|
269
|
+
else
|
|
270
|
+
arr_temp_dir = str_datafile_dir.split('/')
|
|
271
|
+
arr_temp_dir.pop
|
|
272
|
+
arr_temp_dir.pop
|
|
273
|
+
arr_temp_dir.push("test_data")
|
|
274
|
+
@str_temp_dir = arr_temp_dir * "/"
|
|
275
|
+
DataMagic.yml_directory = @str_temp_dir
|
|
276
|
+
actual_file = str_global_file_name
|
|
277
|
+
end
|
|
278
|
+
puts "Test data file successfully set to #{@str_temp_dir}"
|
|
279
|
+
return actual_file
|
|
280
|
+
rescue Exception => ex
|
|
281
|
+
$log.error("Error in setting data file path (#{str_local_file_name}/#{str_global_file_name}) : #{ex}")
|
|
282
|
+
exit
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Description : execute the kernel command
|
|
286
|
+
# Author : Chandra sekaran
|
|
287
|
+
# Arguments :
|
|
288
|
+
# str_command : command string
|
|
289
|
+
# Return value : a boolean value
|
|
290
|
+
#
|
|
291
|
+
def execute_command(str_command)
|
|
292
|
+
str_stdout, str_stderr = '', ''
|
|
293
|
+
Open3.popen3(str_command) do |i,o,e|
|
|
294
|
+
i.close
|
|
295
|
+
while((line = o.gets))
|
|
296
|
+
str_stdout << line
|
|
297
|
+
end
|
|
298
|
+
while((line = e.gets))
|
|
299
|
+
str_stderr << line
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
$log.success("STDOUT : #{str_stdout.strip}") if !(str_stdout.nil? || str_stdout.empty?)
|
|
303
|
+
raise str_stderr.strip if !(str_stderr.nil? || str_stderr.empty?)
|
|
304
|
+
return true
|
|
305
|
+
rescue Exception => ex
|
|
306
|
+
$log.error("Error while executing the command (#{str_command}) : #{ex}")
|
|
307
|
+
exit
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
end
|
|
311
|
+
end
|
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
*Name : CustomHtmlReport
|
|
3
|
+
*Description : class that holds performance report data generator methods
|
|
4
|
+
*Author : Chandra sekaran
|
|
5
|
+
*Creation Date : 05/03/2015
|
|
6
|
+
*Updation Date :
|
|
7
|
+
=end
|
|
8
|
+
|
|
9
|
+
module CUKES
|
|
10
|
+
class PerformanceReport
|
|
11
|
+
|
|
12
|
+
# Description : invoked automatically when an object of the class type is created
|
|
13
|
+
# Author : Chandra sekaran
|
|
14
|
+
# Arguments :
|
|
15
|
+
# arr_file_paths : array of html report file paths
|
|
16
|
+
#
|
|
17
|
+
def initialize(arr_file_path)
|
|
18
|
+
@arr_file_name = arr_file_path
|
|
19
|
+
@num_build_duration = 0
|
|
20
|
+
@bool_build_passed = true
|
|
21
|
+
@num_feature_count = 0
|
|
22
|
+
@num_feature_pass_count = 0
|
|
23
|
+
@num_feature_fail_count = 0
|
|
24
|
+
@num_feature_skip_count = 0
|
|
25
|
+
@str_connection_url = "DBI:SQLAnywhere:SERVER=#{DB_SERVER};DBN=#{DB_NAME}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Description : parses the json object saves the required execution data into Sybase DB
|
|
29
|
+
# Author : Chandra sekaran
|
|
30
|
+
#
|
|
31
|
+
def parse_json
|
|
32
|
+
@json.each_with_index do |json, index| # iterate each feature
|
|
33
|
+
str_feature_id, num_feature_result_id = set_feature(json["name"].to_s) # add feature name
|
|
34
|
+
@num_feature_count += 1
|
|
35
|
+
scenario_count = 0
|
|
36
|
+
feature_duration = 0
|
|
37
|
+
bool_feature_passed = true
|
|
38
|
+
num_scenario_pass_count = 0
|
|
39
|
+
num_scenario_fail_count = 0
|
|
40
|
+
num_scenario_skip_count = 0
|
|
41
|
+
|
|
42
|
+
json["elements"].each do |element|
|
|
43
|
+
# for including the first background steps duration to the first scenario background steps as Cucumber json
|
|
44
|
+
# report considers background for the first scenario and hence will have 0 duration for the background steps
|
|
45
|
+
# under first scenario and the actual duration for the background will be set for the subsequent scenarios
|
|
46
|
+
if index == 0
|
|
47
|
+
if element["keyword"] == "Background"
|
|
48
|
+
element["steps"].each do |step|
|
|
49
|
+
@arr_background_step_duration << step["result"]["duration"].to_i
|
|
50
|
+
@bool = true
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
num_step_pass_count = 0
|
|
55
|
+
num_step_fail_count = 0
|
|
56
|
+
num_step_skip_count = 0
|
|
57
|
+
|
|
58
|
+
if element["keyword"] == "Scenario" # take scenario for scenario level details
|
|
59
|
+
str_scenario_id, scenario_result_id = set_scenario(element["name"], element["tags"][0]["name"], str_feature_id) # add scenario name
|
|
60
|
+
|
|
61
|
+
scenario_count += 1 # as it counts only 'Scenarios' and not 'Backgrounds'
|
|
62
|
+
step_count = 0
|
|
63
|
+
scenario_duration = 0
|
|
64
|
+
bool_scenario_passed = true
|
|
65
|
+
|
|
66
|
+
element["steps"].each_with_index do |step, indx| # iterate each steps of the current scenario
|
|
67
|
+
#num_step_id, num_step_result_id = set_step(step['keyword']+step['name'], str_scenario_id, scenario_result_id) # add step name
|
|
68
|
+
num_step_id = set_step(step['keyword']+step['name'], str_scenario_id, scenario_result_id) # add step name
|
|
69
|
+
|
|
70
|
+
step_count += 1
|
|
71
|
+
step_duration = 0
|
|
72
|
+
bool_step_passed = true
|
|
73
|
+
if (index == 0) && (indx < @arr_background_step_duration.size) && @bool
|
|
74
|
+
step_duration = @arr_background_step_duration[indx] # take duration from Background for the first scenario
|
|
75
|
+
else
|
|
76
|
+
step_duration = step['result']['duration'].to_i # take usual duration
|
|
77
|
+
@bool = false
|
|
78
|
+
end
|
|
79
|
+
scenario_duration += step_duration
|
|
80
|
+
if step['result']['status'] == "passed"
|
|
81
|
+
num_step_pass_count += 1
|
|
82
|
+
elsif step['result']['status'] == "failed"
|
|
83
|
+
num_step_fail_count += 1
|
|
84
|
+
elsif step['result']['status'] == "skipped"
|
|
85
|
+
num_step_skip_count += 1
|
|
86
|
+
end
|
|
87
|
+
bool_step_passed = ["passed", "pending"].include?(step['result']['status']) ? true : false
|
|
88
|
+
bool_scenario_passed &&= bool_step_passed
|
|
89
|
+
#puts "\t\t Step : #{step['keyword']+step['name']} - #{step_duration} - #{bool_step_passed}"
|
|
90
|
+
#reset_step_result(bool_step_passed, step_duration, num_step_result_id)
|
|
91
|
+
set_step_result_new(num_step_id, str_scenario_id, scenario_result_id, bool_step_passed, step_duration)
|
|
92
|
+
end
|
|
93
|
+
#puts "Scenario : #{element["tags"][0]["name"]} - #{element['name']} - #{scenario_duration} - #{bool_scenario_passed} - #{step_count}"
|
|
94
|
+
reset_scenario_result(scenario_result_id, scenario_duration, num_step_pass_count, num_step_fail_count, num_step_skip_count, bool_scenario_passed)
|
|
95
|
+
feature_duration += scenario_duration
|
|
96
|
+
bool_feature_passed &&= bool_scenario_passed
|
|
97
|
+
|
|
98
|
+
if bool_scenario_passed
|
|
99
|
+
num_scenario_pass_count += 1 # scenario pass count
|
|
100
|
+
else
|
|
101
|
+
if num_step_pass_count == 0 && num_step_fail_count == 0 && num_step_skip_count > 0
|
|
102
|
+
num_scenario_skip_count += 1 # scenario skip count
|
|
103
|
+
else
|
|
104
|
+
num_scenario_fail_count += 1 # scenario fail count
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
#puts "Feature : #{json['name']} - #{feature_duration} - #{bool_feature_passed} - #{scenario_count}"
|
|
111
|
+
reset_feature_result(feature_duration, num_scenario_pass_count, num_scenario_fail_count, num_scenario_skip_count, bool_feature_passed, num_feature_result_id)
|
|
112
|
+
@num_build_duration += feature_duration
|
|
113
|
+
@bool_build_passed &&= bool_feature_passed
|
|
114
|
+
|
|
115
|
+
if bool_feature_passed
|
|
116
|
+
@num_feature_pass_count += 1
|
|
117
|
+
else
|
|
118
|
+
@num_feature_fail_count += 1 # to do feature skip count
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
rescue Exception => ex
|
|
122
|
+
$log.error("Error while parsing JSON : #{ex}")
|
|
123
|
+
exit
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Description : sets the build data with default details into Sybase
|
|
127
|
+
# Author : Chandra sekaran
|
|
128
|
+
#
|
|
129
|
+
def set_build
|
|
130
|
+
num_host_id = get_host_data
|
|
131
|
+
build_name = Time.now.strftime("%d_%m_%Y-%H_%M_%S")
|
|
132
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
133
|
+
str_query = "insert into BuildData(BuildName,HostDataID) values (?,?)"
|
|
134
|
+
sth = dbh.prepare(str_query)
|
|
135
|
+
sth.execute(build_name, num_host_id)
|
|
136
|
+
sth.finish
|
|
137
|
+
dbh.commit
|
|
138
|
+
#puts "Added a record to BuildData table successfully"
|
|
139
|
+
|
|
140
|
+
str_query = "select BuildID from BuildData where BuildName='#{build_name}' and HostDataID=#{num_host_id}"
|
|
141
|
+
sth = dbh.prepare(str_query)
|
|
142
|
+
sth.execute()
|
|
143
|
+
@build_id = sth.fetch[0]
|
|
144
|
+
dbh.disconnect()
|
|
145
|
+
end
|
|
146
|
+
rescue Exception => ex
|
|
147
|
+
$log.error("Error in setting build data to BuildData table: #{ex}")
|
|
148
|
+
exit
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Description : gets the host data from Sybase based on current execution host
|
|
152
|
+
# Author : Chandra sekaran
|
|
153
|
+
# Return Arguments :
|
|
154
|
+
# num_host_id : primary key the host
|
|
155
|
+
#
|
|
156
|
+
def get_host_data
|
|
157
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
158
|
+
str_query = "select HostDataID from HostData where HostName like '#{ENV['COMPUTERNAME'].downcase}' and OS like '#{ENV['OS'].downcase}' and Browser like '#{BROWSER.downcase}'"
|
|
159
|
+
sth = dbh.prepare(str_query)
|
|
160
|
+
sth.execute()
|
|
161
|
+
num_host_id = sth.fetch[0]
|
|
162
|
+
dbh.disconnect()
|
|
163
|
+
$log.info("------------host id : #{num_host_id.nil?}")
|
|
164
|
+
num_host_id.nil? ? 5 : num_host_id
|
|
165
|
+
end
|
|
166
|
+
rescue Exception => ex
|
|
167
|
+
$log.error("Error in getting host data from HostData table: #{ex}")
|
|
168
|
+
exit
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Description : resets the build data with execution details into Sybase
|
|
172
|
+
# Author : Chandra sekaran
|
|
173
|
+
# Arguments :
|
|
174
|
+
# num_run_length : total execution time in nanoseconds
|
|
175
|
+
# num_pass_count : number of features passed
|
|
176
|
+
# num_fail_count : number of features failed
|
|
177
|
+
# num_skip_count : number of features skipped
|
|
178
|
+
# bool_result : boolean value resembling the state of build result
|
|
179
|
+
#
|
|
180
|
+
def reset_build(num_run_length, num_pass_count, num_fail_count, num_skip_count, bool_result)
|
|
181
|
+
num_result = bool_result ? 1 : 0
|
|
182
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
183
|
+
sth = dbh.prepare("update BuildData set RunLength=?, Passes=?, Failures=?, Skips=?, Result=? where BuildID=?")
|
|
184
|
+
sth.execute(convert_duration(num_run_length), num_pass_count, num_fail_count, num_skip_count, num_result, @build_id)
|
|
185
|
+
sth.finish
|
|
186
|
+
dbh.commit
|
|
187
|
+
#puts "Updated a record (#{@build_id}) in BuildData table successfully"
|
|
188
|
+
dbh.disconnect()
|
|
189
|
+
end
|
|
190
|
+
rescue Exception => ex
|
|
191
|
+
$log.error("Error in resetting build data to BuildData table: #{ex}")
|
|
192
|
+
exit
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Description : sets the feature data with default details into Sybase
|
|
196
|
+
# Author : Chandra sekaran
|
|
197
|
+
# Arguments :
|
|
198
|
+
# str_feature_name : feature name
|
|
199
|
+
# Return Arguments :
|
|
200
|
+
# num_feature_id : primary key the feature
|
|
201
|
+
# num_feature_result_id : primary key of the feature result
|
|
202
|
+
#
|
|
203
|
+
def set_feature(str_feature_name)
|
|
204
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
205
|
+
str_query = "select TestFeatureID from TestFeature where FeatureName=?"
|
|
206
|
+
sth = dbh.prepare(str_query)
|
|
207
|
+
sth.execute(str_feature_name)
|
|
208
|
+
|
|
209
|
+
if sth.fetch.nil? # insert only if the data is not present in the table
|
|
210
|
+
sth = dbh.prepare("insert into TestFeature(FeatureName) values (?)")
|
|
211
|
+
sth.execute(str_feature_name)
|
|
212
|
+
dbh.commit
|
|
213
|
+
#puts "Added a record to TestFeature table successfully"
|
|
214
|
+
end
|
|
215
|
+
str_query = "select TestFeatureID from TestFeature where FeatureName='#{str_feature_name}'"
|
|
216
|
+
sth = dbh.prepare(str_query)
|
|
217
|
+
sth.execute()
|
|
218
|
+
num_feature_id = sth.fetch[0]
|
|
219
|
+
#puts "********** Record found with Primary key '#{num_feature_id}' in TestFeature *************"
|
|
220
|
+
dbh.disconnect()
|
|
221
|
+
num_feature_result_id = set_feature_result(num_feature_id)
|
|
222
|
+
return num_feature_id, num_feature_result_id # return the feature id and feature result id of the feature
|
|
223
|
+
end
|
|
224
|
+
rescue Exception => ex
|
|
225
|
+
$log.error("Error in setting feature data to TestFeature table : #{ex}")
|
|
226
|
+
exit
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Description : sets the feature result data with default details into Sybase
|
|
230
|
+
# Author : Chandra sekaran
|
|
231
|
+
# Arguments :
|
|
232
|
+
# str_feature_name : feature_id of the feature
|
|
233
|
+
# Return Arguments :
|
|
234
|
+
# num_feature_result_id : primary key of the feature result
|
|
235
|
+
#
|
|
236
|
+
def set_feature_result(num_feature_id)
|
|
237
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
238
|
+
str_query = "select TestFeatureResultID from TestFeatureResult where TestFeatureID=? and BuildID=?"
|
|
239
|
+
sth = dbh.prepare(str_query)
|
|
240
|
+
sth.execute(num_feature_id, @build_id)
|
|
241
|
+
|
|
242
|
+
if sth.fetch.nil? # insert only if the data is not present in the table
|
|
243
|
+
sth = dbh.prepare("insert into TestFeatureResult(TestFeatureID,BuildID) values (?,?)")
|
|
244
|
+
sth.execute(num_feature_id, @build_id)
|
|
245
|
+
dbh.commit
|
|
246
|
+
#puts "Added a record to TestFeatureResult table successfully"
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
str_query = "select TestFeatureResultID from TestFeatureResult where TestFeatureID=#{num_feature_id} and BuildID=#{@build_id}"
|
|
250
|
+
sth = dbh.prepare(str_query)
|
|
251
|
+
sth.execute()
|
|
252
|
+
num_feature_result_id = sth.fetch[0]
|
|
253
|
+
#puts "********** Record found with Primary key '#{num_feature_result_id}' in TestFeatureResult *************"
|
|
254
|
+
dbh.disconnect()
|
|
255
|
+
return num_feature_result_id # return the feature result id of the feature
|
|
256
|
+
end
|
|
257
|
+
rescue Exception => ex
|
|
258
|
+
$log.error("Error in setting feature result data to TestFeatureResult table : #{ex}")
|
|
259
|
+
exit
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Description : resets the feature result data with execution details into Sybase
|
|
263
|
+
# Author : Chandra sekaran
|
|
264
|
+
# Arguments :
|
|
265
|
+
# num_run_length : feature execution time in nanoseconds
|
|
266
|
+
# num_pass_count : number of scenarios passed
|
|
267
|
+
# num_fail_count : number of scenarios failed
|
|
268
|
+
# num_skip_count : number of scenarios skipped
|
|
269
|
+
# bool_result : boolean value resembling the state of build result
|
|
270
|
+
# num_feature_result_id : primary key of the TestFeatureResult table
|
|
271
|
+
#
|
|
272
|
+
def reset_feature_result(num_run_length, num_pass_count, num_fail_count, num_skip_count, bool_result, num_feature_result_id)
|
|
273
|
+
num_result = bool_result ? 1 : 0
|
|
274
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
275
|
+
sth = dbh.prepare("update TestFeatureResult set RunLength=?, Passes=?, Failures=?, Skips=?, Result=? where TestFeatureResultID=?")
|
|
276
|
+
sth.execute(convert_duration(num_run_length), num_pass_count, num_fail_count, num_skip_count, num_result, num_feature_result_id)
|
|
277
|
+
sth.finish
|
|
278
|
+
dbh.commit
|
|
279
|
+
#puts "Updated a record (#{num_feature_result_id}) in TestFeatureResult table successfully"
|
|
280
|
+
dbh.disconnect()
|
|
281
|
+
end
|
|
282
|
+
rescue Exception => ex
|
|
283
|
+
$log.error("Error in resetting feature result data to TestFeatureResult table : #{ex}")
|
|
284
|
+
exit
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Description : sets the scenario data with default details into Sybase
|
|
288
|
+
# Author : Chandra sekaran
|
|
289
|
+
# Arguments :
|
|
290
|
+
# str_scenario_name : scenario name
|
|
291
|
+
# str_qa_complete_id : QA Complete ID (Scenario ID) of the scenario
|
|
292
|
+
# str_feature_id : primary key of the feature
|
|
293
|
+
# Return Arguments :
|
|
294
|
+
# num_scenario_id : primary key of the scenario
|
|
295
|
+
# scenario_result_id : primary key of the scenario result
|
|
296
|
+
#
|
|
297
|
+
def set_scenario(str_scenario_name, str_qa_complete_id, str_feature_id)
|
|
298
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
299
|
+
str_query = "select TestScenarioID from TestScenario where ScenarioName=? and TestFeatureID=?"
|
|
300
|
+
sth = dbh.prepare(str_query)
|
|
301
|
+
sth.execute(str_scenario_name, str_feature_id.to_i)
|
|
302
|
+
|
|
303
|
+
if sth.fetch.nil? # insert only if the data is not present in the table
|
|
304
|
+
sth = dbh.prepare("insert into TestScenario(ScenarioName,QACompleteID,TestFeatureID) values (?,?,?)")
|
|
305
|
+
sth.execute(str_scenario_name, str_qa_complete_id, str_feature_id.to_i)
|
|
306
|
+
sth.finish
|
|
307
|
+
dbh.commit
|
|
308
|
+
#puts "Added a record to TestScenario table successfully"
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
str_query = "select TestScenarioID from TestScenario where ScenarioName='#{str_scenario_name}' and TestFeatureID=#{str_feature_id}"
|
|
312
|
+
sth = dbh.prepare(str_query)
|
|
313
|
+
sth.execute()
|
|
314
|
+
num_scenario_id = sth.fetch[0]
|
|
315
|
+
#puts "********** Record found with Primary key '#{num_scenario_id}' in TestScenario *************"
|
|
316
|
+
scenario_result_id = set_scenario_result(num_scenario_id, str_feature_id)
|
|
317
|
+
dbh.disconnect()
|
|
318
|
+
return num_scenario_id, scenario_result_id # return the scenario id and scenario result id of the scenario
|
|
319
|
+
end
|
|
320
|
+
rescue Exception => ex
|
|
321
|
+
$log.error("Error in setting scenario data to TestScenario table : #{ex}")
|
|
322
|
+
exit
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# Description : sets the scenario result data with default details into Sybase
|
|
326
|
+
# Author : Chandra sekaran
|
|
327
|
+
# Arguments :
|
|
328
|
+
# num_scenario_id : primary key of the scenario
|
|
329
|
+
# num_feature_id : primary key of the feature
|
|
330
|
+
# Return Arguments :
|
|
331
|
+
# num_scenario_result_id : primary key of the scenario result
|
|
332
|
+
#
|
|
333
|
+
def set_scenario_result(num_scenario_id, num_feature_id)
|
|
334
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
335
|
+
sth = dbh.prepare("insert into TestScenarioResult(TestFeatureID,TestScenarioID,BuildID) values (?,?,?)")
|
|
336
|
+
sth.execute(num_feature_id, num_scenario_id, @build_id)
|
|
337
|
+
sth.finish
|
|
338
|
+
dbh.commit
|
|
339
|
+
#puts "Added a record to TestScenarioResult table successfully"
|
|
340
|
+
|
|
341
|
+
str_query = "select TestScenarioResultID from TestScenarioResult where TestFeatureID=#{num_feature_id} and TestScenarioID=#{num_scenario_id} and BuildID=#{@build_id}"
|
|
342
|
+
sth = dbh.prepare(str_query)
|
|
343
|
+
sth.execute()
|
|
344
|
+
num_scenario_result_id = sth.fetch[0]
|
|
345
|
+
#puts "********** Record found with Primary key '#{num_scenario_result_id}' in TestScenarioResult *************"
|
|
346
|
+
dbh.disconnect()
|
|
347
|
+
return num_scenario_result_id # return the scenario id of the scenario
|
|
348
|
+
end
|
|
349
|
+
rescue Exception => ex
|
|
350
|
+
$log.error("Error in setting scenario data to TestScenarioResult table : #{ex}")
|
|
351
|
+
exit
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Description : resets the scenario result data with execution details into Sybase
|
|
355
|
+
# Author : Chandra sekaran
|
|
356
|
+
# Arguments :
|
|
357
|
+
# num_scenario_result_id : primary key of the scenario result
|
|
358
|
+
# num_run_length : steps execution time in nanoseconds
|
|
359
|
+
# num_pass_count : number of steps passed
|
|
360
|
+
# num_fail_count : number of steps failed
|
|
361
|
+
# num_skip_count : number of steps skipped
|
|
362
|
+
# bool_result : boolean value resembling the state of steps result
|
|
363
|
+
#
|
|
364
|
+
def reset_scenario_result(num_scenario_result_id, num_run_length, num_pass_count, num_fail_count, num_skip_count, bool_result)
|
|
365
|
+
num_result = bool_result ? 1 : 0
|
|
366
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
367
|
+
sth = dbh.prepare("update TestScenarioResult set RunLength=?, Passes=?, Failures=?, Skips=?, Result=? where TestScenarioResultID=?")
|
|
368
|
+
sth.execute(convert_duration(num_run_length), num_pass_count, num_fail_count, num_skip_count, num_result, num_scenario_result_id)
|
|
369
|
+
sth.finish
|
|
370
|
+
dbh.commit
|
|
371
|
+
#puts "Updated a record (#{num_scenario_result_id}) in TestScenarioResult table successfully"
|
|
372
|
+
dbh.disconnect()
|
|
373
|
+
end
|
|
374
|
+
rescue Exception => ex
|
|
375
|
+
$log.error("Error in resetting scenario data to TestScenarioResult table : #{ex}")
|
|
376
|
+
exit
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Description : sets the step data with default details into Sybase
|
|
380
|
+
# Author : Chandra sekaran
|
|
381
|
+
# Arguments :
|
|
382
|
+
# str_step_name : step name
|
|
383
|
+
# str_scenario_id : primary key of scenario
|
|
384
|
+
# num_scenario_result_id : primary key of scenario result
|
|
385
|
+
# Return Arguments :
|
|
386
|
+
# num_step_id : primary key of step
|
|
387
|
+
# num_step_result_id : primary key of step result
|
|
388
|
+
#
|
|
389
|
+
def set_step(str_step_name, str_scenario_id, num_scenario_result_id)
|
|
390
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
391
|
+
str_query = "select TestStepID from TestStep where StepName=? and TestScenarioID=?"
|
|
392
|
+
sth = dbh.prepare(str_query)
|
|
393
|
+
sth.execute(str_step_name, str_scenario_id)
|
|
394
|
+
|
|
395
|
+
if sth.fetch.nil? # insert only if the data is not present in the table
|
|
396
|
+
sth = dbh.prepare("insert into TestStep(StepName,TestScenarioID) values (?,?)")
|
|
397
|
+
sth.execute(str_step_name, str_scenario_id)
|
|
398
|
+
dbh.commit
|
|
399
|
+
#puts "Added a record to TestStep table successfully"
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
str_query = "select TestStepID from TestStep where StepName='#{str_step_name}' and TestScenarioID=#{str_scenario_id}"
|
|
403
|
+
sth = dbh.prepare(str_query)
|
|
404
|
+
sth.execute()
|
|
405
|
+
num_step_id = sth.fetch[0]
|
|
406
|
+
#puts "********** Record found with Primary key '#{num_step_id}' in TestStep *************"
|
|
407
|
+
dbh.disconnect()
|
|
408
|
+
return num_step_id
|
|
409
|
+
end
|
|
410
|
+
rescue Exception => ex
|
|
411
|
+
$log.error("Error in setting step data to TestStep table : #{ex}")
|
|
412
|
+
exit
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# Description : sets the step result data with execution details into Sybase
|
|
416
|
+
# Author : Chandra sekaran
|
|
417
|
+
# Arguments :
|
|
418
|
+
# num_step_id : primary key of step
|
|
419
|
+
# num_scenario_id : primary key of scenario
|
|
420
|
+
# num_scenario_result_id : primary key of scenario result
|
|
421
|
+
# bool_result : boolean value resembling the state of step result
|
|
422
|
+
# num_run_length : steps execution time in nanoseconds
|
|
423
|
+
#
|
|
424
|
+
def set_step_result_new(num_step_id, num_scenario_id, num_scenario_result_id, bool_result, num_run_length)
|
|
425
|
+
num_result = bool_result ? 1 : 0
|
|
426
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
427
|
+
sth = dbh.prepare("insert into TestStepResult(TestScenarioResultID,Result,RunLength,TestStepID,BuildID,TestScenarioID) values (?,?,?,?,?,?)")
|
|
428
|
+
sth.execute(num_scenario_result_id, num_result, convert_duration(num_run_length), num_step_id, @build_id, num_scenario_id)
|
|
429
|
+
dbh.commit
|
|
430
|
+
dbh.disconnect()
|
|
431
|
+
#puts "Added a record to TestStepResult table successfully"
|
|
432
|
+
end
|
|
433
|
+
rescue Exception => ex
|
|
434
|
+
$log.error("(set_step_result_new)Error in setting step data to TestStepResult table : #{ex}")
|
|
435
|
+
exit
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
# Description : sets the step result data with default details into Sybase
|
|
439
|
+
# Author : Chandra sekaran
|
|
440
|
+
# Arguments :
|
|
441
|
+
# num_step_id : primary key of step
|
|
442
|
+
# str_scenario_id : primary key of scenario
|
|
443
|
+
# num_scenario_result_id : primary key of scenario result
|
|
444
|
+
# Return Arguments :
|
|
445
|
+
# num_step_result_id : primary key of step result
|
|
446
|
+
#
|
|
447
|
+
def set_step_result(num_step_id, num_scenario_id, num_scenario_result_id)
|
|
448
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
449
|
+
sth = dbh.prepare("insert into TestStepResult(TestScenarioResultID,TestStepID,BuildID,TestScenarioID) values (?,?,?,?)")
|
|
450
|
+
sth.execute(num_scenario_result_id, num_step_id, @build_id, num_scenario_id)
|
|
451
|
+
dbh.commit
|
|
452
|
+
#puts "Added a record to TestStepResult table successfully"
|
|
453
|
+
|
|
454
|
+
str_query = "select TestStepResultID from TestStepResult where TestScenarioResultID=#{num_scenario_result_id} and TestStepID=#{num_step_id} and BuildID=#{@build_id} and TestScenarioID=#{num_scenario_id}"
|
|
455
|
+
sth = dbh.prepare(str_query)
|
|
456
|
+
sth.execute()
|
|
457
|
+
num_step_result_id = sth.fetch[0]
|
|
458
|
+
#puts "********** Record found with Primary key '#{num_step_result_id}' in TestStepResult *************"
|
|
459
|
+
dbh.disconnect()
|
|
460
|
+
return num_step_result_id # return the step result id of the step
|
|
461
|
+
end
|
|
462
|
+
rescue Exception => ex
|
|
463
|
+
$log.error("Error in setting step data to TestStep table : #{ex}")
|
|
464
|
+
exit
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# Description : resets the step result data with execution details into Sybase
|
|
468
|
+
# Author : Chandra sekaran
|
|
469
|
+
# Arguments :
|
|
470
|
+
# bool_result : boolean value resembling the state of step result
|
|
471
|
+
# num_run_length : step execution time in nanoseconds
|
|
472
|
+
# num_step_result_id : primary key of step result
|
|
473
|
+
#
|
|
474
|
+
def reset_step_result(bool_result, num_run_length, num_step_result_id)
|
|
475
|
+
num_result = bool_result ? 1 : 0
|
|
476
|
+
DBI.connect(@str_connection_url, DB_USER_NAME, DB_PASSWORD) do |dbh|
|
|
477
|
+
sth = dbh.prepare("update TestStepResult set Result=?, RunLength=? where TestStepResultID=?")
|
|
478
|
+
sth.execute(num_result, convert_duration(num_run_length), num_step_result_id)
|
|
479
|
+
sth.finish
|
|
480
|
+
dbh.commit
|
|
481
|
+
#puts "Updated a record (#{num_step_result_id}) in TestStepResult table successfully"
|
|
482
|
+
dbh.disconnect()
|
|
483
|
+
end
|
|
484
|
+
rescue Exception => ex
|
|
485
|
+
$log.error("Error in resetting step results data in TestStepResult table : #{ex}")
|
|
486
|
+
exit
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Description : converts nanoseconds to seconds
|
|
490
|
+
# Author : Chandra sekaran
|
|
491
|
+
# Arguments :
|
|
492
|
+
# num_duration : time in nanoseconds
|
|
493
|
+
# Return Argument : time in seconds
|
|
494
|
+
#
|
|
495
|
+
def convert_duration(num_duration)
|
|
496
|
+
num_duration/(1000*1000*1000) #.to_f # convert nanosecond to second
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
# Description : function that creates performance report data and stores it in Sybase
|
|
500
|
+
# Author : Chandra sekaran
|
|
501
|
+
#
|
|
502
|
+
def create_performance_report
|
|
503
|
+
set_build # set Build data only once for each execution (Single or Parallel)
|
|
504
|
+
@arr_file_name.each do |path|
|
|
505
|
+
@arr_background_step_duration = []
|
|
506
|
+
file = File.read(path)
|
|
507
|
+
@json = JSON.parse(file)
|
|
508
|
+
parse_json # parse each json file and extract report data
|
|
509
|
+
end
|
|
510
|
+
#puts "Build duration : #{@num_build_duration} - #{@bool_build_passed} - #{@num_feature_count}"
|
|
511
|
+
reset_build(@num_build_duration, @num_feature_pass_count, @num_feature_fail_count, @num_feature_skip_count, @bool_build_passed) # Update the Build data with execution summary
|
|
512
|
+
rescue Exception => ex
|
|
513
|
+
$log.error("Error while creating report : #{ex}")
|
|
514
|
+
exit
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
end
|
|
518
|
+
end
|