nxgreport 0.10.0 → 0.11.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a070244e38842f494942ea189deba31e45360a50857946d17c11749ab10db465
4
- data.tar.gz: f903e4695cffc3a15069340f563e2ed7930d1531139ff7a4b6219786e8452649
3
+ metadata.gz: 20f1a2f039923a59eab3e9bbe4004412a43bafb78c4a5f4ce51c8ba8d3115cac
4
+ data.tar.gz: 56d2dfc8399405c0d8522ad09a923da5f5fd1dfe595bbe464410119e987ec685
5
5
  SHA512:
6
- metadata.gz: d65497235406123d769ac72f0f61b1a16ca565926911d34819ddcd8d5ea730f2363d969212e372613a9457d97a1649ed8711fc15c75ee0c619a1d34d804adec8
7
- data.tar.gz: 8eb082850d2be42ef630e83e23a68e1058182ab26ee84f8738b17d8f8964b5e45de460ee05d905fe8e15bbde41f577348055457f5da00f416b2cf542064cdc17
6
+ metadata.gz: 718711f7ae9222e6d288cb284a96cd00ff79bf6d25997fe818cc56324a77959ccf5b63a1f9c8e1893b6db7aea4bee04ec828f824d2026daa64944791b649e59f
7
+ data.tar.gz: e79dd72fe1564a1cf6a91156077d778592d7a81b543ff6ec1524cd88897784d8e0df9c10c44cf87b7b202c1b2586f4240a9af298b8802e2799930d95857572a0
data/lib/nxgreport.rb CHANGED
@@ -1,5 +1,5 @@
1
-
2
1
  require 'fileutils'
3
- require 'nxgcore.rb'
2
+ require "nxgreport/version"
3
+ require 'nxgreport/nxgcore.rb'
4
4
 
