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
|
Binary file
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
*Name : CreateLog
|
|
3
|
+
*Description : class that defines custom logger methods
|
|
4
|
+
*Author : Chandra sekaran
|
|
5
|
+
*Creation Date : 23/08/2014
|
|
6
|
+
*Updation Date :
|
|
7
|
+
=end
|
|
8
|
+
|
|
9
|
+
module CUKES
|
|
10
|
+
class CreateLog
|
|
11
|
+
include FileLibrary # module that define methods all file related manipulations
|
|
12
|
+
include DateTimeLibrary # module that define methods for all datetime related manipulations
|
|
13
|
+
|
|
14
|
+
# Description : initializes the Logger class and creates a new log file
|
|
15
|
+
# Author : Chandra sekaran
|
|
16
|
+
# Arguments :
|
|
17
|
+
# str_logfile_name: name of the log file to be created
|
|
18
|
+
#
|
|
19
|
+
def initialize(str_logfile_name = "log_")
|
|
20
|
+
begin
|
|
21
|
+
date_time_format = DATETIME_FORMAT || "%d_%m_%Y-%H_%M_%S"
|
|
22
|
+
rescue Exception => ex
|
|
23
|
+
date_time_format = "%d_%m_%Y-%H_%M_%S" # when DATETIME_FORMAT is not defined
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
begin
|
|
27
|
+
level = LOGGER_LEVEL || "DEBUG"
|
|
28
|
+
rescue Exception => ex
|
|
29
|
+
level = "DEBUG" # when LOGGER_LEVEL is not defined
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
begin
|
|
33
|
+
@str_logdir_name = $current_log_dir || "./test_result/test_report_#{Time.now.strftime(date_time_format)}" # this line is enough, ex handlng not need
|
|
34
|
+
rescue Exception => ex
|
|
35
|
+
@str_logdir_name = "./test_result/test_report_#{Time.now.strftime(date_time_format)}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
create_directory(@str_logdir_name) # creates a new directory
|
|
39
|
+
@log_file = "#{@str_logdir_name}/#{str_logfile_name}.log"
|
|
40
|
+
@log = Logger.new(@log_file) # creates a new log file
|
|
41
|
+
set_level(level) # sets the Logger::Level
|
|
42
|
+
@log.datetime_format = date_time_format # sets the datetime format
|
|
43
|
+
@log.formatter = lambda do |severity, datetime, progname, message|
|
|
44
|
+
"[#{Time.now.strftime(date_time_format)}] #{severity}: #{message}\n" # customize the log content
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Description : logs a DEBUG message
|
|
49
|
+
# Author : Chandra sekaran
|
|
50
|
+
# Arguments :
|
|
51
|
+
# message : string message to be logged
|
|
52
|
+
#
|
|
53
|
+
def debug(message)
|
|
54
|
+
@log.debug(message)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Description : logs an INFO message
|
|
58
|
+
# Author : Chandra sekaran
|
|
59
|
+
# Arguments :
|
|
60
|
+
# message : string message to be logged
|
|
61
|
+
#
|
|
62
|
+
def info(message)
|
|
63
|
+
@log.info(message)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Description : logs a WARN message
|
|
67
|
+
# Author : Chandra sekaran
|
|
68
|
+
# Arguments :
|
|
69
|
+
# message : string message to be logged
|
|
70
|
+
#
|
|
71
|
+
def warn(message)
|
|
72
|
+
@log.warn(message)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Description : logs an ERROR message
|
|
76
|
+
# Author : Chandra sekaran
|
|
77
|
+
# Arguments :
|
|
78
|
+
# message : string message to be logged
|
|
79
|
+
#
|
|
80
|
+
def error(message)
|
|
81
|
+
@log.error(message)
|
|
82
|
+
#$world.puts(message) if !$world.nil?
|
|
83
|
+
#exit #raise #"EXCEPTION RAISED"#Cucumber.wants_to_quit = true # exit(1)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Description : logs a success message
|
|
87
|
+
# Author : Chandra sekaran
|
|
88
|
+
# Arguments :
|
|
89
|
+
# message : string message to be logged
|
|
90
|
+
#
|
|
91
|
+
def success(message)
|
|
92
|
+
info(message)
|
|
93
|
+
$world.puts(message) if !$world.nil?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Description : logs a FATAL message
|
|
97
|
+
# Author : Chandra sekaran
|
|
98
|
+
# Arguments :
|
|
99
|
+
# message : string message to be logged
|
|
100
|
+
#
|
|
101
|
+
def fatal(message)
|
|
102
|
+
@log.fatal(message)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Description : sets the logger level
|
|
106
|
+
# Author : Chandra sekaran
|
|
107
|
+
# Arguments :
|
|
108
|
+
# level : logger level string
|
|
109
|
+
#
|
|
110
|
+
def set_level(level)
|
|
111
|
+
case level.upcase
|
|
112
|
+
when "DEBUG"
|
|
113
|
+
@log.level = Logger::DEBUG
|
|
114
|
+
when "INFO"
|
|
115
|
+
@log.level = Logger::INFO
|
|
116
|
+
when "WARN"
|
|
117
|
+
@log.level = Logger::WARN
|
|
118
|
+
when "ERROR"
|
|
119
|
+
@log.level = Logger::ERROR
|
|
120
|
+
when "FATAL"
|
|
121
|
+
@log.level = Logger::FATAL
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Description : creates a new directory under the given path (newly added to override the method in file_library.rb)
|
|
126
|
+
# Author : Chandra sekaran
|
|
127
|
+
# Arguments :
|
|
128
|
+
# str_directory_path : relative path of the directory to be created
|
|
129
|
+
#
|
|
130
|
+
def create_directory(str_directory_path)
|
|
131
|
+
unless File.directory?(str_directory_path)
|
|
132
|
+
FileUtils.mkdir_p(str_directory_path)
|
|
133
|
+
puts "New directory created under : #{str_directory_path}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Description : returns the relative path of currently created directory
|
|
138
|
+
# Author : Chandra sekaran
|
|
139
|
+
#
|
|
140
|
+
def get_current_log_dir
|
|
141
|
+
@str_logdir_name
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Description : returns the relative path of currently created file (logfile)
|
|
145
|
+
# Author : Chandra sekaran
|
|
146
|
+
#
|
|
147
|
+
def get_current_log_file
|
|
148
|
+
@log_file
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
private
|
|
152
|
+
attr_reader :log
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -0,0 +1,852 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
*Name : CustomHtmlReport
|
|
3
|
+
*Description : class that holds custom report file generator methods
|
|
4
|
+
*Author : Chandra sekaran
|
|
5
|
+
*Creation Date : 11/11/2014
|
|
6
|
+
*Updation Date : 19/02/2015
|
|
7
|
+
=end
|
|
8
|
+
|
|
9
|
+
module CUKES
|
|
10
|
+
class CustomHtmlReport
|
|
11
|
+
include FileLibrary
|
|
12
|
+
include DateTimeLibrary
|
|
13
|
+
|
|
14
|
+
# Description : invoked automatically when an object of the class type is created
|
|
15
|
+
# Author : Chandra sekaran
|
|
16
|
+
# Arguments :
|
|
17
|
+
# arr_file_paths : array of html report file paths
|
|
18
|
+
#
|
|
19
|
+
def initialize(arr_file_paths)
|
|
20
|
+
@arr_file_name = arr_file_paths
|
|
21
|
+
@template_file_name = arr_file_paths.first # take the html template from first html file
|
|
22
|
+
|
|
23
|
+
@scenario=[]
|
|
24
|
+
@scenario_pass=[]
|
|
25
|
+
@scenario_fail=[]
|
|
26
|
+
@scenario_skip=[]
|
|
27
|
+
@scenario_pending=[]
|
|
28
|
+
@scenario_undefined=[]
|
|
29
|
+
@step=[]
|
|
30
|
+
@step_pass=[]
|
|
31
|
+
@step_fail=[]
|
|
32
|
+
@step_skip=[]
|
|
33
|
+
@step_pending=[]
|
|
34
|
+
@step_undefined=[]
|
|
35
|
+
|
|
36
|
+
@feature=[]
|
|
37
|
+
@arr_html_file_name = []
|
|
38
|
+
@arr_testcase_id = []
|
|
39
|
+
@arr_feature_id = []
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Description : creates new directory for custom report files and copies other dependents
|
|
43
|
+
# Author : Chandra sekaran
|
|
44
|
+
#
|
|
45
|
+
def create_report_directory
|
|
46
|
+
create_directory("#{$current_log_dir}/custom_report")
|
|
47
|
+
create_directory("#{$current_log_dir}/custom_report/detailed_report")
|
|
48
|
+
FileUtils.cp("library/generic/app_logo_1.png", "#{$current_log_dir}/custom_report/detailed_report")
|
|
49
|
+
# copy screenshot directory to custom_report directory for image attachment of custom report html files
|
|
50
|
+
FileUtils.cp_r("#{$current_log_dir}/screenshot", "#{$current_log_dir}/custom_report/detailed_report") rescue Exception
|
|
51
|
+
rescue Exception => ex
|
|
52
|
+
$log.error("Error in creating custom report directory : #{ex}")
|
|
53
|
+
exit
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Description : creates new html template object based cucumber report file generated
|
|
57
|
+
# Author : Chandra sekaran
|
|
58
|
+
# Arguments :
|
|
59
|
+
# str_file_path : file path of html file
|
|
60
|
+
# Return arguments :
|
|
61
|
+
# html_template : html object
|
|
62
|
+
#
|
|
63
|
+
def create_html_template(str_file_path)
|
|
64
|
+
html_template = Nokogiri::HTML(File.read(str_file_path))
|
|
65
|
+
html_template.xpath("//div[@id='label']/h1").each do |t|
|
|
66
|
+
t.replace("<br><div class='centr'>CUKES - TEST REPORT SUMMARY</div>")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
bottom = Nokogiri::XML::Node.new("footer", html_template)
|
|
70
|
+
div = html_template.at_css("div.feature")
|
|
71
|
+
div.add_next_sibling(bottom)
|
|
72
|
+
|
|
73
|
+
html_template.at('footer')["id"] = "footer"
|
|
74
|
+
|
|
75
|
+
html_template.xpath("//div[@class='feature']").each do |n|
|
|
76
|
+
n.replace(Nokogiri::XML::Node.new("p", html_template))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
footer = Nokogiri::XML::Node.new("div", html_template)
|
|
80
|
+
timestamp = Nokogiri::XML::Node.new("div", html_template)
|
|
81
|
+
timestamp.inner_html = "<font color='white' size='2'>Executed on #{Time.now.strftime('%m-%d-%Y %I:%M:%S')} <br> Executed in #{ENV['COMPUTERNAME']} (#{ENV['OS']}) / #{BROWSER.capitalize} (#{$browser_version})</font>"
|
|
82
|
+
logo = Nokogiri::XML::Node.new("img", html_template)
|
|
83
|
+
|
|
84
|
+
footer.add_child(logo)
|
|
85
|
+
footer.add_child(timestamp)
|
|
86
|
+
|
|
87
|
+
footer['style'] = "background-color: #363636;" # black color
|
|
88
|
+
|
|
89
|
+
footer.add_child("<style type='text/css'>#footer {position : fixed;margin-top : 35px;text-align:center;width: 100%;height: 63px;bottom: 0px; left: 0px;}</style>")
|
|
90
|
+
bottom.add_child(footer)
|
|
91
|
+
html_template.at('img')["src"] = "data:image/png;base64," + Base64.strict_encode64(File.open(File.absolute_path("library/generic/app_logo_1.png"), "rb").read)
|
|
92
|
+
html_template.at('img')["height"] = "30px"
|
|
93
|
+
|
|
94
|
+
html_template.xpath("//div[@id='summary']/p[1]").each do |t|
|
|
95
|
+
t.replace(Nokogiri::XML::Node.new("p", html_template)) # remove pass/fail count in the report header
|
|
96
|
+
end
|
|
97
|
+
html_template.xpath("//div[@id='summary']/p[2]").each do |t|
|
|
98
|
+
t.replace(Nokogiri::XML::Node.new("p", html_template)) # remove execution duration in the report header
|
|
99
|
+
end
|
|
100
|
+
return html_template
|
|
101
|
+
rescue Exception => ex
|
|
102
|
+
$log.error("Error in creating report html template : #{ex}")
|
|
103
|
+
exit
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Description : creates new html file holding complete execution summary
|
|
107
|
+
# Author : Chandra sekaran
|
|
108
|
+
#
|
|
109
|
+
def create_main_report
|
|
110
|
+
@html_template = create_html_template(@template_file_name)
|
|
111
|
+
template_header = @html_template.at_css "div#cucumber-header"
|
|
112
|
+
timestamp = Nokogiri::XML::Node.new("h4", @html_template)
|
|
113
|
+
timestamp.inner_html = "Executed on #{$log_env.get_formatted_datetime($start_time)}"
|
|
114
|
+
logo = Nokogiri::XML::Node.new("img", @html_template)
|
|
115
|
+
h1 = @html_template.at_css "h1"
|
|
116
|
+
|
|
117
|
+
br = Nokogiri::XML::Node.new("div", @html_template)
|
|
118
|
+
br.inner_html="<br><br><br>"
|
|
119
|
+
|
|
120
|
+
@table = Nokogiri::XML::Node.new("table", @html_template)
|
|
121
|
+
|
|
122
|
+
row_size = @feature.size
|
|
123
|
+
|
|
124
|
+
create_report_table_header
|
|
125
|
+
|
|
126
|
+
@tot_feature = 0
|
|
127
|
+
@tot_scenario = 0
|
|
128
|
+
@tot_scenario_pass = 0
|
|
129
|
+
@tot_scenario_fail = 0
|
|
130
|
+
@tot_scenario_skip = 0
|
|
131
|
+
@tot_scenario_pending = 0
|
|
132
|
+
@tot_scenario_undefined = 0
|
|
133
|
+
@tot_step = 0
|
|
134
|
+
@tot_step_pass = 0
|
|
135
|
+
@tot_step_fail = 0
|
|
136
|
+
@tot_step_skip = 0
|
|
137
|
+
@tot_step_pending = 0
|
|
138
|
+
@tot_step_undefined = 0
|
|
139
|
+
|
|
140
|
+
for i in 1..row_size
|
|
141
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template)
|
|
142
|
+
|
|
143
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
144
|
+
td.inner_html = "#{i}"
|
|
145
|
+
tr.add_child(td)
|
|
146
|
+
@tot_feature = i
|
|
147
|
+
|
|
148
|
+
if ["yes", "true"].include? INCLUDE_FEATUREID_IN_REPORT.downcase
|
|
149
|
+
td = Nokogiri::XML::Node.new("td", @html_template) # for Feature ID
|
|
150
|
+
td.inner_html = @arr_feature_id[i-1].nil? ? " " : @arr_feature_id[i-1].gsub("@", "").to_s
|
|
151
|
+
tr.add_child(td)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
if ["yes", "true"].include? INCLUDE_SCENARIOID_IN_REPORT.downcase
|
|
155
|
+
td = Nokogiri::XML::Node.new("td", @html_template) # for Scenario ID
|
|
156
|
+
td.inner_html = @arr_testcase_id[i-1].nil? ? " " : @arr_testcase_id[i-1].join(", ").to_s
|
|
157
|
+
tr.add_child(td)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
161
|
+
td.inner_html = "<a href='detailed_report/#{@arr_html_file_name[i-1]}.html' target='_blank'>#{@feature[i-1]}</a>"
|
|
162
|
+
tr.add_child(td)
|
|
163
|
+
td['width'] = "40%"
|
|
164
|
+
|
|
165
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
166
|
+
td.inner_html = "#{@scenario[i-1]}"
|
|
167
|
+
tr.add_child(td)
|
|
168
|
+
@tot_scenario += @scenario[i-1]
|
|
169
|
+
|
|
170
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
171
|
+
num_pass_count = @scenario_pass[i-1]
|
|
172
|
+
td.inner_html = "#{num_pass_count}"
|
|
173
|
+
td['style'] = "background-color: #b0f9c3;" if num_pass_count > 0 # green color
|
|
174
|
+
tr.add_child(td)
|
|
175
|
+
@tot_scenario_pass += num_pass_count
|
|
176
|
+
|
|
177
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
178
|
+
td.inner_html = "#{@scenario_fail[i-1]}"
|
|
179
|
+
td['style'] = "background-color: #fbc8d5;" if @scenario_fail[i-1] > 0 # red color
|
|
180
|
+
tr.add_child(td)
|
|
181
|
+
@tot_scenario_fail += @scenario_fail[i-1]
|
|
182
|
+
|
|
183
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
184
|
+
td.inner_html = "#{@scenario_skip[i-1]}"
|
|
185
|
+
td['style'] = "background-color: #f2f9b0;" if @scenario_skip[i-1] > 0 # yellow color
|
|
186
|
+
tr.add_child(td)
|
|
187
|
+
@tot_scenario_skip += @scenario_skip[i-1]
|
|
188
|
+
|
|
189
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
190
|
+
td.inner_html = "#{@scenario_pending[i-1]}"
|
|
191
|
+
td['style'] = "background-color: #f2f9b0;" if @scenario_pending[i-1] > 0 # yellow color
|
|
192
|
+
tr.add_child(td)
|
|
193
|
+
@tot_scenario_pending += @scenario_pending[i-1]
|
|
194
|
+
|
|
195
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
196
|
+
td.inner_html = "#{@scenario_undefined[i-1]}"
|
|
197
|
+
td['style'] = "background-color: #f2f9b0;" if @scenario_undefined[i-1] > 0 # yellow color
|
|
198
|
+
tr.add_child(td)
|
|
199
|
+
@tot_scenario_undefined += @scenario_undefined[i-1]
|
|
200
|
+
|
|
201
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
202
|
+
td.inner_html = "#{@step[i-1]}"
|
|
203
|
+
tr.add_child(td)
|
|
204
|
+
@tot_step += @step[i-1]
|
|
205
|
+
|
|
206
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
207
|
+
td.inner_html = "#{@step_pass[i-1]}"
|
|
208
|
+
td['style'] = "background-color: #b0f9c3;" if @step_pass[i-1] > 0 # green color
|
|
209
|
+
tr.add_child(td)
|
|
210
|
+
@tot_step_pass += @step_pass[i-1]
|
|
211
|
+
|
|
212
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
213
|
+
td.inner_html = "#{@step_fail[i-1]}"
|
|
214
|
+
td['style'] = "background-color: #fbc8d5;" if @step_fail[i-1] > 0 # red color
|
|
215
|
+
tr.add_child(td)
|
|
216
|
+
@tot_step_fail += @step_fail[i-1]
|
|
217
|
+
|
|
218
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
219
|
+
td.inner_html = "#{@step_skip[i-1]}"
|
|
220
|
+
td['style'] = "background-color: #f2f9b0;" if @step_skip[i-1] > 0 # yellow color
|
|
221
|
+
tr.add_child(td)
|
|
222
|
+
@tot_step_skip += @step_skip[i-1]
|
|
223
|
+
|
|
224
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
225
|
+
td.inner_html = "#{@step_pending[i-1]}"
|
|
226
|
+
td['style'] = "background-color: #f2f9b0;" if @step_pending[i-1] > 0 # yellow color
|
|
227
|
+
tr.add_child(td)
|
|
228
|
+
@tot_step_pending += @step_pending[i-1]
|
|
229
|
+
|
|
230
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
231
|
+
td.inner_html = "#{@step_undefined[i-1]}"
|
|
232
|
+
td['style'] = "background-color: #f2f9b0;" if @step_undefined[i-1] > 0 # yellow color
|
|
233
|
+
tr.add_child(td)
|
|
234
|
+
@tot_step_undefined += @step_undefined[i-1]
|
|
235
|
+
|
|
236
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
237
|
+
td.inner_html = @scenario_fail[i-1] > 0 ? "Failed" : "Passed"
|
|
238
|
+
td['style'] = @scenario_fail[i-1] > 0 ? "background-color: #fbc8d5;" : "background-color: #b0f9c3;"
|
|
239
|
+
tr.add_child(td)
|
|
240
|
+
|
|
241
|
+
@table.add_child(tr)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
create_report_table_footer
|
|
245
|
+
|
|
246
|
+
@table['style'] = "width:90%; font:13px;"
|
|
247
|
+
10.times { template_header.add_next_sibling("<br>") }
|
|
248
|
+
template_header.add_next_sibling(@table)
|
|
249
|
+
template_header.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;} .left{margin-left:50px;margin-top:20px;margin-bottom:20px;font:bold 12.5px 'Lucida Grande',Helvetica,sans-serif;} .centr{font-size:200%;font-weight:bold;text-align:center;}</script>")
|
|
250
|
+
@html_template.at('table')["border"] = 2
|
|
251
|
+
@html_template.at('table')["align"] = "center"
|
|
252
|
+
|
|
253
|
+
# set report header background color
|
|
254
|
+
if @tot_scenario_fail > 0 # for red color header
|
|
255
|
+
template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#c40d0d'); $('#cucumber-header').css('color', '#FFFFFF');</script>")
|
|
256
|
+
elsif @tot_scenario_pending > 0 # for yellow color header
|
|
257
|
+
template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#f2f9b0'); $('#cucumber-header').css('color', '#000000');</script>")
|
|
258
|
+
else # for green color header
|
|
259
|
+
template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#65c400'); $('#cucumber-header').css('color', '#FFFFFF');</script>")
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
@html_template.xpath("//div[@id='expand-collapse']").each do |t|
|
|
263
|
+
t.replace(Nokogiri::XML::Node.new("p", @html_template)) # removes Collapse All & Expand All links
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# style : .left{margin-left:50px;margin-top:20px;margin-bottom:20px;font:bold 12.5px 'Lucida Grande',Helvetica,sans-serif;}
|
|
267
|
+
template_header.add_next_sibling("<div class='left' id='build_result'><b>Execution details : <b></div>")
|
|
268
|
+
build_res = @html_template.at_css "div#build_result"
|
|
269
|
+
arr_build_durations = get_execution_duration
|
|
270
|
+
# for getting individual build durations
|
|
271
|
+
#@arr_json_report_file.each_with_index do |file, indx|
|
|
272
|
+
# build_res.add_child("<div> Build - #{indx+1} duration : #{format_nonoseconds_to_time(arr_build_durations[indx])}</div>")
|
|
273
|
+
#end
|
|
274
|
+
build_res.add_child("<div> Total number of executions : #{@arr_json_report_file.size}</div>")
|
|
275
|
+
build_res.add_child("<div> Total duration (DD:HH:MM:SS) : #{format_nonoseconds_to_time(@num_build_duration)}</div>")
|
|
276
|
+
build_res.add_child("<div> Total build duration (DD:HH:MM:SS) : #{format_nonoseconds_to_time(arr_build_durations.max)}</div>")
|
|
277
|
+
|
|
278
|
+
File.open("#{$current_log_dir}/custom_report/report_home.html", "w") do |f|
|
|
279
|
+
f.write(@html_template)
|
|
280
|
+
end
|
|
281
|
+
rescue Exception => ex
|
|
282
|
+
$log.error("Error in creating main html report : #{ex}")
|
|
283
|
+
exit
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Description : creates new html files holding complete execution summary for each feature
|
|
287
|
+
# Author : Chandra sekaran
|
|
288
|
+
# Argument :
|
|
289
|
+
# str_file_path : file path of the report file
|
|
290
|
+
#
|
|
291
|
+
def create_sub_report(str_file_path)
|
|
292
|
+
@html_doc = Nokogiri::HTML(File.read(str_file_path))
|
|
293
|
+
br = Nokogiri::XML::Node.new("p", @html_doc)
|
|
294
|
+
|
|
295
|
+
@html_doc.xpath("//div[@class='feature']").each_with_index do |f, index|
|
|
296
|
+
@scenario_name = []
|
|
297
|
+
@num_step_count = []
|
|
298
|
+
@num_step_pass_count = []
|
|
299
|
+
@num_step_fail_count = []
|
|
300
|
+
@num_step_skip_count = []
|
|
301
|
+
@num_step_pending_count = []
|
|
302
|
+
@num_step_undefined_count = []
|
|
303
|
+
|
|
304
|
+
@html_template1 = create_html_template(@template_file_name)
|
|
305
|
+
# @html_template1.at('img')["src"] = "app_logo_1.png" # change the image file path for the sub-report files
|
|
306
|
+
@html_template1.at('img')["src"] = "data:image/png;base64," + Base64.strict_encode64(File.open(File.absolute_path("library/generic/app_logo_1.png"), "rb").read) # change the image file path for the sub-report files
|
|
307
|
+
template_header1 = @html_template1.at_css "div#cucumber-header"
|
|
308
|
+
|
|
309
|
+
@feature << f.xpath("./h2/span[@class='val']").text.gsub("Feature:", "")
|
|
310
|
+
|
|
311
|
+
begin # for feature documentation header content
|
|
312
|
+
pre_old = f.at_css "pre"
|
|
313
|
+
f.xpath("./pre").each do |t|
|
|
314
|
+
t.replace("<br><br><br><br><pre><font color='black'>")
|
|
315
|
+
end
|
|
316
|
+
font = f.at_css "font"
|
|
317
|
+
font.add_child(pre_old)
|
|
318
|
+
rescue Exception => ex
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
@scenario_skip_count = 0
|
|
322
|
+
|
|
323
|
+
cstep = 0
|
|
324
|
+
cstep_pass = 0
|
|
325
|
+
cstep_fail = 0
|
|
326
|
+
cstep_skip = 0
|
|
327
|
+
cstep_pending = 0
|
|
328
|
+
cstep_undefined = 0
|
|
329
|
+
|
|
330
|
+
bstep = 0
|
|
331
|
+
bstep_pass = 0
|
|
332
|
+
bstep_fail = 0
|
|
333
|
+
bstep_skip = 0
|
|
334
|
+
bstep_pending = 0
|
|
335
|
+
|
|
336
|
+
f.search("./div[@class='scenario']/h3").each do |s|
|
|
337
|
+
@scenario_name << s.inner_text.strip
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
f.search("./div[@class='background']").each do |s|
|
|
341
|
+
bstep = s.search(".//ol/li/div[@class='step_name']").size
|
|
342
|
+
bstep_pass = s.search(".//ol/li[@class='step passed']").size
|
|
343
|
+
bstep_fail = s.search(".//ol/li[@class='step failed']").size
|
|
344
|
+
bstep_skip = s.search(".//ol/li[@class='step skipped']").size
|
|
345
|
+
bstep_pending = s.search(".//ol/li[@class='step pending']").size
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
@scenario << f.search("./div[@class='scenario']").size
|
|
349
|
+
tmp = []
|
|
350
|
+
break_count = true # for getting scenario ID of scenario that has failed in Background itself
|
|
351
|
+
@pass_step_count = 0
|
|
352
|
+
@fail_step_count = 0
|
|
353
|
+
if bstep_fail > 0
|
|
354
|
+
f.search("./div[@class='scenario']").each_with_index do |s, indx|
|
|
355
|
+
cstep += bstep
|
|
356
|
+
cstep_fail = bstep_fail
|
|
357
|
+
cstep_skip += bstep_skip
|
|
358
|
+
cstep_pending += bstep_pending
|
|
359
|
+
|
|
360
|
+
cstep += s.search(".//ol/li/div[@class='step_name']").size
|
|
361
|
+
cstep_skip += s.search(".//ol/li[@class='step skipped']").size
|
|
362
|
+
cstep_pending += s.search(".//ol/li[@class='step pending']").size
|
|
363
|
+
|
|
364
|
+
@num_step_count << s.search(".//ol/li/div[@class='step_name']").size + bstep
|
|
365
|
+
@num_step_fail_count << bstep_fail
|
|
366
|
+
@num_step_skip_count << s.search(".//ol/li[@class='step skipped']").size
|
|
367
|
+
@num_step_pending_count << s.search(".//ol/li[@class='step pending']").size
|
|
368
|
+
@num_step_undefined_count << s.search(".//ol/li[@class='step undefined']").size
|
|
369
|
+
|
|
370
|
+
if s.search(".//ol/li/div[@class='step_name']").size == s.search(".//ol/li[@class='step skipped']").size
|
|
371
|
+
@scenario_skip_count += 1
|
|
372
|
+
elsif (s.search(".//ol/li/div[@class='step_name']").size - s.search(".//ol/li[@class='step skipped']").size) > 0
|
|
373
|
+
@scenario_skip_count += 1
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# setting colors for the scenario IDs under the feature
|
|
377
|
+
s.search("./span[@class='tag'][1]").each do |tag|
|
|
378
|
+
if cstep_fail >= 1 && break_count
|
|
379
|
+
tmp << "<span style='color:red'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
|
|
380
|
+
break_count = false
|
|
381
|
+
@fail_step_count += 1
|
|
382
|
+
elsif s.search(".//ol/li[@class='step skipped']").size >= 1
|
|
383
|
+
tmp << "<span style='color:#B0A914'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
|
|
384
|
+
else
|
|
385
|
+
tmp << "<span style='color:green'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
scenario_undefined_count = 0
|
|
390
|
+
else
|
|
391
|
+
scenario_undefined_count = 0
|
|
392
|
+
f.search("./div[@class='scenario']").each_with_index do |s, indx|
|
|
393
|
+
cstep += bstep
|
|
394
|
+
cstep_pass += bstep_pass
|
|
395
|
+
cstep_fail += bstep_fail
|
|
396
|
+
cstep_skip += bstep_skip
|
|
397
|
+
cstep_pending += bstep_pending
|
|
398
|
+
|
|
399
|
+
cstep += s.search(".//ol/li/div[@class='step_name']").size
|
|
400
|
+
cstep_pass += s.search(".//ol/li[@class='step passed']").size
|
|
401
|
+
cstep_fail += s.search(".//ol/li[@class='step failed']").size
|
|
402
|
+
cstep_skip += s.search(".//ol/li[@class='step skipped']").size
|
|
403
|
+
cstep_pending += s.search(".//ol/li[@class='step pending']").size
|
|
404
|
+
cstep_undefined += s.search(".//ol/li[@class='step undefined']").size
|
|
405
|
+
|
|
406
|
+
@num_step_count << s.search(".//ol/li/div[@class='step_name']").size + bstep
|
|
407
|
+
@num_step_pass_count << s.search(".//ol/li[@class='step passed']").size + bstep_pass
|
|
408
|
+
@num_step_fail_count << s.search(".//ol/li[@class='step failed']").size
|
|
409
|
+
@num_step_skip_count << s.search(".//ol/li[@class='step skipped']").size
|
|
410
|
+
@num_step_pending_count << s.search(".//ol/li[@class='step pending']").size
|
|
411
|
+
@num_step_undefined_count << s.search(".//ol/li[@class='step undefined']").size
|
|
412
|
+
|
|
413
|
+
# setting colors for the scenario IDs under the feature
|
|
414
|
+
s.search("./span[@class='tag'][1]").each do |tag|
|
|
415
|
+
if s.search(".//ol/li[@class='step failed']").size >= 1
|
|
416
|
+
tmp << "<span style='color:red'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
|
|
417
|
+
@fail_step_count += 1
|
|
418
|
+
elsif s.search(".//ol/li[@class='step skipped']").size >= 1
|
|
419
|
+
tmp << "<span style='color:#B0A914'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
|
|
420
|
+
else
|
|
421
|
+
tmp << "<span style='color:green'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
if s.search(".//ol/li[@class='step undefined']").size > 0
|
|
425
|
+
scenario_undefined_count += 1 if s.search(".//ol/li[@class='step failed']").size == 0
|
|
426
|
+
end
|
|
427
|
+
if s.search(".//ol/li/div[@class='step_name']").size == s.search(".//ol/li[@class='step passed']").size
|
|
428
|
+
@pass_step_count += 1
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# for getting the feature ID
|
|
434
|
+
f.search("./span[@class='tag']").each do |tag|
|
|
435
|
+
if tag.inner_text.include? FEATURE_ID_PREFIX
|
|
436
|
+
if cstep_fail >= 1
|
|
437
|
+
@arr_feature_id << "<span style='color:red'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>"
|
|
438
|
+
elsif cstep_pending >= 1
|
|
439
|
+
@arr_feature_id << "<span style='color:#B0A914'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>"
|
|
440
|
+
else
|
|
441
|
+
@arr_feature_id << "<span style='color:green'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>"
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
@scenario_pass << @pass_step_count
|
|
447
|
+
@scenario_fail << @fail_step_count
|
|
448
|
+
|
|
449
|
+
@step << cstep
|
|
450
|
+
@step_pass << cstep_pass
|
|
451
|
+
@step_fail << cstep_fail
|
|
452
|
+
@step_skip << cstep_skip
|
|
453
|
+
@step_pending << cstep_pending
|
|
454
|
+
|
|
455
|
+
if @scenario_skip_count - 1 < 0
|
|
456
|
+
@scenario_skip << 0
|
|
457
|
+
else
|
|
458
|
+
@scenario_skip << @scenario_skip_count - 1
|
|
459
|
+
end
|
|
460
|
+
@scenario_pending << cstep_pending
|
|
461
|
+
@step_undefined << cstep_undefined
|
|
462
|
+
@scenario_undefined << scenario_undefined_count
|
|
463
|
+
|
|
464
|
+
@arr_testcase_id << tmp
|
|
465
|
+
|
|
466
|
+
feature_name = f.xpath("./div[@class='scenario']/span[@class='scenario_file']").inner_text.strip
|
|
467
|
+
arr_feature_file_path = format_file_path(feature_name).split("/")
|
|
468
|
+
str_feature_name = arr_feature_file_path.pop.split(".").first
|
|
469
|
+
arr_feature_folder_name = arr_feature_file_path.pop(2)
|
|
470
|
+
html_file_name = "#{arr_feature_folder_name[0]}_#{str_feature_name}" # add stage name with fetaure file name
|
|
471
|
+
@arr_html_file_name << html_file_name
|
|
472
|
+
|
|
473
|
+
# table that summarises steps results for each scenario in the child html pages
|
|
474
|
+
@scenario_table = Nokogiri::XML::Node.new("table", @html_template1)
|
|
475
|
+
create_child_report_table_header
|
|
476
|
+
|
|
477
|
+
for i in 1..@scenario_name.size
|
|
478
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template1)
|
|
479
|
+
|
|
480
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
481
|
+
td.inner_html = "#{i}"
|
|
482
|
+
tr.add_child(td)
|
|
483
|
+
|
|
484
|
+
td = Nokogiri::XML::Node.new("td", @html_template1) # for Scenario ID
|
|
485
|
+
td.inner_html = tmp[i-1].to_s
|
|
486
|
+
tr.add_child(td)
|
|
487
|
+
|
|
488
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
489
|
+
td.inner_html = @scenario_name[i-1].gsub("Scenario:", "").to_s
|
|
490
|
+
tr.add_child(td)
|
|
491
|
+
td["width"] = "40%"
|
|
492
|
+
|
|
493
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
494
|
+
td.inner_html = @num_step_count[i-1].to_s
|
|
495
|
+
tr.add_child(td)
|
|
496
|
+
|
|
497
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
498
|
+
td.inner_html = @num_step_pass_count[i-1].to_s
|
|
499
|
+
td['style'] = "background-color: #b0f9c3;" if @num_step_pass_count[i-1] > 0 # green color
|
|
500
|
+
tr.add_child(td)
|
|
501
|
+
|
|
502
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
503
|
+
td.inner_html = @num_step_fail_count[i-1].to_s
|
|
504
|
+
td['style'] = "background-color: #fbc8d5;" if @num_step_fail_count[i-1] > 0 # red color
|
|
505
|
+
tr.add_child(td)
|
|
506
|
+
|
|
507
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
508
|
+
td.inner_html = @num_step_skip_count[i-1].to_s
|
|
509
|
+
td['style'] = "background-color: #f2f9b0;" if @num_step_skip_count[i-1] > 0 # yellow color
|
|
510
|
+
tr.add_child(td)
|
|
511
|
+
|
|
512
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
513
|
+
td.inner_html = @num_step_pending_count[i-1].to_s
|
|
514
|
+
td['style'] = "background-color: #f2f9b0;" if @num_step_pending_count[i-1] > 0 # yellow color
|
|
515
|
+
tr.add_child(td)
|
|
516
|
+
|
|
517
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
518
|
+
td.inner_html = @num_step_undefined_count[i-1].to_s
|
|
519
|
+
td['style'] = "background-color: #f2f9b0;" if @num_step_undefined_count[i-1] > 0 # yellow color
|
|
520
|
+
tr.add_child(td)
|
|
521
|
+
|
|
522
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
523
|
+
td.inner_html = @num_step_fail_count[i-1] > 0 ? "Failed" : "Passed"
|
|
524
|
+
td['style'] = @num_step_fail_count[i-1] > 0 ? "background-color: #fbc8d5;" : "background-color: #b0f9c3;"
|
|
525
|
+
tr.add_child(td)
|
|
526
|
+
|
|
527
|
+
@scenario_table.add_child(tr)
|
|
528
|
+
end
|
|
529
|
+
create_child_report_table_footer
|
|
530
|
+
@scenario_table['style'] = "width:80%; font:13px;"
|
|
531
|
+
template_header1.add_next_sibling(@scenario_table)
|
|
532
|
+
template_header1.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;}</script>")
|
|
533
|
+
@html_template1.at('table')["border"] = 2
|
|
534
|
+
@html_template1.at('table')["align"] = "center"
|
|
535
|
+
font = f.at_css "font"
|
|
536
|
+
font.add_next_sibling(@scenario_table)
|
|
537
|
+
|
|
538
|
+
# try to add report table next to the feature title, but its not working
|
|
539
|
+
#feature_header = @html_template1.at_xpath("//div[@id='cucumber-header']/div[3]/div[1]")
|
|
540
|
+
##feature_header.add_next_sibling(@scenario_table)
|
|
541
|
+
#@html_template1.xpath("//div[@id='cucumber-header']/div[3]/div[1]").each do |t|
|
|
542
|
+
# t.add_previous_sibling(@scenario_table)
|
|
543
|
+
#end
|
|
544
|
+
#@html_template1.at('table')["border"] = 2
|
|
545
|
+
#@html_template1.at('table')["align"] = "center"
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
template_header1.add_child(f) # add scenario with its steps as it is from cucumber report for this particular feature
|
|
549
|
+
6.times { template_header1.add_child("<br>") }
|
|
550
|
+
h2 = @html_template1.at_css "h2"
|
|
551
|
+
h2["style"] = "color: black;"
|
|
552
|
+
failed_step = @html_template1.at_css("//li[@class='step failed']")
|
|
553
|
+
if !failed_step.nil?
|
|
554
|
+
template_header1.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#C40D0D'); $('#cucumber-header').css('color', '#FFFFFF');</script>")
|
|
555
|
+
end
|
|
556
|
+
template_header1.xpath("//div[@id='label']/div").each do |t|
|
|
557
|
+
t.replace("<h1>#{html_file_name.gsub("_", " ").split.map(&:capitalize).join(' ')} - DETAILED REPORT</h1>")
|
|
558
|
+
end
|
|
559
|
+
template_header1.xpath("//div[@id='summary']/p[@id='duration']").each do |t|
|
|
560
|
+
t.replace("<p>") # remove duration fiels from cucumber report header
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
template_header1.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;}</script>")
|
|
564
|
+
|
|
565
|
+
File.open("#{$current_log_dir}/custom_report/detailed_report/#{html_file_name}.html", "w") do |file|
|
|
566
|
+
file.write(@html_template1)
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
@html_doc.xpath("//div[@class='feature']/div[@class='scenario']").each do |n|
|
|
570
|
+
n.replace(br)
|
|
571
|
+
end
|
|
572
|
+
rescue Exception => ex
|
|
573
|
+
$log.error("Error in creating sub report html : #{ex}")
|
|
574
|
+
exit
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# Description : creates header for report table
|
|
578
|
+
# Author : Chandra sekaran
|
|
579
|
+
#
|
|
580
|
+
def create_report_table_header
|
|
581
|
+
arr_table_header = ["Sr No"]
|
|
582
|
+
arr_table_header << "Feature ID" if ["yes", "true"].include? INCLUDE_FEATUREID_IN_REPORT.downcase
|
|
583
|
+
arr_table_header << "Scenario ID" if ["yes", "true"].include? INCLUDE_SCENARIOID_IN_REPORT.downcase
|
|
584
|
+
arr_table_header += ["Feature","Total","Passed","Failed","Skipped","Pending","Undefined","Total","Passed","Failed","Skipped","Pending","Undefined","Result"]
|
|
585
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template)
|
|
586
|
+
5.times do |col|
|
|
587
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
588
|
+
case col
|
|
589
|
+
when 1
|
|
590
|
+
td["colspan"] = "3"
|
|
591
|
+
td["colspan"] = (td["colspan"].to_i - 1).to_s if !(["yes", "true"].include?(INCLUDE_FEATUREID_IN_REPORT.downcase))
|
|
592
|
+
td["colspan"] = (td["colspan"].to_i - 1).to_s if !(["yes", "true"].include?(INCLUDE_SCENARIOID_IN_REPORT.downcase))
|
|
593
|
+
when 2
|
|
594
|
+
td["colspan"] = "6"
|
|
595
|
+
td.inner_html = "<b>Scenarios</b>"
|
|
596
|
+
td['align'] = "center"
|
|
597
|
+
when 3
|
|
598
|
+
td["colspan"] = "6"
|
|
599
|
+
td.inner_html = "<b>Steps</b>"
|
|
600
|
+
td['align'] = "center"
|
|
601
|
+
end
|
|
602
|
+
td['style'] = "background-color: #d3ecfc;"
|
|
603
|
+
tr.add_child(td)
|
|
604
|
+
end
|
|
605
|
+
@table.add_child(tr)
|
|
606
|
+
|
|
607
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template)
|
|
608
|
+
arr_table_header.each do |str_header|
|
|
609
|
+
th = Nokogiri::XML::Node.new("th", @html_template)
|
|
610
|
+
th.inner_html = "<b>#{str_header}</b>"
|
|
611
|
+
th['style'] = "background-color: #d3ecfc;" # light blue color
|
|
612
|
+
th["font"] = "size: 15px;"
|
|
613
|
+
tr.add_child(th)
|
|
614
|
+
end
|
|
615
|
+
@table.add_child(tr)
|
|
616
|
+
rescue Exception => ex
|
|
617
|
+
$log.error("Error while creating report table header : #{ex}")
|
|
618
|
+
exit
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
# Description : creates footer for report table
|
|
622
|
+
# Author : Chandra sekaran
|
|
623
|
+
#
|
|
624
|
+
def create_report_table_footer
|
|
625
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template)
|
|
626
|
+
num_col = 17
|
|
627
|
+
num_col -= 1 if !(["yes", "true"].include?(INCLUDE_FEATUREID_IN_REPORT.downcase))
|
|
628
|
+
num_col -= 1 if !(["yes", "true"].include?(INCLUDE_SCENARIOID_IN_REPORT.downcase))
|
|
629
|
+
|
|
630
|
+
bool_skip = false
|
|
631
|
+
num_col.times do |col|
|
|
632
|
+
td = Nokogiri::XML::Node.new("td", @html_template)
|
|
633
|
+
case col
|
|
634
|
+
when 1
|
|
635
|
+
if !(["yes", "true"].include?(INCLUDE_FEATUREID_IN_REPORT.downcase)) && !(["yes", "true"].include?(INCLUDE_SCENARIOID_IN_REPORT.downcase))
|
|
636
|
+
td.inner_html = "<b>Total<b>"
|
|
637
|
+
td["align"] = "right"
|
|
638
|
+
bool_skip = true
|
|
639
|
+
end
|
|
640
|
+
when 2
|
|
641
|
+
if (!(["yes", "true"].include?(INCLUDE_FEATUREID_IN_REPORT.downcase)) && (["yes", "true"].include?(INCLUDE_SCENARIOID_IN_REPORT.downcase))) || ((["yes", "true"].include?(INCLUDE_FEATUREID_IN_REPORT.downcase)) && !(["yes", "true"].include?(INCLUDE_SCENARIOID_IN_REPORT.downcase)))
|
|
642
|
+
td.inner_html = "<b>Total<b>"
|
|
643
|
+
td["align"] = "right"
|
|
644
|
+
bool_skip = true
|
|
645
|
+
end
|
|
646
|
+
when 3
|
|
647
|
+
if !bool_skip
|
|
648
|
+
td.inner_html = "<b>Total<b>"
|
|
649
|
+
td["align"] = "right"
|
|
650
|
+
end
|
|
651
|
+
when 4
|
|
652
|
+
td.inner_html = "<b>#{@tot_scenario.to_s}</b>"
|
|
653
|
+
when 5
|
|
654
|
+
td.inner_html = "<b>#{@tot_scenario_pass.to_s}</b>"
|
|
655
|
+
when 6
|
|
656
|
+
td.inner_html = "<b>#{@tot_scenario_fail.to_s}</b>"
|
|
657
|
+
when 7
|
|
658
|
+
td.inner_html = "<b>#{@tot_scenario_skip.to_s}</b>"
|
|
659
|
+
when 8
|
|
660
|
+
td.inner_html = "<b>#{@tot_scenario_pending.to_s}</b>"
|
|
661
|
+
when 9
|
|
662
|
+
td.inner_html = "<b>#{@tot_scenario_undefined.to_s}</b>"
|
|
663
|
+
when 10
|
|
664
|
+
td.inner_html = "<b>#{@tot_step.to_s}</b>"
|
|
665
|
+
when 11
|
|
666
|
+
td.inner_html = "<b>#{@tot_step_pass.to_s}<b>"
|
|
667
|
+
when 12
|
|
668
|
+
td.inner_html = "<b>#{@tot_step_fail.to_s}</b>"
|
|
669
|
+
when 13
|
|
670
|
+
td.inner_html = "<b>#{@tot_step_skip.to_s}</b>"
|
|
671
|
+
when 14
|
|
672
|
+
td.inner_html = "<b>#{@tot_step_pending.to_s}</b>"
|
|
673
|
+
when 15
|
|
674
|
+
td.inner_html = "<b>#{@tot_step_undefined.to_s}</b>"
|
|
675
|
+
end
|
|
676
|
+
td['style'] = "background-color: #d3ecfc;"
|
|
677
|
+
tr.add_child(td)
|
|
678
|
+
end
|
|
679
|
+
@table.add_child(tr)
|
|
680
|
+
rescue Exception => ex
|
|
681
|
+
$log.error("Error while creating report table footer : #{ex}")
|
|
682
|
+
exit
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
# Description : creates footer for report table for child pages
|
|
686
|
+
# Author : Chandra sekaran
|
|
687
|
+
#
|
|
688
|
+
def create_child_report_table_footer
|
|
689
|
+
begin
|
|
690
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template1)
|
|
691
|
+
10.times do |col|
|
|
692
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
693
|
+
case col
|
|
694
|
+
when 2
|
|
695
|
+
td.inner_html = "<b>Total<b>"
|
|
696
|
+
td["align"] = "right"
|
|
697
|
+
when 3
|
|
698
|
+
td.inner_html = "<b>#{@num_step_count.inject(:+).to_s}</b>"
|
|
699
|
+
when 4
|
|
700
|
+
td.inner_html = "<b>#{@num_step_pass_count.inject(:+).to_s}</b>"
|
|
701
|
+
when 5
|
|
702
|
+
td.inner_html = "<b>#{@num_step_fail_count.inject(:+).to_s}</b>"
|
|
703
|
+
when 6
|
|
704
|
+
td.inner_html = "<b>#{@num_step_skip_count.inject(:+).to_s}</b>"
|
|
705
|
+
when 7
|
|
706
|
+
td.inner_html = "<b>#{@num_step_pending_count.inject(:+).to_s}</b>"
|
|
707
|
+
when 8
|
|
708
|
+
td.inner_html = "<b>#{@num_step_undefined_count.inject(:+).to_s}</b>"
|
|
709
|
+
end
|
|
710
|
+
td['style'] = "background-color: #d3ecfc;"
|
|
711
|
+
tr.add_child(td)
|
|
712
|
+
end
|
|
713
|
+
@scenario_table.add_child(tr)
|
|
714
|
+
rescue Exception => ex
|
|
715
|
+
$log.error("Error while creating report table footer (for child pages): #{ex}")
|
|
716
|
+
exit
|
|
717
|
+
end
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
# Description : creates header for report table for child pages
|
|
721
|
+
# Author : Chandra sekaran
|
|
722
|
+
#
|
|
723
|
+
def create_child_report_table_header
|
|
724
|
+
begin
|
|
725
|
+
arr_table_header = ["Sr No","Scenario ID","Scenario Title","Total","Passed","Failed","Skipped","Pending","Undefined","Result"]
|
|
726
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template1)
|
|
727
|
+
4.times do |col|
|
|
728
|
+
td = Nokogiri::XML::Node.new("td", @html_template1)
|
|
729
|
+
case col
|
|
730
|
+
when 1
|
|
731
|
+
td["colspan"] = "2"
|
|
732
|
+
when 2
|
|
733
|
+
td["colspan"] = "6"
|
|
734
|
+
td.inner_html = "<b>Steps</b>"
|
|
735
|
+
td['align'] = "center"
|
|
736
|
+
end
|
|
737
|
+
td['style'] = "background-color: #d3ecfc;"
|
|
738
|
+
tr.add_child(td)
|
|
739
|
+
end
|
|
740
|
+
@scenario_table.add_child(tr)
|
|
741
|
+
tr = Nokogiri::XML::Node.new("tr", @html_template1)
|
|
742
|
+
arr_table_header.each do |str_header|
|
|
743
|
+
th = Nokogiri::XML::Node.new("th", @html_template1)
|
|
744
|
+
th.inner_html = "<b>#{str_header}</b>"
|
|
745
|
+
th['style'] = "background-color: #d3ecfc;" # light blue color
|
|
746
|
+
th["font"] = "size: 15px;"
|
|
747
|
+
tr.add_child(th)
|
|
748
|
+
end
|
|
749
|
+
@scenario_table.add_child(tr)
|
|
750
|
+
rescue Exception => ex
|
|
751
|
+
$log.error("Error while creating report table header for child pages : #{ex}")
|
|
752
|
+
exit
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
# Description : creates new custome html report files
|
|
757
|
+
# Author : Chandra sekaran
|
|
758
|
+
#
|
|
759
|
+
def create_custom_report
|
|
760
|
+
create_report_directory
|
|
761
|
+
@arr_file_name.each do |path| # move screenshot directory
|
|
762
|
+
path = format_file_path(path)
|
|
763
|
+
arr = path.split("/")
|
|
764
|
+
arr.pop # remove the html file name
|
|
765
|
+
path = arr.join("/")
|
|
766
|
+
Dir.glob(path).each do |file|
|
|
767
|
+
if File.directory?("#{file}/screenshot") # check if screenshot directory exists else create a new one and copy it to the recent log directory
|
|
768
|
+
create_directory("#{$current_log_dir}/custom_report/detailed_report/screenshot")
|
|
769
|
+
FileUtils.cp Dir["#{File.expand_path(file)}/screenshot/*.png"], "#{$current_log_dir}/custom_report/detailed_report/screenshot"
|
|
770
|
+
end
|
|
771
|
+
end
|
|
772
|
+
end
|
|
773
|
+
@arr_file_name.each do |path| # create sub report
|
|
774
|
+
create_sub_report(path)
|
|
775
|
+
end
|
|
776
|
+
create_main_report # create consolidated home report file
|
|
777
|
+
$log.success("Custom html report file has been generated successfully")
|
|
778
|
+
rescue Exception => ex
|
|
779
|
+
$log.error("Error in creating custom html report : #{ex}")
|
|
780
|
+
exit
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
# Description : gets the total execution duration with input data from json report file
|
|
784
|
+
# Author : Chandra sekaran
|
|
785
|
+
# Return argument :
|
|
786
|
+
# arr_build_durations : total execution time in nanoseconds
|
|
787
|
+
#
|
|
788
|
+
def get_execution_duration
|
|
789
|
+
@arr_json_report_file = get_files_absolute_path("test_result", "json", $start_time - $world.get_execution_delay_time.seconds)
|
|
790
|
+
$log.info("Report file names (json): #{@arr_json_report_file}")
|
|
791
|
+
@num_build_duration = 0
|
|
792
|
+
|
|
793
|
+
arr_build_durations = []
|
|
794
|
+
|
|
795
|
+
@arr_json_report_file.each do |path|
|
|
796
|
+
@arr_background_step_duration = []
|
|
797
|
+
file = File.read(path)
|
|
798
|
+
@json = JSON.parse(file)
|
|
799
|
+
arr_build_durations << parse_json # parse each json file and extract report data
|
|
800
|
+
end
|
|
801
|
+
arr_build_durations
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
# Description : parses the json file and calculates the total execution duration
|
|
805
|
+
# Author : Chandra sekaran
|
|
806
|
+
# Return argument :
|
|
807
|
+
# feature_duration : total execution time for each execution in nanoseconds
|
|
808
|
+
#
|
|
809
|
+
def parse_json
|
|
810
|
+
unit_build_duration = 0
|
|
811
|
+
feature_duration = 0
|
|
812
|
+
scenario_duration = 0
|
|
813
|
+
step_duration = 0
|
|
814
|
+
@json.each_with_index do |json, index| # iterate each feature
|
|
815
|
+
feature_duration = 0
|
|
816
|
+
json["elements"].each do |element|
|
|
817
|
+
# for including the first background steps duration to the first scenario background steps as Cucumber json
|
|
818
|
+
# report considers background for the first scenario and hence will have 0 duration for the background steps
|
|
819
|
+
# under first scenario and the actual duration for the background will be set for the subsequent scenarios
|
|
820
|
+
if index == 0
|
|
821
|
+
if element["keyword"] == "Background"
|
|
822
|
+
element["steps"].each do |step|
|
|
823
|
+
@arr_background_step_duration << step["result"]["duration"].to_i
|
|
824
|
+
@bool = true
|
|
825
|
+
end
|
|
826
|
+
end
|
|
827
|
+
end
|
|
828
|
+
if element["keyword"] == "Scenario" # take scenario for scenario level details
|
|
829
|
+
scenario_duration = 0
|
|
830
|
+
element["steps"].each_with_index do |step, indx| # iterate each steps of the current scenario
|
|
831
|
+
step_duration = 0
|
|
832
|
+
if (index == 0) && (indx < @arr_background_step_duration.size) && @bool
|
|
833
|
+
step_duration = @arr_background_step_duration[indx] # take duration from Background for the first scenario
|
|
834
|
+
else
|
|
835
|
+
step_duration = step["result"]["duration"].to_i # take usual duration
|
|
836
|
+
@bool = false
|
|
837
|
+
end
|
|
838
|
+
scenario_duration += step_duration
|
|
839
|
+
end
|
|
840
|
+
feature_duration += scenario_duration
|
|
841
|
+
end
|
|
842
|
+
end
|
|
843
|
+
@num_build_duration += feature_duration
|
|
844
|
+
unit_build_duration += feature_duration
|
|
845
|
+
end
|
|
846
|
+
unit_build_duration
|
|
847
|
+
rescue Exception => ex
|
|
848
|
+
$log.error("Error while parsing JSON : #{ex}")
|
|
849
|
+
exit
|
|
850
|
+
end
|
|
851
|
+
end
|
|
852
|
+
end
|