rsformat 0.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2b7ac4779747333628c16ff390b0c4a0f600628c
4
+ data.tar.gz: bec807ba30ea3aaf95184154546623404b32fc8c
5
+ SHA512:
6
+ metadata.gz: 8727322601bb1f87a41d74f1b3cebdcf59966c032492fd920401e677f188ab0ef0c475a9be726163396bd540b67f9bb4b875948a6511fa8899eb9036e511700c
7
+ data.tar.gz: 04368443999e418ce91fc88a7c2aa2e5e6a5fc650733b762e499db2861320e1239f6820e6d3478f82dd34913726e8295cbc32bb74a00611a4eb0e00d70403ee6
data/bin/helper.rb ADDED
@@ -0,0 +1,72 @@
1
+ class Helper
2
+
3
+ def initialize
4
+ getProject
5
+ getFooter
6
+ getDocument
7
+ getOutPath
8
+
9
+ config = {
10
+ "project": @project,
11
+ "footer": @footer,
12
+ "document": @document,
13
+ "outPath": @outPath
14
+ }
15
+
16
+ puts "\n\n Below is the configuration that you have set up. Please check if its Ok to proceed. "
17
+ puts "#{JSON.generate(config)}"
18
+
19
+ getConfirmation config
20
+ end
21
+
22
+ def getProject
23
+ print "project Name: "
24
+ @project = STDIN.gets.chomp.to_s
25
+ end
26
+
27
+ def getFooter
28
+ print "Footer Message: "
29
+ @footer = STDIN.gets.chomp.to_s
30
+ end
31
+
32
+ def getOutPath
33
+ print "Output Path: "
34
+ @outPath = STDIN.gets.chomp.to_s
35
+ end
36
+
37
+ def getDocument
38
+ print "Error Documentation (Y/N): "
39
+ d = STDIN.gets.chomp
40
+
41
+ if(d.to_s == "Y" || d.to_s == "y")
42
+ @document = "true"
43
+ elsif(d.to_s == "N" || d.to_s == "n")
44
+ @document = "false"
45
+ else
46
+ getDocument
47
+ end
48
+ end
49
+
50
+ def getConfirmation config
51
+ print "\n Is it Okay to proceed ? (Y/N)"
52
+
53
+ confirmation = STDIN.gets.chomp
54
+
55
+ if(confirmation.to_s == "Y" || confirmation.to_s == "y")
56
+ File.open ".sbfrc", "w" do |f|
57
+ f << JSON.generate(config)
58
+ end
59
+
60
+ puts "file .sbfrc created for your project"
61
+
62
+ elsif(confirmation.to_s == "n" || confirmation.to_s == "N")
63
+ puts "Configuration not Okay."
64
+ puts "Please run the command rsformat init, if you want to do the configuration"
65
+
66
+ else
67
+ getConfirmation config
68
+ end
69
+ end
70
+
71
+
72
+ end
data/bin/rsformat ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/ruby
2
+ require 'json'
3
+ require_relative 'helper'
4
+
5
+ @project = "SB"
6
+ @footer = ""
7
+ @document = false
8
+ @outPath = ""
9
+
10
+ allowedArgs = ["init", "--help", "init-help"]
11
+ if(ARGV.length == 1)
12
+ ARGV.each do |arg|
13
+ if(!allowedArgs.include?(arg))
14
+ puts "Unallowed argument."
15
+ puts "run rsformat --help for more information."
16
+ exit
17
+ elsif (arg == "--help")
18
+ puts "Welcome to rspec format @ShreyasBande"
19
+ puts "Usage: rsformat [--help] | [init] | [init-help]"
20
+ puts "\n\n ******************* OPTIONS **********************\n"
21
+ puts " --help You are looking at it"
22
+ puts " init Initialise your project with rsformat."
23
+ puts " init-help Lists down the options which can be used in init."
24
+ puts "\n\n ******************* USE WITH RSPEC **********************\n"
25
+ puts "While using with .rspec file :"
26
+ puts "--require 'rsformat' \n--format RsFormat\n"
27
+ puts "While using with command: "
28
+ puts "--require 'rsformat' --format RsFormat along with the rspec and spec locations"
29
+ puts "\n\n"
30
+ exit
31
+ elsif (arg == "init-help")
32
+ puts "------------------------------------"
33
+ puts "Documentation for rsformat init \n\n"
34
+ puts "********** OPTIONS *****************\n\n"
35
+ puts "1. project "
36
+ puts " - Defaults to 'SB'"
37
+ puts " - You can set your project name here. It will be displayed on the HTML report."
38
+ puts "\n"
39
+ puts "2. footer "
40
+ puts " - Defaults to blank"
41
+ puts " - You can set a footer message here. The text here will be used as footer message in the HTML report"
42
+ puts "\n"
43
+ puts "3. document "
44
+ puts " - Defaults to false"
45
+ puts " - If set as true, will display the errors/exceptions in the console"
46
+ puts " - If set as false, the errors/exceptions will not be shown in console"
47
+ puts " - Irrespective of this value, the HTML report will contain all the errors/exceptions"
48
+ puts "\n"
49
+ puts "4. outPath "
50
+ puts " - Defaults to the path from where rspec is being executed"
51
+ puts " - If set, the HTML report will be generated at the mentioned location"
52
+ puts " - Path mentioned here should be realtive path with respect to the project"
53
+ puts "\n\n************************************\n\n"
54
+ elsif (arg == "init")
55
+ begin
56
+ puts "This utility will walk you through creating a .srbfc file."
57
+ puts "It covers the items which you can configure for generating the report as per your need."
58
+ puts "If any of the options asked are left blank, default values for the same will be considered."
59
+ puts "If you want to check what are the default values which are used or what values you can provide for configuration, \nrun command rsformat init-help"
60
+ puts "\n\n"
61
+
62
+ Helper.new
63
+
64
+ rescue SystemExit, Interrupt
65
+ puts "\n\n\ninterrupted .... "
66
+ puts "Utility will exit now ... "
67
+ exit
68
+ rescue Exception => e
69
+ puts "Some error occured. Please try again."
70
+ puts e
71
+ exit
72
+ end
73
+ end
74
+ end
75
+ elsif(ARGV.length > 1)
76
+ puts "Invalid Command. Run rsformat --help for more information."
77
+ exit
78
+ end
79
+
data/lib/htmler.rb ADDED
@@ -0,0 +1,56 @@
1
+ class Htmler
2
+ def initialize summary, data, userChoice
3
+ @data = JSON.parse(data)
4
+ @summary = JSON.parse(summary)
5
+ @userData = JSON.parse(userChoice)
6
+ end
7
+
8
+ def inits
9
+ # User Choice Data to be used.
10
+ footer = @userData['footerMessage'] # Footer Message.
11
+ outPath = @userData['outPath'] # Path where to keep the generated report.
12
+ documentation = @userData['documentation'] # whether or not show the exceptions in console.
13
+ # User Data Ends ---------------------------------------------------------------------------
14
+
15
+ # Variables to be used in HTML page.
16
+ currentTime = Time.now.strftime("%A, %b %d %Y %r %z") # Time when the report is generated.
17
+ summary = @summary # Summary to be shown in header.
18
+ suits = @data # All groups data.
19
+ groupNames = @data.collect{|x| x['grpName']} # All unique group Names
20
+ # Variables end ----------------------------------------------------------------------------
21
+
22
+ path = 'rsReports' # location where the report will be generated.
23
+ if(outPath != '')
24
+ path = outPath
25
+ end
26
+
27
+ #create folders where the report will be placed.
28
+ Dir.mkdir(path) unless File.exists?(path)
29
+ Dir.mkdir(path + '/refs') unless File.exists?(path + '/refs')
30
+
31
+ # Read CSS + JS Files from source
32
+ cssFile = File.expand_path(File.dirname(__FILE__)) + "/refs/main.min.css"
33
+ jsFile = File.expand_path(File.dirname(__FILE__)) + "/refs/main.min.js"
34
+
35
+ # Write CSS file to the destination folder.
36
+ File.open path + "/refs/main.min.css", "w" do |c|
37
+ c << IO.read(cssFile)
38
+ end
39
+
40
+ # Write JS file to the destination folder.
41
+ File.open path + "/refs/main.min.js", "w" do |c|
42
+ c << IO.read(jsFile)
43
+ end
44
+
45
+ # Write HTML file to the destination folder.
46
+ templateFile = File.expand_path(File.dirname(__FILE__)) + "/index.erb"
47
+ File.open path + "/index.html", "w" do |f|
48
+ f << ERB.new(IO.read(templateFile), nil, '>', 'output').result(binding)
49
+ end
50
+
51
+ # Write summary to a file in the destination folder.
52
+ File.open path + "/summary.json", "w" do |f|
53
+ f.write summary.to_json
54
+ end
55
+ end
56
+ end
data/lib/index.erb ADDED
@@ -0,0 +1,160 @@
1
+ <html>
2
+ <head>
3
+ <title>Shreyas</title>
4
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
5
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400" rel="stylesheet">
6
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
7
+ <link href="./refs/main.min.css" rel="stylesheet">
8
+ <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
9
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
10
+ <script src="./refs/main.min.js"></script>
11
+ <script>
12
+ $(document).ready(function(){
13
+ initialise('<%= groupNames %>');
14
+ });
15
+ </script>
16
+ </head>
17
+ <body>
18
+ <div id="holder">
19
+ <nav id="menuHeader" class="navbar navbar-default">
20
+ <div>
21
+ <div class="navbar-header">
22
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
23
+ <span class="sr-only">Toggle navigation</span>
24
+ <span class="icon-bar"></span>
25
+ <span class="icon-bar"></span>
26
+ <span class="icon-bar"></span>
27
+ </button>
28
+ <a class="navbar-brand" href="#" onClick="openNav()"><i class="material-icons md-18 slideSide">dehaze</i></a>
29
+ <p class="navbar-text" ><%= summary['projectName'] %></p>
30
+ </div>
31
+ <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1" >
32
+ <ul class="nav navbar-nav navbar-right">
33
+ <li><p class="navbar-text"><i class="material-icons md-18" >timer</i> <%= summary['duration'] %></p></li>
34
+ <li><p class="navbar-text"><i class="material-icons md-18" style="color: lightgreen">folder</i> <%= summary['groupCount'] %></p></li>
35
+ <li><p class="navbar-text"><i class="material-icons md-18" style="color: dodgerblue">library_books</i> <%= summary['testCount'] %></p></li>
36
+ <li><p class="navbar-text"><i class="material-icons md-18" style="color: #4CAF50">done</i> <%= summary['passCount'] %></p></li>
37
+ <li><p class="navbar-text"><i class="material-icons md-18" style="color: red">clear</i> <%= summary['failureCount'] %></p></li>
38
+ <li><p class="navbar-text"><i class="material-icons md-18" style="color: orange">pan_tool</i> <%=summary['pendingCount'] %></p></li>
39
+ </ul>
40
+ </div>
41
+ </div>
42
+ </nav>
43
+ <div id="mainBody" class="container-fluid">
44
+ <a href="#" class="goTop" onClick="navigateToTop()" style="display: none;"><i class="material-icons">publish</i></a>
45
+ <div id="main">
46
+ <% suits.each do |suit| %>
47
+ <div id="Main_<%= suit['grpName']%>" class="suitContainer">
48
+
49
+ <div class="container">
50
+ <div class="suitTitle"><%= suit['grpName']%></div>
51
+ <div class="suitDetails">
52
+ <div>
53
+ <ul class="list-inline">
54
+ <li><i class="material-icons md-18" style="color: dodgerblue">library_books</i> <%= suit['testCount']%></li>
55
+ <li><i class="material-icons md-18" style="color: #4CAF50">done</i> <%= suit['passedCount']%> </li>
56
+ <li><i class="material-icons md-18" style="color: red">clear</i> <%= suit['failedCount']%></li>
57
+ <li><i class="material-icons md-18" style="color: orange">warning</i> <%= suit['pendingCount']%></li>
58
+ <li><i class="material-icons md-18" style="color: #333">timer</i> <%= suit['totalTimeForSuit']%></li>
59
+ <li><i class="material-icons md-18" style="color: #666">location_on</i> <%= suit['location']%></li>
60
+ </ul>
61
+ </div>
62
+ </div>
63
+ <div class="col-sm-12 testContainer" >
64
+ <% suit['grpTests'].each do |test|%>
65
+ <div class=" row testDetail">
66
+ <div id="Boundary_<%= test['status']%>_<%= test['id']%>" class="col-sm-12 testBoundary anchorDiv" onClick="showErrorDetails(<%= test['id']%>, '<%= test['status']%>')">
67
+ <%if test['status'] == 'passed' %>
68
+ <div class="col-sm-10"><i class="material-icons md-24" style="color: #4CAF50">check_circle</i> <%= test['fullName']%></div>
69
+ <% elsif test['status'] == 'failed' %>
70
+ <div class="col-sm-10"><i class="material-icons md-24" style="color: red">error</i> <%= test['fullName']%></div>
71
+ <% elsif test['status'] == 'pending' %>
72
+ <div class="col-sm-10"><i class="material-icons md-24" style="color: orange">warning</i> <%= test['fullName']%></div>
73
+ <%end %>
74
+ <div class="col-sm-2 alignRight"><%= RSpec::Core::Formatters::Helpers.format_duration(test['runtime'].round(3))%> <i class="material-icons md-24" style="color: silver;">timer</i></div>
75
+ <%if test['status'] == 'failed'|| test['status'] == 'pending' %>
76
+ <div class="col-sm-12 exceptionDiv ">
77
+ <%if test['status'] == 'failed'%>
78
+ <div class="col-sm-12"><%= test['exception']['type'].split('::')[2]%>: <%= test['exception']['message']%></div>
79
+ <%end %>
80
+ </div>
81
+ <div>
82
+ <div id="Exception_<%= test['id']%>" class="col-sm-12 exceptionDiv">
83
+ <div class="well errorInfo">
84
+ <div><i class="material-icons">keyboard_arrow_right</i> Location &nbsp; : <%= suit['location']%></div>
85
+ <div><i class="material-icons">keyboard_arrow_right</i> Line No &nbsp;&nbsp; : <%= test['lineNo']%></div>
86
+ <%if test['status'] == 'failed'%><div><i class="material-icons">keyboard_arrow_right</i> Type &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : <%= test['exception']['type']%></div><%end %>
87
+ <%if test['status'] == 'failed'%>
88
+ <div><i class="material-icons">keyboard_arrow_right</i> Message &nbsp;&nbsp; : <%= test['exception']['message']%></div>
89
+ <% elsif test['status'] == 'pending' %>
90
+ <div><i class="material-icons">keyboard_arrow_right</i> Message &nbsp;&nbsp; : <%= test['pendingMessage']%></div>
91
+ <%end %>
92
+ </div>
93
+ <%if test['status'] == 'failed'%>
94
+ <div class="well">
95
+ <div><%= test['exception']['backtrace'] %></div>
96
+ </div>
97
+ <%end %>
98
+ </div>
99
+ </div>
100
+ <%end %>
101
+ </div>
102
+ </div>
103
+ <%end %>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ <%end %>
108
+ </div>
109
+ </div>
110
+ <div class="footer">
111
+ <div class="mainFooter"><%= footer%></div>
112
+ <div class="fixedFooter">&copy; designed and built by Shreyas Bande</div> </div>
113
+
114
+ <!-- Side Menu Starts -->
115
+ <div id="slideMenu" class="sidenav">
116
+ <div>
117
+ <div class="col-sm-12 bottomBorder">
118
+ <div class="col-sm-9 sideNavHeading"><%= summary['projectName']%></div>
119
+ <div class="col-sm-3 anchorDiv" style="text-align: right;" onclick="closeNav()"><i class="material-icons md-24" style="color: red">clear</i></div>
120
+ <br/>
121
+ <div class="col-sm-12 sideNavSubHeading"><%= currentTime%></div>
122
+ </div> <!-- Main Heading Side Menu End -->
123
+ <div class="col-sm-12 bottomBorder"> <!-- Bottom Border Nav Settings starts -->
124
+ <div class="col-sm-12 navSettings">
125
+ <div class="col-sm-8 navSettingsText"><i class="material-icons md-18" style="color: #4CAF50">done</i> Show passed</div>
126
+ <div class="col-sm-4 navSettingsText anchorDiv" style="text-align: right;" onclick="toggleCheck('P')"><i id="chkPass" class="material-icons md-24" style="color: gray"></i></div>
127
+ </div>
128
+ <div class="col-sm-12 navSettings">
129
+ <div class="col-sm-8 navSettingsText"><i class="material-icons md-18" style="color: red">clear</i> Show failed</div>
130
+ <div class="col-sm-4 navSettingsText anchorDiv" style="text-align: right;" onclick="toggleCheck('F')"><i id="chkFail" class="material-icons md-24" style="color: gray"></i></div>
131
+ </div>
132
+ <div class="col-sm-12 navSettings">
133
+ <div class="col-sm-8 navSettingsText"><i class="material-icons md-18" style="color: orange">pan_tool</i> Show pending</div>
134
+ <div class="col-sm-4 navSettingsText anchorDiv" style="text-align: right;" onclick="toggleCheck('W')"><i id="chkPending" class="material-icons md-24" style="color: gray"></i></div>
135
+ </div>
136
+ </div> <!-- Bottom Border Nav Settings End -->
137
+ <div class="col-sm-12 bottomBorder"> <!-- Bottom Border Suits Names starts -->
138
+ <div>
139
+ <% suits.each do |suit| %>
140
+ <a href="#" class="col-sm-12 navSuits">
141
+
142
+ <%if suit['status'] == 'P' %>
143
+ <div class="col-sm-1 "><i class="material-icons md-18" style="color: #4CAF50">done_all</i></div>
144
+ <% elsif suit['status'] == 'F' %>
145
+ <div class="col-sm-1 "><i class="material-icons md-18" style="color: red">error</i></div>
146
+ <% elsif suit['status'] == 'W' || suit['status'] == 'FW' %>
147
+ <div class="col-sm-1 "><i class="material-icons md-18" style="color: orange">warning</i></div>
148
+ <%end %>
149
+ <div class="col-sm-10" onClick="navigateToSuit('<%= suit['grpName']%>')"><%= suit['grpName']%></div>
150
+
151
+ </a>
152
+ <%end %>
153
+ </div>
154
+ </div> <!-- Bottom Border Suits Names Ends -->
155
+ </div>
156
+ </div>
157
+ <!-- Side Menu Ends -->
158
+ </div>
159
+ </body>
160
+ </html>
data/lib/refs/main.js ADDED
@@ -0,0 +1,153 @@
1
+ function initialise(groups) {
2
+ $("#chkPass").text("radio_button_checked");
3
+ $("#chkFail").text("radio_button_checked");
4
+ $("#chkPending").text("radio_button_checked");
5
+
6
+ var suits = JSON.parse(groups);
7
+ console.log('suits: ', suits);
8
+ console.log('suits: ', suits.length);
9
+ for (i = 0; i < suits.length; i++) {
10
+ var acc = "#" + suits[i] + "Accordion"
11
+ console.log('acc: ', acc);
12
+ $(acc).text('arrow_drop_down');
13
+ }
14
+
15
+ var exceptions = $('[id^="Exception_"]').get();
16
+ for (i = 0; i < exceptions.length; i++) {
17
+ var id = "#" + exceptions[i].id;
18
+ $(id).hide();
19
+ }
20
+
21
+ $('html, body').animate({ scrollTop: 0 }, 300);
22
+ showToTopButton();
23
+ }
24
+
25
+ function showToTopButton() {
26
+ $(window).scroll(function() {
27
+ if ($(this).scrollTop() > 200) {
28
+ $('.goTop').fadeIn(500);
29
+ } else {
30
+ $('.goTop').fadeOut(500);
31
+ }
32
+ });
33
+ }
34
+
35
+ function navigateToTop() {
36
+ $('.goTop').click(function(event) {
37
+ $('html, body').animate({
38
+ scrollTop: 0
39
+ }, slow);
40
+
41
+ event.preventDefault();
42
+ })
43
+ }
44
+
45
+ function openNav() {
46
+ $("#slideMenu").width(350);
47
+ }
48
+
49
+ function closeNav() {
50
+ $("#slideMenu").width(0);
51
+ }
52
+
53
+ function toggleCheck(e) {
54
+ unCheckText = "radio_button_unchecked";
55
+ checkText = "radio_button_checked";
56
+ if (e === 'P') {
57
+ var passed = $('[id^="Boundary_passed_"]').get();
58
+ if ($("#chkPass").text() === checkText) {
59
+ $("#chkPass").text(unCheckText);
60
+ /* hide P elements*/
61
+
62
+ for (i = 0; i < passed.length; i++) {
63
+ var id = "#" + passed[i].id;
64
+ $(id).hide('slow');
65
+ }
66
+ } else {
67
+ $("#chkPass").text(checkText);
68
+ /* show P elements*/
69
+ for (i = 0; i < passed.length; i++) {
70
+ var id = "#" + passed[i].id;
71
+ $(id).show('slow');
72
+ }
73
+ }
74
+ }
75
+
76
+ if (e === 'F') {
77
+ var failed = $('[id^="Boundary_failed_"]').get();
78
+ if ($("#chkFail").text() === checkText) {
79
+ $("#chkFail").text(unCheckText);
80
+ for (i = 0; i < failed.length; i++) {
81
+ var id = "#" + failed[i].id;
82
+ $(id).hide('slow');
83
+ }
84
+ } else {
85
+ $("#chkFail").text(checkText);
86
+ for (i = 0; i < failed.length; i++) {
87
+ var id = "#" + failed[i].id;
88
+ $(id).show('slow');
89
+ }
90
+ }
91
+ }
92
+
93
+ if (e === 'W') {
94
+ var pending = $('[id^="Boundary_pending_"]').get();
95
+ if ($("#chkPending").text() === checkText) {
96
+ $("#chkPending").text(unCheckText);
97
+ for (i = 0; i < pending.length; i++) {
98
+ var id = "#" + pending[i].id;
99
+ $(id).hide('slow');
100
+ }
101
+ } else {
102
+ $("#chkPending").text(checkText);
103
+ for (i = 0; i < pending.length; i++) {
104
+ var id = "#" + pending[i].id;
105
+ $(id).show('slow');
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ function navigateToSuit(suit) {
112
+ var id = "#Main_" + suit;
113
+ var offset = 0;
114
+
115
+ if ($(id).offset().top == 110) {
116
+ offset = 60;
117
+ } else {
118
+ offset = $(id).offset().top;
119
+ }
120
+
121
+ $('html,body').animate({
122
+ scrollTop: offset
123
+ },
124
+ 'slow');
125
+ closeNav();
126
+ }
127
+
128
+ function toggleAccordion(suit) {
129
+ downArrow = 'arrow_drop_down';
130
+ upArrow = 'arrow_drop_up';
131
+ var accordion = "#" + suit + "Accordion";
132
+
133
+ if ($(accordion).text() == downArrow) {
134
+ $(accordion).text(upArrow)
135
+ } else {
136
+ $(accordion).text(downArrow)
137
+ }
138
+ }
139
+
140
+ function showErrorDetails(test, status) {
141
+ var id = "#Exception_" + test;
142
+ var bId = "#Boundary_" + test;
143
+
144
+ if (status == 'failed') {
145
+ $(bId).toggleClass("errorBoundary");
146
+ $(id).toggle();
147
+ }
148
+
149
+ if (status == 'pending') {
150
+ $(bId).toggleClass("warningBoundary");
151
+ $(id).toggle();
152
+ }
153
+ }
@@ -0,0 +1,300 @@
1
+ #mainBody,
2
+ body {
3
+ background: #F2F2F2
4
+ }
5
+
6
+ .sidenav,
7
+ .testDetail {
8
+ border-right: 1px solid #f5f5f5
9
+ }
10
+
11
+ body {
12
+ font-family: 'Open Sans', sans-serif;
13
+ height: 100%
14
+ }
15
+
16
+ #holder {
17
+ min-height: 100%;
18
+ position: relative
19
+ }
20
+
21
+ #mainBody {
22
+ padding-bottom: 100px
23
+ }
24
+
25
+ .navbar-default .navbar-collapse,
26
+ .navbar-header {
27
+ background-color: #45555D
28
+ }
29
+
30
+ .container-fluid {
31
+ background-color: #fff
32
+ }
33
+
34
+ .navbar-default .navbar-brand,
35
+ .navbar-default .navbar-text,
36
+ .slideSide,
37
+ .slideSide:active,
38
+ .slideSide:focus,
39
+ .slideSide:hover {
40
+ color: #fff
41
+ }
42
+
43
+ .material-icons {
44
+ font-family: 'Material Icons';
45
+ font-weight: 400;
46
+ font-style: normal;
47
+ font-size: 24px;
48
+ display: inline-block;
49
+ line-height: 1;
50
+ text-transform: none;
51
+ letter-spacing: normal;
52
+ word-wrap: normal;
53
+ white-space: nowrap;
54
+ direction: ltr;
55
+ -webkit-font-smoothing: antialiased;
56
+ text-rendering: optimizeLegibility;
57
+ -moz-osx-font-smoothing: grayscale;
58
+ font-feature-settings: 'liga';
59
+ vertical-align: middle
60
+ }
61
+
62
+ .material-icons.md-14 {
63
+ font-size: 14px
64
+ }
65
+
66
+ .material-icons.md-18 {
67
+ font-size: 18px
68
+ }
69
+
70
+ .material-icons.md-24 {
71
+ font-size: 24px
72
+ }
73
+
74
+ .material-icons.md-36 {
75
+ font-size: 36px
76
+ }
77
+
78
+ .material-icons.md-48 {
79
+ font-size: 48px
80
+ }
81
+
82
+ #menuHeader:after {
83
+ width: 0;
84
+ border-bottom: 4px solid silver;
85
+ -webkit-animation: transit 3s forwards;
86
+ -webkit-animation-direction: right;
87
+ animation: transit 2s forwards;
88
+ animation-direction: right
89
+ }
90
+
91
+ @-webkit-keyframes transit {
92
+ 0% {
93
+ width: 0
94
+ }
95
+ 100% {
96
+ width: 100%
97
+ }
98
+ }
99
+
100
+ @keyframes transit {
101
+ 0% {
102
+ width: 0
103
+ }
104
+ 100% {
105
+ width: 100%
106
+ }
107
+ }
108
+
109
+ .footer {
110
+ text-align: center;
111
+ bottom: 0;
112
+ padding: 10px;
113
+ left: 0;
114
+ position: absolute;
115
+ right: 0
116
+ }
117
+
118
+ .fixedFooter {
119
+ opacity: 0.2;
120
+ font-size: 12px;
121
+ color: silver
122
+ }
123
+
124
+ .mainFooter {
125
+ font-size: 15px;
126
+ color: #111
127
+ }
128
+
129
+ .suitDetails {
130
+ padding-top: 8px;
131
+ color: #111;
132
+ font-size: 12px;
133
+ text-align: left
134
+ }
135
+
136
+ .testContainer {
137
+ box-shadow: 10px 10px 5px #888
138
+ }
139
+
140
+ .suitTitle {
141
+ font-weight: 700;
142
+ font-size: 20px
143
+ }
144
+
145
+ .testDetail {
146
+ border-left: 1px solid #f5f5f5;
147
+ border-bottom: 1px solid #f5f5f5;
148
+ background: #fff
149
+ }
150
+
151
+ .testDetail:first-child {
152
+ border-top: 1px solid #f5f5f5
153
+ }
154
+
155
+ .testBoundary {
156
+ border-left: 5px solid #fff;
157
+ padding: 15px 0
158
+ }
159
+
160
+ .testBoundary:hover {
161
+ border-left: 5px solid silver
162
+ }
163
+
164
+ .errorBoundary,
165
+ .errorBoundary:hover {
166
+ border-left: 5px solid red
167
+ }
168
+
169
+ .warningBoundary,
170
+ .warningBoundary:hover {
171
+ border-left: 5px solid orange
172
+ }
173
+
174
+ .alignRight {
175
+ text-align: right
176
+ }
177
+
178
+ .alignLeft {
179
+ text-align: left
180
+ }
181
+
182
+ .suitContainer {
183
+ margin-top: 40px
184
+ }
185
+
186
+ .exceptionDiv {
187
+ padding-top: 10px;
188
+ padding-left: 27px;
189
+ color: red;
190
+ font-size: 13px
191
+ }
192
+
193
+ .well {
194
+ margin-bottom: 1px;
195
+ background-color: gray;
196
+ color: #fafad2;
197
+ font-size: 13px;
198
+ font-family: consolas;
199
+ border-radius: 0
200
+ }
201
+
202
+ .goTop,
203
+ .goTop:hover {
204
+ color: #fff;
205
+ text-decoration: none
206
+ }
207
+
208
+ .errorInfo div {
209
+ border-bottom: 1px solid #8C8C8C;
210
+ padding: 4px 0
211
+ }
212
+
213
+ .errorInfo div:last-child {
214
+ border-bottom: none
215
+ }
216
+
217
+ .goTop {
218
+ position: fixed;
219
+ bottom: 50px;
220
+ right: .5em;
221
+ background-color: rgba(0, 0, 0, .25);
222
+ font-size: 12px;
223
+ padding: 10px;
224
+ display: none;
225
+ margin: 0
226
+ }
227
+
228
+ .goTop:hover {
229
+ background-color: rgba(0, 0, 0, .6)
230
+ }
231
+
232
+ .sidenav {
233
+ height: 100%;
234
+ width: 0;
235
+ position: fixed;
236
+ z-index: 1;
237
+ top: 0;
238
+ left: 0;
239
+ background-color: #fff;
240
+ overflow-x: hidden;
241
+ padding-top: 25px;
242
+ transition: .5s
243
+ }
244
+
245
+ .bottomBorder {
246
+ border-bottom: 1px solid #f5f5f5;
247
+ margin-bottom: 10px;
248
+ padding-bottom: 10px
249
+ }
250
+
251
+ .sideNavHeading {
252
+ overflow: hidden;
253
+ font-size: 20px
254
+ }
255
+
256
+ .sideNavSubHeading {
257
+ color: silver;
258
+ font-size: 12px;
259
+ text-align: left;
260
+ font-weight: lighter
261
+ }
262
+
263
+ .navSettingsText,
264
+ .navSuits {
265
+ color: #a9a9a9;
266
+ font-size: 13px;
267
+ padding: 8px 0
268
+ }
269
+
270
+ .anchorDiv {
271
+ cursor: pointer;
272
+ cursor: hand
273
+ }
274
+
275
+ .navSettings {
276
+ background: #f5f5f5
277
+ }
278
+
279
+ .navSettings:nth-child(even) {
280
+ background-color: #fff
281
+ }
282
+
283
+ .navSuits {
284
+ display: block;
285
+ transition: .3s;
286
+ text-decoration: none
287
+ }
288
+
289
+ .navSuits:hover {
290
+ color: red
291
+ }
292
+
293
+ @media screen and (max-height:450px) {
294
+ .sidenav {
295
+ padding-top: 15px
296
+ }
297
+ .sidenav a {
298
+ font-size: 18px
299
+ }
300
+ }
@@ -0,0 +1,79 @@
1
+ function initialise(a) {
2
+ $("#chkPass").text("radio_button_checked"), $("#chkFail").text("radio_button_checked"), $("#chkPending").text("radio_button_checked");
3
+ var b = JSON.parse(a);
4
+ for (console.log("suits: ", b), console.log("suits: ", b.length), i = 0; i < b.length; i++) {
5
+ var c = "#" + b[i] + "Accordion";
6
+ console.log("acc: ", c), $(c).text("arrow_drop_down")
7
+ }
8
+ var d = $('[id^="Exception_"]').get();
9
+ for (i = 0; i < d.length; i++) {
10
+ var e = "#" + d[i].id;
11
+ $(e).hide()
12
+ }
13
+ $("html, body").animate({ scrollTop: 0 }, 300), showToTopButton()
14
+ }
15
+
16
+ function showToTopButton() { $(window).scroll(function() { $(this).scrollTop() > 200 ? $(".goTop").fadeIn(500) : $(".goTop").fadeOut(500) }) }
17
+
18
+ function navigateToTop() { $(".goTop").click(function(a) { $("html, body").animate({ scrollTop: 0 }, slow), a.preventDefault() }) }
19
+
20
+ function openNav() { $("#slideMenu").width(350) }
21
+
22
+ function closeNav() { $("#slideMenu").width(0) }
23
+
24
+ function toggleCheck(a) {
25
+ if (unCheckText = "radio_button_unchecked", checkText = "radio_button_checked", "P" === a) {
26
+ var b = $('[id^="Boundary_passed_"]').get();
27
+ if ($("#chkPass").text() === checkText)
28
+ for ($("#chkPass").text(unCheckText), i = 0; i < b.length; i++) {
29
+ var c = "#" + b[i].id;
30
+ $(c).hide("slow")
31
+ } else
32
+ for ($("#chkPass").text(checkText), i = 0; i < b.length; i++) {
33
+ var c = "#" + b[i].id;
34
+ $(c).show("slow")
35
+ }
36
+ }
37
+ if ("F" === a) {
38
+ var d = $('[id^="Boundary_failed_"]').get();
39
+ if ($("#chkFail").text() === checkText)
40
+ for ($("#chkFail").text(unCheckText), i = 0; i < d.length; i++) {
41
+ var c = "#" + d[i].id;
42
+ $(c).hide("slow")
43
+ } else
44
+ for ($("#chkFail").text(checkText), i = 0; i < d.length; i++) {
45
+ var c = "#" + d[i].id;
46
+ $(c).show("slow")
47
+ }
48
+ }
49
+ if ("W" === a) {
50
+ var e = $('[id^="Boundary_pending_"]').get();
51
+ if ($("#chkPending").text() === checkText)
52
+ for ($("#chkPending").text(unCheckText), i = 0; i < e.length; i++) {
53
+ var c = "#" + e[i].id;
54
+ $(c).hide("slow")
55
+ } else
56
+ for ($("#chkPending").text(checkText), i = 0; i < e.length; i++) {
57
+ var c = "#" + e[i].id;
58
+ $(c).show("slow")
59
+ }
60
+ }
61
+ }
62
+
63
+ function navigateToSuit(a) {
64
+ var b = "#Main_" + a,
65
+ c = 0;
66
+ c = 110 == $(b).offset().top ? 60 : $(b).offset().top, $("html,body").animate({ scrollTop: c }, "slow"), closeNav()
67
+ }
68
+
69
+ function toggleAccordion(a) {
70
+ downArrow = "arrow_drop_down", upArrow = "arrow_drop_up";
71
+ var b = "#" + a + "Accordion";
72
+ $(b).text() == downArrow ? $(b).text(upArrow) : $(b).text(downArrow)
73
+ }
74
+
75
+ function showErrorDetails(a, b) {
76
+ var c = "#Exception_" + a,
77
+ d = "#Boundary_" + b + "_" + a;
78
+ "failed" == b && ($(d).toggleClass("errorBoundary"), $(c).toggle()), "pending" == b && ($(d).toggleClass("warningBoundary"), $(c).toggle())
79
+ }
data/lib/rsformat.rb ADDED
@@ -0,0 +1,214 @@
1
+ require 'json'
2
+ require_relative 'htmler'
3
+
4
+ class RsFormat
5
+ attr_accessor :summary
6
+ RSpec::Core::Formatters.register self, :close, :example_passed, :example_failed, :example_pending, :dump_summary
7
+
8
+ def initialize y
9
+
10
+ @summary = {}
11
+ @failed = []
12
+ @groups = []
13
+ @count = 0
14
+ @groupCount = 0
15
+
16
+ @projectName = 'SB'
17
+ @footerMessage = ''
18
+ @outPath = ''
19
+ @documentation = false
20
+
21
+ if File.exist?('.sbfrc')
22
+ begin
23
+ x = JSON.parse(IO.read('.sbfrc'))
24
+ if(x.has_key? 'project')
25
+ @projectName = x['project']
26
+ end
27
+
28
+ if(x.has_key? 'footer')
29
+ @footerMessage = x['footer']
30
+ end
31
+
32
+ if(x.has_key? 'outPath')
33
+ @outPath = x['outPath']
34
+ end
35
+
36
+ if(x.has_key? 'document')
37
+ @documentation = x['document'].eql?('true') ? true : false
38
+ end
39
+ rescue
40
+ puts 'rescue block'
41
+ end
42
+ else
43
+ puts "No user specification (.sbfrc) found. Using default configuration."
44
+ end
45
+ end
46
+
47
+ def example_passed notification # ExampleNotification
48
+ test = {
49
+ name: notification.example.description,
50
+ fullName: notification.example.full_description,
51
+ status: notification.example.execution_result.status.to_s,
52
+ location: notification.example.location.split(":")[0],
53
+ lineNo: notification.example.location.split(":")[1],
54
+ runtime: notification.example.execution_result.run_time,
55
+ pendingMessage: notification.example.execution_result.pending_message,
56
+ id: @count + 1
57
+ }
58
+
59
+ addOrAppendGroup test, notification
60
+ @count = @count + 1
61
+ print "."
62
+ end
63
+
64
+ def example_failed notification # FailedExampleNotification
65
+ test = {
66
+ group: notification.example.example_group,
67
+ name: notification.example.description,
68
+ fullName: notification.example.full_description,
69
+ status: notification.example.execution_result.status.to_s,
70
+ location: notification.example.location.split(":")[0],
71
+ lineNo: notification.example.location.split(":")[1],
72
+ runtime: notification.example.execution_result.run_time,
73
+ id: @count + 1,
74
+ exception: {
75
+ type: notification.example.exception.class,
76
+ message: notification.example.execution_result.exception.message,
77
+ backtrace: notification.example.exception.backtrace
78
+ },
79
+ pendingMessage: notification.example.execution_result.pending_message
80
+ }
81
+
82
+ addOrAppendGroup test, notification
83
+ @count = @count + 1
84
+ @failed.push(test)
85
+ print "F"
86
+ end
87
+
88
+ def example_pending notification # ExampleNotification
89
+ test = {
90
+ group: notification.example.example_group,
91
+ name: notification.example.description,
92
+ fullName: notification.example.full_description,
93
+ status: notification.example.execution_result.status.to_s,
94
+ location: notification.example.location.split(":")[0],
95
+ lineNo: notification.example.location.split(":")[1],
96
+ runtime: notification.example.execution_result.run_time,
97
+ pendingMessage: notification.example.execution_result.pending_message,
98
+ id: @count + 1
99
+ }
100
+
101
+ addOrAppendGroup test, notification
102
+ @count = @count + 1
103
+ print "*"
104
+ end
105
+
106
+ def dump_summary notification # SummaryNotification
107
+ # puts "\nTesting ends ... Generating Report"
108
+ # puts "Total Tests: #{@count}"
109
+ # puts @groups.length
110
+
111
+ @summary = {
112
+ duration: RSpec::Core::Formatters::Helpers.format_duration(notification.duration.round(3)),
113
+ groupCount: @groups.length,
114
+ testCount: notification.example_count,
115
+ pendingCount: notification.pending_count,
116
+ failureCount: notification.failure_count,
117
+ passCount: notification.example_count - ( notification.pending_count + notification.failure_count),
118
+ projectName: @projectName
119
+ }
120
+
121
+ userData = {
122
+ projectName: @projectName,
123
+ footerMessage: @footerMessage,
124
+ outPath: @outPath,
125
+ documentation: @documentation
126
+ }
127
+
128
+ html = Htmler.new(JSON.generate(@summary), JSON.generate(@groups), JSON.generate(userData))
129
+ html.inits
130
+ end
131
+
132
+ def close notification # NullNotification
133
+ puts "\n"
134
+ puts "---------------------------------------------------------"
135
+ puts "Total Suits : #{@summary[:groupCount]}"
136
+ puts "Total Tests : #{@summary[:testCount]}"
137
+ puts "Total Passed : #{@summary[:passCount]}"
138
+ puts "Total Failed : #{@summary[:failureCount]}"
139
+ puts "Total Pending : #{@summary[:pendingCount]}"
140
+ puts "Total Time Taken : #{@summary[:duration]}"
141
+ puts "---------------------------------------------------------"
142
+
143
+ if(@documentation)
144
+ if(@failed.length == 0)
145
+ puts "******************* NO Exceptions found **************************"
146
+ else
147
+ puts "=====================Exceptions=========================="
148
+ cnt = 0
149
+
150
+ @failed.each do |failedTest|
151
+ exMessage = failedTest[:exception][:message].gsub("\n","")
152
+ exType = failedTest[:exception][:type]
153
+ puts "\n#{cnt + 1}. #{failedTest[:fullName]}"
154
+ puts "Exception : #{exType}"
155
+ puts "Message : #{exMessage}"
156
+ cnt = cnt + 1
157
+ puts "\n"
158
+ end
159
+ puts "========================================================="
160
+ end
161
+ end
162
+ end
163
+
164
+ def addOrAppendGroup test, notification
165
+ grps = @groups.select{|y| y[:grpName] == notification.example.example_group.to_s.split('::')[2]}
166
+ if(!grps.any?) # No entry for this group Yet.
167
+ grp = {
168
+ grpId: @groupCount + 1,
169
+ grpName: notification.example.example_group.to_s.split('::')[2],
170
+ status: notification.example.execution_result.status.to_s == "passed" ? "P" :
171
+ (notification.example.execution_result.status.to_s == "failed" ? "F" :
172
+ (notification.example.execution_result.status.to_s == "pending" ? "W" : "X")),
173
+ location: notification.example.location.split(":")[0],
174
+ totalTimeForSuit: notification.example.execution_result.run_time.round(3),
175
+ testCount: 1,
176
+ passedCount: notification.example.execution_result.status.to_s == "passed" ? 1 : 0,
177
+ failedCount: notification.example.execution_result.status.to_s == "failed" ? 1 : 0,
178
+ pendingCount: notification.example.execution_result.status.to_s == "pending" ? 1 : 0,
179
+ grpTests: [test],
180
+ }
181
+
182
+ @groups.push(grp)
183
+ @groupCount = @groupCount + 1
184
+ else
185
+ # grp status can change
186
+ if(grps[0][:status] == "P")
187
+ grps[0][:status] = notification.example.execution_result.status.to_s == "failed" ? "F" :
188
+ (notification.example.execution_result.status.to_s == "pending" ? "W" : "P")
189
+ elsif (grps[0][:status] == "F")
190
+ grps[0][:status] = notification.example.execution_result.status.to_s == "pending" ? "FW" : "F"
191
+ elsif (grps[0][:status] == "W")
192
+ grps[0][:status] = notification.example.execution_result.status.to_s == "failed" ? "FW" : "W"
193
+ end
194
+
195
+ # grp total time for suit
196
+ grps[0][:totalTimeForSuit] = (grps[0][:totalTimeForSuit] + notification.example.execution_result.run_time).round(3)
197
+
198
+ # grp test count
199
+ grps[0][:testCount] = grps[0][:testCount] + 1
200
+
201
+ # grp passed / failed / pending count
202
+ if(notification.example.execution_result.status.to_s == "passed")
203
+ grps[0][:passedCount] = grps[0][:passedCount] + 1
204
+ elsif(notification.example.execution_result.status.to_s == "failed")
205
+ grps[0][:failedCount] = grps[0][:failedCount] + 1
206
+ elsif(notification.example.execution_result.status.to_s == "pending")
207
+ grps[0][:pendingCount] = grps[0][:pendingCount] + 1
208
+ end
209
+
210
+ # grp Tests should be added.
211
+ grps[0][:grpTests].push(test)
212
+ end
213
+ end
214
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rsformat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Shreyas Bande
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.4'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.4'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-core
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.4'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 3.4.4
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '3.4'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 3.4.4
67
+ description: Formats the rspec results beautifully in html
68
+ email: shreyas.bande@abc
69
+ executables:
70
+ - rsformat
71
+ extensions: []
72
+ extra_rdoc_files: []
73
+ files:
74
+ - bin/helper.rb
75
+ - bin/rsformat
76
+ - lib/htmler.rb
77
+ - lib/index.erb
78
+ - lib/refs/main.js
79
+ - lib/refs/main.min.css
80
+ - lib/refs/main.min.js
81
+ - lib/rsformat.rb
82
+ homepage: https://github.com/ssbande/rsformat/blob/master/README.md
83
+ licenses:
84
+ - SB
85
+ metadata: {}
86
+ post_install_message: "Thanks for installing! \n\n Run rsformat --help for more information
87
+ and setting up configuration \n\n"
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.6.10
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: SB Formatter for Rspec
107
+ test_files: []