lab_bench 0.2.1 → 0.3.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.
data/README.rdoc CHANGED
@@ -22,9 +22,6 @@ Send your browser to http://localhost:9020/ then run your tests like this:
22
22
 
23
23
  == TODO
24
24
 
25
- * Buffer test events in server and replay to new browser clients so they can start "hot"
26
- * Browser should show whether it is connected to the server and reconnect if it dies
27
- * Show me test failures as they happen
28
25
  * Give me more context on the test suite (names of files being run, command line, project directory, etc)
29
26
  * Allow me to rerun a suite
30
27
  * Allow me to rerun a test
@@ -32,6 +29,7 @@ Send your browser to http://localhost:9020/ then run your tests like this:
32
29
  * Continuous rerunning of failed tests (like autotest)
33
30
  * Rerunning of failed tests when files change (like autotests)
34
31
  * Notifications for success and failure
32
+ * Limit the number of events buffered on the server
35
33
 
36
34
  == Contributing to lab_bench
37
35
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
data/assets/css/app.css CHANGED
@@ -1,6 +1,6 @@
1
1
  appstatus {
2
2
  display: block;
3
- height: 5%;
3
+ height: 40px;
4
4
  position: fixed;
5
5
  top: 0;
6
6
  left: 0;
@@ -27,9 +27,9 @@ appstatus.realtime {
27
27
  testruns {
28
28
  display: block;
29
29
  overflow-y: scroll;
30
- height: 60%;
31
30
  position: fixed;
32
- top: 6%;
31
+ top: 44px;
32
+ bottom: 163px;
33
33
  left: 0;
34
34
  right: 0;
35
35
  }
@@ -48,13 +48,14 @@ testrunsummary {
48
48
  padding-left: 25px;
49
49
  }
50
50
 
51
- testrunsummary started, testrunsummary currenttest, testrunsummary statitics {
51
+ testrunsummary started, testrunsummary statistics {
52
52
  display: block;
53
53
  }
54
54
 
55
55
  /* TODO icons for these */
56
56
  testrunsummary.Running {
57
57
  background-image: url(/images/spinner.gif);
58
+ background-color: #EDF;
58
59
  background-repeat: no-repeat;
59
60
  background-position: 3px 4px;
60
61
  }
@@ -73,7 +74,7 @@ eventlog {
73
74
  bottom: 0;
74
75
  left: 0;
75
76
  right: 0;
76
- height: 35%;
77
+ height: 160px;
77
78
  border-top: 3px solid black;
78
79
  overflow-y: scroll;
79
80
  }
@@ -94,4 +95,49 @@ testevent timestamp {
94
95
 
95
96
  testevent.testFault {
96
97
  background-color: #FFBBBB;
98
+ }
99
+
100
+ faults {
101
+ display: inline-block;
102
+ width: 45%;
103
+ top: 0px;
104
+ }
105
+
106
+ fault {
107
+ display: block;
108
+ border: 2px solid red;
109
+ background-color: red;
110
+ color: white;
111
+ padding: 3px;
112
+ margin: 5px;
113
+ border-radius: 5px;
114
+ }
115
+
116
+ fault:hover {
117
+ cursor: pointer;
118
+ }
119
+
120
+ fault:hover, fault.selected {
121
+ border-color: white;
122
+ }
123
+
124
+ /* pure state - probably should move this to data rather than html */
125
+ fault detail {
126
+ display: none;
127
+ }
128
+
129
+ /* displayed backtrace */
130
+ /* TODO nice vertical alignment (with bounding box) with matching test */
131
+ activefaultdetail {
132
+ display: block;
133
+ float: right;
134
+ width: 50%;
135
+ margin-right: 20px;
136
+ padding: 7px;
137
+ white-space: pre-wrap;
138
+ font-size: 0.9em;
139
+ font-family: Courier;
140
+ border: 2px solid white;
141
+ color: white;
142
+ background-color: black;
97
143
  }
data/assets/js/app.js CHANGED
@@ -1,23 +1,97 @@
1
1
  head.ready(function(){
2
+ var redrawTestrun = function(testrun) {
3
+ // rerender the suite based on the updated data
4
+ testrun.html(Mustache.to_html("\
5
+ <testrunsummary class='{{status}}'> \
6
+ <started> \
7
+ Test Run Started [{{timestamp}}] - {{status}} \
8
+ {{#running}} \
9
+ <currenttest>{{currentTest}}</currenttest> \
10
+ {{/running}} \
11
+ </started> \
12
+ <statistics> \
13
+ <testcount>{{testCount}} total test(s): </testcount> \
14
+ {{#hasfailures}} \
15
+ <failedcount>{{failedCount}} failure(s)</failedcount> \
16
+ {{#showfaults}} \
17
+ <a class='hideFaults' href='#'>Hide Failures</a> \
18
+ {{/showfaults}} \
19
+ {{^showfaults}} \
20
+ <a class='showFaults' href='#'>Show Failures</a> \
21
+ {{/showfaults}} \
22
+ {{/hasfailures}} \
23
+ {{^hasfailures}} \
24
+ <failedcount>no failures</failedcount> \
25
+ {{/hasfailures}} \
26
+ </statistics> \
27
+ {{#showfaults}} \
28
+ <faultpanel> \
29
+ <faults> \
30
+ {{#faults}} \
31
+ <fault {{#selected}}class='selected'{{/selected}}> \
32
+ {{test}} \
33
+ <detail>{{detail}}</detail> \
34
+ </fault> \
35
+ {{/faults}} \
36
+ </faults> \
37
+ {{#showfaultdetail}} \
38
+ <activefaultdetail>{{faultdetail}}</activefaultdetail> \
39
+ {{/showfaultdetail}} \
40
+ </faultpanel> \
41
+ {{/showfaults}} \
42
+ </testrunsummary>", testrun.data()));
43
+ };
44
+
45
+ $('testruns').delegate('a.showFaults', 'click', function(){
46
+ var testrun = $(this).closest('testrun');
47
+ testrun.data().showfaults = true;
48
+ redrawTestrun(testrun);
49
+ return false;
50
+ });
51
+
52
+ $('testruns').delegate('a.hideFaults', 'click', function(){
53
+ var testrun = $(this).closest('testrun');
54
+ testrun.data().showfaults = false;
55
+ redrawTestrun(testrun);
56
+ return false;
57
+ });
58
+
59
+ $('testruns').delegate('fault', 'click', function(){
60
+ var testrun = $(this).closest('testrun');
61
+ testrun.data().faultdetail = $(this).find('detail').html();
62
+ testrun.data().showfaultdetail = true;
63
+
64
+ // mark only this fault as selected - TODO must be a better way to do this
65
+ _.each(testrun.data().faults, function(fault) { fault.selected = false; });
66
+ var details = testrun.find('detail');
67
+ var matchingFault = _.detect(details, function(detail) { return $(detail).html() === testrun.data().faultdetail; });
68
+ var matchingFaultIdx = _.indexOf(details, matchingFault);
69
+ testrun.data().faults[matchingFaultIdx].selected = true;
70
+ redrawTestrun(testrun);
71
+
72
+ return false;
73
+ });
74
+
75
+ // TODO don't assume localhost
2
76
  var socket = new WebSocket('ws://localhost:9021/');
3
77
 
4
78
  var suites = {};
5
79
 
6
80
  var templates = {
7
81
  "Test::Unit::UI::TestRunnerMediator::STARTED":
8
- "<testevent class='suiteStarted'><timestamp>{{timestamp}}</timestamp>Test Suite Started</testevent>",
82
+ "<testevent class='suiteStarted'><timestamp>[{{timestamp}}]</timestamp>Test Suite Started</testevent>",
9
83
 
10
84
  "Test::Unit::TestCase::STARTED":
11
- "<testevent class='testStarted'><timestamp>{{timestamp}}</timestamp>Test Started: {{args}}</testevent>",
85
+ "<testevent class='testStarted'><timestamp>[{{timestamp}}]</timestamp>Test Started: {{args}}</testevent>",
12
86
 
13
87
  "FAULT":
14
- "<testevent class='testFault'><timestamp>{{timestamp}}</timestamp>{{args}}</testevent>",
88
+ "<testevent class='testFault'><timestamp>[{{timestamp}}]</timestamp>{{args}}</testevent>",
15
89
 
16
90
  "Test::Unit::TestCase::FINISHED":
17
- "<testevent class='testFinished'><timestamp>{{timestamp}}</timestamp>Test Completed: {{args}}</testevent>",
91
+ "<testevent class='testFinished'><timestamp>[{{timestamp}}]</timestamp>Test Completed: {{args}}</testevent>",
18
92
 
19
93
  "Test::Unit::UI::TestRunnerMediator::FINISHED":
20
- "<testevent class='suiteFinished'><timestamp>{{timestamp}}</timestamp>Test Suite Completed in {{args}} seconds</testevent>"
94
+ "<testevent class='suiteFinished'><timestamp>[{{timestamp}}]</timestamp>Test Suite Completed in {{args}} seconds</testevent>"
21
95
  };
22
96
 
23
97
  socket.onopen = function (e) {
@@ -59,12 +133,17 @@ head.ready(function(){
59
133
  testrunData.status = 'Initializing';
60
134
  testrunData.testCount = 0;
61
135
  testrunData.failedCount = 0;
136
+ testrunData.hasfailures = false;
137
+ testrunData.faults = [];
138
+ testrunData.showfaults = false;
62
139
  } else if (message.event === "Test::Unit::TestCase::STARTED") {
63
140
  testrunData.status = 'Running';
64
141
  testrunData.currentTest = message.args;
65
142
  testrunData.running = true;
66
143
  } else if (message.event === "FAULT") {
67
144
  testrunData.failedCount += 1;
145
+ testrunData.hasfailures = true;
146
+ testrunData.faults.push({test: testrunData.currentTest, detail: message.args});
68
147
  } else if (message.event === "Test::Unit::TestCase::FINISHED") {
69
148
  testrunData.running = false;
70
149
  testrunData.testCount += 1;
@@ -76,18 +155,7 @@ head.ready(function(){
76
155
  }
77
156
  }
78
157
 
79
- // rerender the suite based on the updated data
80
- testrun.html(Mustache.to_html("\
81
- <testrunsummary class='{{status}}'> \
82
- <started>Test Run Started {{timestamp}} - {{status}}</started> \
83
- {{#running}} \
84
- <currenttest>Current Test: {{currentTest}}</currenttest> \
85
- {{/running}} \
86
- <statistics> \
87
- <testcount>{{testCount}} total test(s)</testcount> \
88
- <failedcount>{{failedCount}} failure(s)</failedcount> \
89
- </statistics> \
90
- </testrunsummary>", testrunData));
158
+ redrawTestrun(testrun);
91
159
  }
92
160
  }
93
161
  };
data/lab_bench.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{lab_bench}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bradley Buda"]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lab_bench
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bradley Buda