5
- $NxgReport = NxgCore.new().instance()
5
+ $NxgReport = NxgCore.new().instance()
@@ -0,0 +1,217 @@
1
+ require 'fileutils'
2
+ require 'nxgreport/nxghtml.rb'
3
+
4
+ class NxgCore
5
+ class NxgReport
6
+
7
+ include NxgHTML
8
+
9
+ def initialize(data_provider)
10
+ @data_provider = data_provider
11
+ @data_provider[:pass] = 0
12
+ @data_provider[:fail] = 0
13
+ @data_provider[:total] = 0
14
+ @data_provider[:open_on_completion] = false
15
+ @data_provider[:features] = Array.new()
16
+ @data_provider[:title] = ""
17
+ @data_provider[:report_path] = ""
18
+ @start_time = Time.now.to_f
19
+ @test_start_time = Time.now.to_f
20
+ end
21
+
22
+ def setup(location: "./NxgReport.html", title: "$NxgReport")
23
+ @data_provider[:report_path] = location.empty? ? "./NxgReport.html" : location
24
+ @data_provider[:title] = title
25
+ end
26
+
27
+ def open_upon_execution(value: true)
28
+ return if !value
29
+
30
+ @data_provider[:open_on_completion] = value
31
+ end
32
+
33
+ def set_environment(name: "")
34
+ return if name.empty?()
35
+
36
+ @data_provider[:environment] = name
37
+ end
38
+
39
+ def set_app_version(no: "")
40
+ return if no.empty?()
41
+
42
+ version_no = no.downcase.gsub("app", "").gsub("version", "").strip
43
+ @data_provider[:app_version] = "App Version #{version_no}"
44
+ end
45
+
46
+ def set_release(name: "")
47
+ return if name.empty?()
48
+
49
+ @data_provider[:release_name] = name
50
+ end
51
+
52
+ def set_os(name: "")
53
+ return if name.empty?()
54
+
55
+ @data_provider[:os] = name
56
+ end
57
+
58
+ def set_device(name: "")
59
+ return if name.empty?()
60
+
61
+ @data_provider[:device] = name
62
+ end
63
+
64
+ def set_execution(date: "")
65
+ return if date.empty?()
66
+
67
+ @data_provider[:execution_date] = date
68
+ end
69
+
70
+ def set_execution_time()
71
+ time_diff_in_mins = 0
72
+ time_diff_in_secs = 0
73
+
74
+ @data_provider[:features].each do |feature|
75
+ feature["tests"].each do |test|
76
+ time_diff_in_secs += test["time"]
77
+ end
78
+ end
79
+
80
+ time_diff_in_mins = ((time_diff_in_secs) / 60).to_i
81
+
82
+ if time_diff_in_mins >= 60
83
+ time_diff_in_hrs = (time_diff_in_mins / 60.to_f).round(2)
84
+ @data_provider[:execution_time] = "#{time_diff_in_hrs} #{time_diff_in_hrs == 1 ? "hour" : "hours"}"
85
+ else
86
+ @data_provider[:execution_time] = "#{time_diff_in_mins} mins"
87
+ end
88
+ end
89
+
90
+ def log_test(feature_name: "", test_name:"", test_status: "", tag: "", comments: "", execution_time: 0)
91
+ if feature_name.nil?() || feature_name.strip.empty?()
92
+ log("Feature name cannot be empty.")
93
+ return
94
+ end
95
+
96
+ if test_status.nil?() || test_status.strip.empty?()
97
+ log("Test status cannot be empty.")
98
+ return
99
+ end
100
+
101
+ if test_name.nil?() || test_name.strip.empty?()
102
+ log("Test name cannot be empty.")
103
+ return
104
+ end
105
+
106
+ f_name = feature_name.strip
107
+ t_name = test_name.strip
108
+ t_pass = test_status.strip.downcase.include?('pass') ? true : false
109
+ t_comments = comments.strip
110
+
111
+ if !feature_exists?(f_name)
112
+ new_feature = {
113
+ "name" => f_name,
114
+ "total" => 0,
115
+ "pass" => 0,
116
+ "fail" => 0,
117
+ "tests" => Array.new()
118
+ }
119
+ @data_provider[:features].push(new_feature)
120
+ end
121
+
122
+ update_feature(f_name, t_name, t_pass, t_comments, get_execution_time(execution_time), tag)
123
+ @data_provider[:total] += 1
124
+ @data_provider[t_pass ? :pass : :fail] += 1
125
+ end
126
+
127
+ def build()
128
+ @data_provider[:report_path] = generate_report_path() if @data_provider[:report_path].empty?()
129
+ @data_provider[:title] = "$NxgReport" if @data_provider[:title].empty?()
130
+ folder_check()
131
+ set_execution_time()
132
+ write()
133
+ if @data_provider[:open_on_completion]
134
+ system("open #{@data_provider[:report_path]}") if File.file?(@data_provider[:report_path])
135
+ end
136
+ end
137
+
138
+ # Private methods
139
+
140
+ def update_feature(f_name, t_name, t_pass, t_comments, t_execution_time, t_tag)
141
+ @data_provider[:features].each do |feature|
142
+ if feature["name"].eql?(f_name)
143
+ feature["total"]+=1
144
+ feature[t_pass ? "pass" : "fail"]+=1
145
+ feature["tests"].push({
146
+ "name" => t_name,
147
+ "testPass" => t_pass,
148
+ "comments" => t_comments,
149
+ "time" => t_execution_time,
150
+ "tag" => t_tag
151
+ })
152
+ return
153
+ end
154
+ end
155
+ end
156
+
157
+ def feature_exists?(feature_name)
158
+ @data_provider[:features].each do |feature|
159
+ return true if feature["name"].eql?(feature_name)
160
+ end
161
+ return false
162
+ end
163
+
164
+ def log(message)
165
+ puts("🤖- #{message}")
166
+ end
167
+
168
+ def folder_check()
169
+ folder = File.dirname(@data_provider[:report_path])
170
+ FileUtils.mkdir_p(folder) unless File.directory?(folder)
171
+ end
172
+
173
+ def clean()
174
+ File.delete(@data_provider[:report_path]) if File.file?(@data_provider[:report_path])
175
+ end
176
+
177
+ def write()
178
+ clean()
179
+ if @data_provider[:features].length == 0
180
+ log("No tests logged, cannot build empty report.")
181
+ return
182
+ end
183
+ template = File.new(@data_provider[:report_path], 'w')
184
+ template.puts(html(@data_provider))
185
+ template.close()
186
+ end
187
+
188
+ def generate_report_path()
189
+ report_filename = @data_provider.key?(:release_name) ? @data_provider[:release_name] : "NxgReport"
190
+ report_filename += "-#{@data_provider[:device]}" if @data_provider.key?(:device)
191
+ report_filename += "-#{@data_provider[:os]}" if @data_provider.key?(:os)
192
+ report_filename += "-#{@data_provider[:app_version]}" if @data_provider.key?(:app_version)
193
+ report_filename += "-#{@data_provider[:environment]}" if @data_provider.key?(:environment)
194
+ report_filename = report_filename.gsub(/[^0-9a-z-]/i, '')
195
+ return "./#{report_filename}.html"
196
+ end
197
+
198
+ def get_execution_time(execution_time)
199
+ if execution_time != 0
200
+ @test_start_time = Time.now.to_f
201
+ return execution_time.round()
202
+ end
203
+ @test_end_time = Time.now.to_f
204
+ execution_time = (@test_end_time - @test_start_time).round()
205
+ @test_start_time = Time.now.to_f
206
+ return execution_time
207
+ end
208
+
209
+ private :log, :clean, :write, :update_feature, :folder_check
210
+ end
211
+
212
+ private_constant :NxgReport
213
+
214
+ def instance(data_provider: Hash.new())
215
+ NxgReport.new(data_provider)
216
+ end
217
+ end
@@ -14,21 +14,21 @@ module NxgCss
14
14
  --primary-color: #fff;
