diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js
index c9aa426f..5ca93110 100644
--- a/lib/jasmine-core/jasmine-html.js
+++ b/lib/jasmine-core/jasmine-html.js
@@ -978,6 +978,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
// Sub-views
#alerts;
+ #statusBar;
#progress;
#banner;
#failures;
@@ -1012,6 +1013,9 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
this.#stateBuilder = new j$.private.ResultsStateBuilder();
this.#alerts = new j$.private.AlertsView(this.#urlBuilder);
+ this.#statusBar = new j$.private.OverallStatusBar(this.#urlBuilder);
+ this.#statusBar.showRunning();
+ this.#alerts.addBar(this.#statusBar.rootEl);
this.#progress = new ProgressView();
this.#banner = new j$.private.Banner(
this.#queryString.navigateWithNewParam.bind(this.#queryString),
@@ -1044,6 +1048,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
if (result.status === 'failed') {
this.#failures.append(result, this.#stateBuilder.currentParent);
+ this.#statusBar.showFailing();
}
}
@@ -1064,6 +1069,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
if (result.status === 'failed') {
this.#failures.append(result, this.#stateBuilder.currentParent);
+ this.#statusBar.showFailing();
}
}
@@ -1082,9 +1088,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
);
}
- const statusBar = new j$.private.OverallStatusBar(this.#urlBuilder);
- statusBar.showDone(doneResult, this.#stateBuilder);
- this.#alerts.addBar(statusBar.rootEl);
+ this.#statusBar.showDone(doneResult, this.#stateBuilder);
if (doneResult.failedExpectations) {
for (const f of doneResult.failedExpectations) {
@@ -1327,6 +1331,7 @@ jasmineRequire.OverallStatusBar = function(j$) {
'use strict';
const { createDom } = j$.private.htmlReporterUtils;
+ const staticClassNames = 'jasmine-overall-result jasmine-bar';
class OverallStatusBar {
#urlBuilder;
@@ -1334,11 +1339,25 @@ jasmineRequire.OverallStatusBar = function(j$) {
constructor(urlBuilder) {
this.#urlBuilder = urlBuilder;
this.rootEl = createDom('span', {
- className: 'jasmine-overall-result jasmine-bar'
+ className: staticClassNames,
+ 'aria-live': 'polite'
});
}
+ showRunning() {
+ this.rootEl.textContent = 'Running...';
+ this.rootEl.classList.add('jasmine-in-progress');
+ }
+
+ showFailing() {
+ this.rootEl.textContent = 'Failing...';
+ this.rootEl.classList.add('jasmine-failed');
+ }
+
showDone(doneResult, stateBuilder) {
+ // Clear any classes added to represent in-progress state
+ this.rootEl.className = staticClassNames;
+
let statusBarMessage = '';
const globalFailures =
(doneResult && doneResult.failedExpectations) || [];
diff --git a/lib/jasmine-core/jasmine.css b/lib/jasmine-core/jasmine.css
index 180ec354..9f223563 100644
--- a/lib/jasmine-core/jasmine.css
+++ b/lib/jasmine-core/jasmine.css
@@ -162,8 +162,12 @@ body {
display: block;
color: #eee;
}
+.jasmine_html-reporter .jasmine-bar.jasmine-in-progress {
+ color: #333;
+}
.jasmine_html-reporter .jasmine-bar.jasmine-failed, .jasmine_html-reporter .jasmine-bar.jasmine-errored {
background-color: #ca3a11;
+ color: #eee;
border-bottom: 1px solid #eee;
}
.jasmine_html-reporter .jasmine-bar.jasmine-passed {
diff --git a/spec/html/HtmlReporterV2Spec.js b/spec/html/HtmlReporterV2Spec.js
index 788c6e9c..d5e0b70f 100644
--- a/spec/html/HtmlReporterV2Spec.js
+++ b/spec/html/HtmlReporterV2Spec.js
@@ -1132,7 +1132,74 @@ describe('HtmlReporterV2', function() {
});
});
- describe('The overall result bar', function() {
+ describe('The overall status bar', function() {
+ describe('Before the jasmineDone event fires', function() {
+ describe('When nothing has failed', function() {
+ it('shows "Running..." and the has class jasmine-in-progress', function() {
+ const reporter = setup();
+ reporter.initialize();
+ const alertBar = container.querySelector('.jasmine-overall-result');
+
+ expect(alertBar.textContent).toEqual('Running...');
+ expect(alertBar).not.toHaveClass('jasmine-passed');
+ expect(alertBar).not.toHaveClass('jasmine-failed');
+ expect(alertBar).toHaveClass('jasmine-in-progress');
+
+ for (const status of ['passed', 'excluded', 'pending']) {
+ reporter.specDone({
+ status,
+ fullName: `Some ${status} spec`,
+ passedExpectations: [],
+ failedExpectations: []
+ });
+ }
+
+ expect(alertBar.textContent).toEqual('Running...');
+ expect(alertBar).not.toHaveClass('jasmine-passed');
+ expect(alertBar).not.toHaveClass('jasmine-failed');
+ expect(alertBar).toHaveClass('jasmine-in-progress');
+ });
+ });
+
+ describe('When a spec has failed', function() {
+ it('shows "Failing..." and the has class jasmine-failed', function() {
+ const reporter = setup();
+ reporter.initialize();
+ const alertBar = container.querySelector('.jasmine-overall-result');
+
+ reporter.specDone({
+ status: 'failed',
+ fullName: 'Some failed spec',
+ passedExpectations: [],
+ failedExpectations: []
+ });
+
+ expect(alertBar.textContent).toEqual('Failing...');
+ expect(alertBar).toHaveClass('jasmine-failed');
+ expect(alertBar).not.toHaveClass('jasmine-passed');
+ });
+ });
+
+ describe('When a suite has failed', function() {
+ it('shows "Failing..." and the has class jasmine-failed', function() {
+ const reporter = setup();
+ reporter.initialize();
+ const alertBar = container.querySelector('.jasmine-overall-result');
+
+ reporter.suiteDone({
+ status: 'failed',
+ fullName: 'Some failed suite',
+ passedExpectations: [],
+ failedExpectations: []
+ });
+
+ expect(alertBar.textContent).toEqual('Failing...');
+ expect(alertBar).toHaveClass('jasmine-failed');
+ expect(alertBar).not.toHaveClass('jasmine-passed');
+ });
+ });
+ });
+
describe("When the jasmineDone event's overallStatus is 'passed'", function() {
it('has class jasmine-passed', function() {
const reporter = setup();
diff --git a/src/html/HtmlReporterV2.js b/src/html/HtmlReporterV2.js
index f1b9b552..468f8224 100644
--- a/src/html/HtmlReporterV2.js
+++ b/src/html/HtmlReporterV2.js
@@ -30,6 +30,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
// Sub-views
#alerts;
+ #statusBar;
#progress;
#banner;
#failures;
@@ -64,6 +65,9 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
this.#stateBuilder = new j$.private.ResultsStateBuilder();
this.#alerts = new j$.private.AlertsView(this.#urlBuilder);
+ this.#statusBar = new j$.private.OverallStatusBar(this.#urlBuilder);
+ this.#statusBar.showRunning();
+ this.#alerts.addBar(this.#statusBar.rootEl);
this.#progress = new ProgressView();
this.#banner = new j$.private.Banner(
this.#queryString.navigateWithNewParam.bind(this.#queryString),
@@ -96,6 +100,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
if (result.status === 'failed') {
this.#failures.append(result, this.#stateBuilder.currentParent);
+ this.#statusBar.showFailing();
}
}
@@ -116,6 +121,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
if (result.status === 'failed') {
this.#failures.append(result, this.#stateBuilder.currentParent);
+ this.#statusBar.showFailing();
}
}
@@ -134,9 +140,7 @@ jasmineRequire.HtmlReporterV2 = function(j$) {
);
}
- const statusBar = new j$.private.OverallStatusBar(this.#urlBuilder);
- statusBar.showDone(doneResult, this.#stateBuilder);
- this.#alerts.addBar(statusBar.rootEl);
+ this.#statusBar.showDone(doneResult, this.#stateBuilder);
if (doneResult.failedExpectations) {
for (const f of doneResult.failedExpectations) {
diff --git a/src/html/OverallStatusBar.js b/src/html/OverallStatusBar.js
index 2c9a1e7c..e489f810 100644
--- a/src/html/OverallStatusBar.js
+++ b/src/html/OverallStatusBar.js
@@ -2,6 +2,7 @@ jasmineRequire.OverallStatusBar = function(j$) {
'use strict';
const { createDom } = j$.private.htmlReporterUtils;
+ const staticClassNames = 'jasmine-overall-result jasmine-bar';
class OverallStatusBar {
#urlBuilder;
@@ -9,11 +10,25 @@ jasmineRequire.OverallStatusBar = function(j$) {
constructor(urlBuilder) {
this.#urlBuilder = urlBuilder;
this.rootEl = createDom('span', {
- className: 'jasmine-overall-result jasmine-bar'
+ className: staticClassNames,
+ 'aria-live': 'polite'
});
}
+ showRunning() {
+ this.rootEl.textContent = 'Running...';
+ this.rootEl.classList.add('jasmine-in-progress');
+ }
+
+ showFailing() {
+ this.rootEl.textContent = 'Failing...';
+ this.rootEl.classList.add('jasmine-failed');
+ }
+
showDone(doneResult, stateBuilder) {
+ // Clear any classes added to represent in-progress state
+ this.rootEl.className = staticClassNames;
+
let statusBarMessage = '';
const globalFailures =
(doneResult && doneResult.failedExpectations) || [];
diff --git a/src/html/_HTMLReporter.scss b/src/html/_HTMLReporter.scss
index a742b9e2..cb5e738c 100644
--- a/src/html/_HTMLReporter.scss
+++ b/src/html/_HTMLReporter.scss
@@ -233,8 +233,13 @@ body {
display: block;
color: #eee;
+ &.jasmine-in-progress {
+ color: $text-color;
+ }
+
&.jasmine-failed, &.jasmine-errored {
background-color: $failing-color;
+ color: #eee; // Override jasmine-in-progress
border-bottom: 1px solid $page-background-color;
}