15
15
  --secondary-color: #fff;
16
16
  --primary-font-color: #424242;
17
- --green: rgb(31, 172, 31);
17
+ --green: rgb(19, 143, 19);
18
18
  --red: rgb(214, 7, 7);
19
19
  --blue: rgb(0, 89, 255);
20
- --red-bg: rgba(255, 0, 0, 0.233);
20
+ --red-bg: #ff073925;
21
21
  }
22
-
22
+
23
23
  [theme=\"dark\"] {
24
24
  --background-color: #252525;
25
25
  --primary-color: #2e2e2e;
26
- --secondary-color: rgba(255, 255, 255, 0.842);
26
+ --secondary-color: #fff;
27
27
  --primary-font-color: #f9fafccb;
28
- --green: rgb(6, 207, 6);
29
- --red: rgb(228, 1, 1);
30
- --blue: rgb(91, 226, 250);
31
- --red-bg: rgba(201, 53, 53, 0.479);
28
+ --green: #15ce40;
29
+ --red: #ff073a;
30
+ --blue: #2cbcff;
31
+ --red-bg: #ff07392c;
32
32
  }
33
33
 
34
34
  * {
@@ -71,6 +71,36 @@ module NxgCss
71
71
 
72
72
  #sidebar-div {
73
73
  margin: auto;
74
+ display: grid;
75
+ grid-template-rows: 1fr auto;
76
+ place-items: center;
77
+ }
78
+
79
+ #sidebar-catergories {
80
+ width: 80%;
81
+ display: flex;
82
+ flex-wrap: wrap;
83
+ justify-content: center;
84
+ transition: opacity 0.5s ease-in-out;
85
+ transition-delay: 0.5s;
86
+ opacity: 0;
87
+ margin-top: 25px;
88
+ }
89
+
90
+ #sidebar-catergories > div {
91
+ background-color: var(--background-color);
92
+ border-radius: 1em;
93
+ margin: 0.5em 0.2em;
94
+ padding: 0.2em 0.5em;
95
+ -webkit-box-shadow: -3px 0px 5px -3px rgba(216, 216, 216, 0.75);
96
+ -moz-box-shadow: -3px 0px 5px -3px rgba(216, 216, 216, 0.75);
97
+ box-shadow: -3px 0px 5px -3px rgba(216, 216, 216, 0.75);
98
+ }
99
+
100
+ #sidebar-catergories > div > h6 {
101
+ color: var(--primary-font-color);
102
+ font-weight: normal;
103
+ font-size: 0.8em;
74
104
  }
75
105
 
76
106
  #sidebar-overlay-test-info {
@@ -101,21 +131,43 @@ module NxgCss
101
131
  height: fit-content;
102
132
  }
103
133
 
104
- #sidebar-title-wrap,
134
+ #sidebar-title-wrap {
135
+ display: grid;
136
+ grid-template-columns: 1fr auto;
137
+ place-items: center;
138
+ }
139
+
105
140
  #sidebar-overlay-test-info {
106
141
  display: flex;
107
142
  place-items: center;
108
143
  flex-wrap: wrap;
109
144
  }
145
+
146
+ #sidebar-title {
147
+ margin: 0 0.2em 0 0;
148
+ }
110
149
 
111
150
  #sidebar-title,
112
151
  #sidebar-status {
113
152
  color: var(--secondary-color);
153
+ transition: opacity 0.5s ease-in-out;
154
+ transition-delay: 0.5s;
155
+ opacity: 0;
114
156
  }
115
157
 
116
158
  #test-title {
117
159
  margin: 0;
118
160
  }
161
+
162
+ #test-execution-time {
163
+ font-size: 0.7em;
164
+ font-weight: bold;
165
+ background: var(--primary-gradient);
166
+ color: white;
167
+ padding: 0.2em 0.5em;
168
+ border-radius: 0.5em;
169
+ margin-left: 0.5em;
170
+ }
119
171
 
120
172
  h2,
121
173
  h3,
@@ -245,7 +297,7 @@ module NxgCss
245
297
  }
246
298
 
247
299
  #pt {
248
- font-size: 0.7em;
300
+ font-size: 0.8em;
249
301
  }
250
302
 
251
303
  .funcname {
@@ -0,0 +1,196 @@
1
+ require 'nxgreport/nxgcss.rb'
2
+ require 'nxgreport/nxgjs.rb'
3
+
4
+ module NxgHTML
5
+
6
+ include NxgCss
7
+ include NxgJavascript
8
+
9
+ def html(data_provider)
10
+ @data_provider = data_provider
11
+ "<html lang=\"en\">
12
+ #{head()}
13
+ #{body()}
14
+ #{js(@data_provider)}
15
+ </html>"
16
+ end
17
+
18
+ def head()
19
+ "<head>
20
+ <meta charset=\"UTF-8\" />
21
+ <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />
22
+ <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js\"></script>
23
+ <script> #{js_detect_system_dark_mode()}</script>
24
+ <title>Home | #{@data_provider[:title]}</title>
25
+ #{google_fonts_link()}
26
+ #{icons_link()}
27
+ #{css(@data_provider)}
28
+ </head>"
29
+ end
30
+
31
+ def google_fonts_link()
32
+ "<link
33
+ href=\"https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;0,800;1,300;1,400;1,600;1,700;1,800&display=swap\"
34
+ rel=\"stylesheet\"
35
+ />"
36
+ end
37
+
38
+ def icons_link()
39
+ "<link
40
+ href=\"https://fonts.googleapis.com/icon?family=Material+Icons\"
41
+ rel=\"stylesheet\"
42
+ />"
43
+ end
44
+
45
+ def body()
46
+ "<body id=\"app\" onload=\"onRefresh()\">
47
+ <div id=\"sidebar\" onclick=\"closeDetails(event)\">
48
+ <div id=\"sidebar-div\">
49
+ <div id=\"sidebar-title-wrap\">
50
+ <h1 id=\"sidebar-title\">Title</h1>
51
+ <i class=\"material-icons\" id=\"sidebar-status\">check_circle</i>
52
+ </div>
53
+ <div id=\"sidebar-catergories\">
54
+ </div>
55
+ </div>
56
+ </div>
57
+ <div id=\"sidebar-overlay\" onclick=\"closeDetails(event)\">
58
+ <div id=\"sidebar-overlay-grid\"></div>
59
+ </div>
60
+ <div id=\"body-wrap\">
61
+ #{header()}
62
+ #{config()}
63
+ #{features()}
64
+ #{footer()}
65
+ </div>
66
+ </body>"
67
+ end
68
+
69
+ def header()
70
+ "<div id=\"header\">
71
+ <h1 id=\"app-title\">#{@data_provider[:title]}</h1>
72
+ <div id=\"theme-wrap\">
73
+ <button id=\"theme-switch\" onclick=\"switchTheme()\">
74
+ <i class=\"material-icons\" id=\"theme-icon\">wb_sunny</i>
75
+ </button>
76
+ </div>
77
+ </div>"
78
+ end
79
+
80
+ def features()
81
+ "<div class=\"features-grid\"></div>"
82
+ end
83
+
84
+ def footer()
85
+ "<div id=\"footer\">
86
+ <p>
87
+ Developed by
88
+ <span>
89
+ <a
90
+ href=\"https://www.linkedin.com/in/balabharathijayaraman\"
91
+ rel=\"noopener\"
92
+ target=\"_blank\"
93
+ >Balabharathi Jayaraman</a
94
+ >
95
+ </span>
96
+ </p>
97
+ </div>"
98
+ end
99
+
100
+ def config()
101
+ return if @data_provider.length == 0
102
+
103
+ return "<div class=\"params-container\">
104
+ #{release_name()}
105
+ #{execution_date()}
106
+ #{device()}
107
+ #{os()}
108
+ #{app_version()}
109
+ #{environment()}
110
+ #{passed_tests()}
111
+ #{failed_tests()}
112
+ #{percentage_pass()}
113
+ #{execution_time()}
114
+ #{filter()}
115
+ </div>"
116
+ end
117
+
118
+ def execution_time()
119
+ return if !@data_provider.key?(:environment)
120
+
121
+ return config_item("Total execution time", @data_provider[:execution_time],'access_time')
122
+ end
123
+
124
+ def filter()
125
+ "<div class=\"param-wrap\" onclick=\"setFilter()\" id=\"filter\" title=\"Filter tests\">
126
+ <i class=\"pi material-icons\">filter_list</i>
127
+ <h5 id=\"pt\">Failed</h5>
128
+ </div>"
129
+ end
130
+
131
+ def passed_tests()
132
+ "<div class=\"param-wrap\" title=\"Passed tests\">
133
+ <i class=\"pi green-font material-icons\">check_circle</i>
134
+ <h5 id=\"pt\">#{@data_provider[:pass] == 0 ? "None" : @data_provider[:pass]}</h5>
135
+ </div>"
136
+ end
137
+
138
+ def failed_tests()
139
+ "<div class=\"param-wrap\" title=\"Failed tests\" #{@data_provider[:fail] > 0 ? "onclick=\"filterAllFailed()\" style=\"cursor: pointer\"" : ""}>
140
+ <i class=\"pi red-font material-icons\">cancel</i>
141
+ <h5 id=\"pt\">#{@data_provider[:fail] == 0 ? "None" : @data_provider[:fail]}</h5>
142
+ </div>"
143
+ end
144
+
145
+ def percentage_pass()
146
+ pass_percentage = ((@data_provider[:pass]/@data_provider[:total].to_f) * 100).round(2)
147
+
148
+ return "<div class=\"param-wrap\" title=\"Pass percentage\">
149
+ <i class=\"pi #{pass_percentage.to_i == 100 ? "green-font" : ""} material-icons\">equalizer</i>
150
+ <h5 id=\"pt\">#{pass_percentage.to_i == 100 ? pass_percentage.to_i : pass_percentage}%</h5>
151
+ </div>"
152
+ end
153
+
154
+ def environment()
155
+ return if !@data_provider.key?(:environment)
156
+
157
+ return config_item("Test environment", @data_provider[:environment], "layers")
158
+ end
159
+
160
+ def app_version()
161
+ return if !@data_provider.key?(:app_version)
162
+
163
+ return config_item("App version tested", @data_provider[:app_version], "info")
164
+ end
165
+
166
+ def release_name()
167
+ return if !@data_provider.key?(:release_name)
168
+
169
+ return config_item("Release", @data_provider[:release_name], "bookmark")
170
+ end
171
+
172
+ def os()
173
+ return if !@data_provider.key?(:os)
174
+
175
+ return config_item("Os tested", @data_provider[:os], "settings")
176
+ end
177
+
178
+ def device()
179
+ return if !@data_provider.key?(:device)
180
+
181
+ return config_item("Device tested", @data_provider[:device], "devices")
182
+ end
183
+
184
+ def execution_date()
185
+ @data_provider[:execution_date] = Time.now().strftime("%b %d, %Y") if !@data_provider.key?(:execution_date)
186
+
187
+ return config_item("Execution date", @data_provider[:execution_date], "event")
188
+ end
189
+
190
+ def config_item(toot_tip, name, icon)
191
+ "<div class=\"param-wrap\" title=\"#{toot_tip}\">
192
+ <i class=\"pi material-icons\">#{icon}</i>
193
+ <h5 id=\"pt\">#{name}</h5>
194
+ </div>"
195
+ end
196
+ end