diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js index a0b06394..157f7e85 100644 --- a/lib/jasmine-core/jasmine-html.js +++ b/lib/jasmine-core/jasmine-html.js @@ -78,6 +78,7 @@ jasmine.HtmlReporter = function(_doc) { createReporterDom(runner.env.versionString()); doc.body.appendChild(dom.reporter); + setExceptionHandling(); reporterView = new jasmine.HtmlReporter.ReporterView(dom); reporterView.addSpecs(specs, self.specFilter); @@ -131,7 +132,7 @@ jasmine.HtmlReporter = function(_doc) { } var paramMap = []; - var params = doc.location.search.substring(1).split('&'); + var params = jasmine.HtmlReporter.parameters(doc); for (var i = 0; i < params.length; i++) { var p = params[i].split('='); @@ -151,14 +152,78 @@ jasmine.HtmlReporter = function(_doc) { self.createDom('span', { className: 'version' }, version)), dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}), - dom.alert = self.createDom('div', {className: 'alert'}), + dom.alert = self.createDom('div', {className: 'alert'}, + self.createDom('span', { className: 'exceptions' }, + self.createDom('label', { className: 'label', for: 'no_try_catch' }, 'No try/catch'), + self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))), dom.results = self.createDom('div', {className: 'results'}, dom.summary = self.createDom('div', { className: 'summary' }), dom.details = self.createDom('div', { id: 'details' })) ); } + + function noTryCatch() { + return window.location.search.match(/catch=false/); + } + + function searchWithCatch() { + var params = jasmine.HtmlReporter.parameters(window.document); + var removed = false; + var i = 0; + + while (!removed && i < params.length) { + if (params[i].match(/catch=/)) { + params.splice(i, 1); + removed = true; + } + i++; + } + if (jasmine.CATCH_EXCEPTIONS) { + params.push("catch=false"); + } + + return params.join("&"); + } + + function setExceptionHandling() { + var chxCatch = document.getElementById('no_try_catch'); + + if (noTryCatch()) { + chxCatch.setAttribute('checked', true); + jasmine.CATCH_EXCEPTIONS = false; + } + chxCatch.onclick = function() { + window.location.search = searchWithCatch(); + }; + } }; -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) { +jasmine.HtmlReporter.parameters = function(doc) { + var paramStr = doc.location.search.substring(1); + var params = []; + + if (paramStr.length > 0) { + params = paramStr.split('&'); + } + return params; +} +jasmine.HtmlReporter.sectionLink = function(sectionName) { + var link = '?'; + var params = []; + + if (sectionName) { + params.push('spec=' + encodeURIComponent(sectionName)); + } + if (!jasmine.CATCH_EXCEPTIONS) { + params.push("catch=false"); + } + if (params.length > 0) { + link += params.join("&"); + } + + return link; +}; +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter); +jasmine.HtmlReporter.ReporterView = function(dom) { this.startedAt = new Date(); this.runningSpecCount = 0; this.completeSpecCount = 0; @@ -241,14 +306,14 @@ jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporte // currently running UI if (isUndefined(this.runningAlert)) { - this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"}); + this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" }); dom.alert.appendChild(this.runningAlert); } this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount); // skipped specs UI if (isUndefined(this.skippedAlert)) { - this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"}); + this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" }); } this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; @@ -259,7 +324,7 @@ jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporte // passing specs UI if (isUndefined(this.passedAlert)) { - this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"}); + this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" }); } this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount); @@ -331,11 +396,11 @@ jasmine.HtmlReporter.SpecView = function(spec, dom, views) { this.dom.symbolSummary.appendChild(this.symbol); this.summary = this.createDom('div', { className: 'specSummary' }, - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(this.spec.getFullName()), - title: this.spec.getFullName() - }, this.spec.description) + this.createDom('a', { + className: 'description', + href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()), + title: this.spec.getFullName() + }, this.spec.description) ); this.detail = this.createDom('div', { className: 'specDetail' }, @@ -406,7 +471,7 @@ jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.Ht this.views = views; this.element = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description) + this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description) ); this.appendToSummary(this.suite, this.element); diff --git a/lib/jasmine-core/jasmine.css b/lib/jasmine-core/jasmine.css index 826e5753..8c008dc7 100644 --- a/lib/jasmine-core/jasmine.css +++ b/lib/jasmine-core/jasmine.css @@ -19,6 +19,7 @@ body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } #HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } #HTMLReporter .symbolSummary li.pending { line-height: 11px; } #HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } +#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } #HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } #HTMLReporter .runningAlert { background-color: #666666; } #HTMLReporter .skippedAlert { background-color: #aaaaaa; } diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 03bf89a0..6bac2236 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -39,6 +39,13 @@ jasmine.DEFAULT_UPDATE_INTERVAL = 250; */ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; +/** + * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite. + * Set to false to let the exception bubble up in the browser. + * + */ +jasmine.CATCH_EXCEPTIONS = true; + jasmine.getGlobal = function() { function getGlobal() { return this; @@ -1019,11 +1026,16 @@ jasmine.Block = function(env, func, spec) { this.spec = spec; }; -jasmine.Block.prototype.execute = function(onComplete) { - try { +jasmine.Block.prototype.execute = function(onComplete) { + if (!jasmine.CATCH_EXCEPTIONS) { this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); + } + else { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } } onComplete(); }; @@ -2525,5 +2537,5 @@ jasmine.version_= { "major": 1, "minor": 2, "build": 0, - "revision": 1337005947 + "revision": 1337006083 }; diff --git a/spec/core/ExceptionsSpec.js b/spec/core/ExceptionsSpec.js index fcd51eeb..315aa1bf 100644 --- a/spec/core/ExceptionsSpec.js +++ b/spec/core/ExceptionsSpec.js @@ -32,118 +32,144 @@ describe('Exceptions:', function() { expect(jasmine.util.formatException(sampleWebkitException)).toEqual(expected); }); - it('should handle exceptions thrown, but continue', function() { - var fakeTimer = new jasmine.FakeTimer(); - env.setTimeout = fakeTimer.setTimeout; - env.clearTimeout = fakeTimer.clearTimeout; - env.setInterval = fakeTimer.setInterval; - env.clearInterval = fakeTimer.clearInterval; - - //we run two exception tests to make sure we continue after throwing an exception - var suite = env.describe('Suite for handles exceptions', function () { - env.it('should be a test that fails because it throws an exception', function() { - throw new Error('fake error 1'); - }); - - env.it('should be another test that fails because it throws an exception', function() { - this.runs(function () { - throw new Error('fake error 2'); + describe('with break on exception', function() { + it('should not catch the exception', function() { + var suite = env.describe('suite for break on exceptions', function() { + env.it('should break when an exception is thrown', function() { + throw new Error('I should hit a breakpoint!'); }); - this.runs(function () { + }); + var runner = env.currentRunner(); + var dont_change = 'I will never change!'; + + var oldCatch = jasmine.CATCH_EXCEPTIONS; + jasmine.CATCH_EXCEPTIONS = false; + try { + suite.execute(); + dont_change = 'oops I changed'; + } + catch (e) {} + finally { + jasmine.CATCH_EXCEPTIONS = oldCatch; + } + + expect(dont_change).toEqual('I will never change!'); + }); + }); + + describe("with catch on exception", function() { + it('should handle exceptions thrown, but continue', function() { + var fakeTimer = new jasmine.FakeTimer(); + env.setTimeout = fakeTimer.setTimeout; + env.clearTimeout = fakeTimer.clearTimeout; + env.setInterval = fakeTimer.setInterval; + env.clearInterval = fakeTimer.clearInterval; + + //we run two exception tests to make sure we continue after throwing an exception + var suite = env.describe('Suite for handles exceptions', function () { + env.it('should be a test that fails because it throws an exception', function() { + throw new Error('fake error 1'); + }); + + env.it('should be another test that fails because it throws an exception', function() { + this.runs(function () { + throw new Error('fake error 2'); + }); + this.runs(function () { + this.expect(true).toEqual(true); + }); + }); + + env.it('should be a passing test that runs after exceptions are thrown', function() { + this.expect(true).toEqual(true); + }); + + env.it('should be another test that fails because it throws an exception after a wait', function() { + this.runs(function () { + var foo = 'foo'; + }); + this.waits(250); + this.runs(function () { + throw new Error('fake error 3'); + }); + }); + + env.it('should be a passing test that runs after exceptions are thrown from a async test', function() { this.expect(true).toEqual(true); }); }); - env.it('should be a passing test that runs after exceptions are thrown', function() { - this.expect(true).toEqual(true); - }); + var runner = env.currentRunner(); + suite.execute(); + fakeTimer.tick(2500); - env.it('should be another test that fails because it throws an exception after a wait', function() { - this.runs(function () { - var foo = 'foo'; - }); - this.waits(250); - this.runs(function () { - throw new Error('fake error 3'); - }); - }); + var suiteResults = suite.results(); + var specResults = suiteResults.getItems(); - env.it('should be a passing test that runs after exceptions are thrown from a async test', function() { - this.expect(true).toEqual(true); - }); + expect(suiteResults.passed()).toEqual(false); + // + expect(specResults.length).toEqual(5); + expect(specResults[0].passed()).toMatch(false); + var blockResults = specResults[0].getItems(); + expect(blockResults[0].passed()).toEqual(false); + expect(blockResults[0].message).toMatch(/fake error 1/); + + expect(specResults[1].passed()).toEqual(false); + blockResults = specResults[1].getItems(); + expect(blockResults[0].passed()).toEqual(false); + expect(blockResults[0].message).toMatch(/fake error 2/); + expect(blockResults[1].passed()).toEqual(true); + + expect(specResults[2].passed()).toEqual(true); + + expect(specResults[3].passed()).toEqual(false); + blockResults = specResults[3].getItems(); + expect(blockResults[0].message).toMatch(/fake error 3/); + + expect(specResults[4].passed()).toEqual(true); }); - var runner = env.currentRunner(); - suite.execute(); - fakeTimer.tick(2500); - - var suiteResults = suite.results(); - var specResults = suiteResults.getItems(); - - expect(suiteResults.passed()).toEqual(false); - // - expect(specResults.length).toEqual(5); - expect(specResults[0].passed()).toMatch(false); - var blockResults = specResults[0].getItems(); - expect(blockResults[0].passed()).toEqual(false); - expect(blockResults[0].message).toMatch(/fake error 1/); - - expect(specResults[1].passed()).toEqual(false); - blockResults = specResults[1].getItems(); - expect(blockResults[0].passed()).toEqual(false); - expect(blockResults[0].message).toMatch(/fake error 2/); - expect(blockResults[1].passed()).toEqual(true); - - expect(specResults[2].passed()).toEqual(true); - - expect(specResults[3].passed()).toEqual(false); - blockResults = specResults[3].getItems(); - expect(blockResults[0].message).toMatch(/fake error 3/); - - expect(specResults[4].passed()).toEqual(true); - }); - - - it("should handle exceptions thrown directly in top-level describe blocks and continue", function () { - var suite = env.describe("a top level describe block that throws an exception", function () { - env.it("is a test that should pass", function () { + it("should handle exceptions thrown directly in top-level describe blocks and continue", function () { + var suite = env.describe("a top level describe block that throws an exception", function () { + env.it("is a test that should pass", function () { this.expect(true).toEqual(true); - }); + }); - throw new Error("top level error"); - }); + throw new Error("top level error"); + }); - suite.execute(); - var suiteResults = suite.results(); - var specResults = suiteResults.getItems(); + suite.execute(); + var suiteResults = suite.results(); + var specResults = suiteResults.getItems(); - expect(suiteResults.passed()).toEqual(false); - expect(specResults.length).toEqual(2); + expect(suiteResults.passed()).toEqual(false); + expect(specResults.length).toEqual(2); - expect(specResults[1].description).toMatch(/encountered a declaration exception/); - }); + expect(specResults[1].description).toMatch(/encountered a declaration exception/); + }); - it("should handle exceptions thrown directly in nested describe blocks and continue", function () { - var suite = env.describe("a top level describe", function () { - env.describe("a mid-level describe that throws an exception", function () { - env.it("is a test that should pass", function () { - this.expect(true).toEqual(true); - }); + it("should handle exceptions thrown directly in nested describe blocks and continue", function () { + var suite = env.describe("a top level describe", function () { + env.describe("a mid-level describe that throws an exception", function () { + env.it("is a test that should pass", function () { + this.expect(true).toEqual(true); + }); - throw new Error("a mid-level error"); - }); - }); + throw new Error("a mid-level error"); + }); + }); - suite.execute(); - var suiteResults = suite.results(); - var specResults = suiteResults.getItems(); + suite.execute(); + var suiteResults = suite.results(); + var specResults = suiteResults.getItems(); - expect(suiteResults.passed()).toEqual(false); - expect(specResults.length).toEqual(1); + expect(suiteResults.passed()).toEqual(false); + expect(specResults.length).toEqual(1); - var nestedSpecResults = specResults[0].getItems(); + var nestedSpecResults = specResults[0].getItems(); - expect(nestedSpecResults.length).toEqual(2); - expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/); - }); -}); \ No newline at end of file + expect(nestedSpecResults.length).toEqual(2); + expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/); + }); + }); +}); diff --git a/src/core/Block.js b/src/core/Block.js index b24221e1..8085095d 100644 --- a/src/core/Block.js +++ b/src/core/Block.js @@ -12,11 +12,16 @@ jasmine.Block = function(env, func, spec) { this.spec = spec; }; -jasmine.Block.prototype.execute = function(onComplete) { - try { +jasmine.Block.prototype.execute = function(onComplete) { + if (!jasmine.CATCH_EXCEPTIONS) { this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); + } + else { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } } onComplete(); }; diff --git a/src/core/base.js b/src/core/base.js index 3a61b3d8..a4afea98 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -39,6 +39,13 @@ jasmine.DEFAULT_UPDATE_INTERVAL = 250; */ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; +/** + * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite. + * Set to false to let the exception bubble up in the browser. + * + */ +jasmine.CATCH_EXCEPTIONS = true; + jasmine.getGlobal = function() { function getGlobal() { return this; diff --git a/src/html/HtmlReporter.js b/src/html/HtmlReporter.js index b69fc9d1..b5d062b8 100644 --- a/src/html/HtmlReporter.js +++ b/src/html/HtmlReporter.js @@ -18,6 +18,7 @@ jasmine.HtmlReporter = function(_doc) { createReporterDom(runner.env.versionString()); doc.body.appendChild(dom.reporter); + setExceptionHandling(); reporterView = new jasmine.HtmlReporter.ReporterView(dom); reporterView.addSpecs(specs, self.specFilter); @@ -71,7 +72,7 @@ jasmine.HtmlReporter = function(_doc) { } var paramMap = []; - var params = doc.location.search.substring(1).split('&'); + var params = jasmine.HtmlReporter.parameters(doc); for (var i = 0; i < params.length; i++) { var p = params[i].split('='); @@ -91,11 +92,74 @@ jasmine.HtmlReporter = function(_doc) { self.createDom('span', { className: 'version' }, version)), dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}), - dom.alert = self.createDom('div', {className: 'alert'}), + dom.alert = self.createDom('div', {className: 'alert'}, + self.createDom('span', { className: 'exceptions' }, + self.createDom('label', { className: 'label', for: 'no_try_catch' }, 'No try/catch'), + self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))), dom.results = self.createDom('div', {className: 'results'}, dom.summary = self.createDom('div', { className: 'summary' }), dom.details = self.createDom('div', { id: 'details' })) ); } + + function noTryCatch() { + return window.location.search.match(/catch=false/); + } + + function searchWithCatch() { + var params = jasmine.HtmlReporter.parameters(window.document); + var removed = false; + var i = 0; + + while (!removed && i < params.length) { + if (params[i].match(/catch=/)) { + params.splice(i, 1); + removed = true; + } + i++; + } + if (jasmine.CATCH_EXCEPTIONS) { + params.push("catch=false"); + } + + return params.join("&"); + } + + function setExceptionHandling() { + var chxCatch = document.getElementById('no_try_catch'); + + if (noTryCatch()) { + chxCatch.setAttribute('checked', true); + jasmine.CATCH_EXCEPTIONS = false; + } + chxCatch.onclick = function() { + window.location.search = searchWithCatch(); + }; + } }; -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter); \ No newline at end of file +jasmine.HtmlReporter.parameters = function(doc) { + var paramStr = doc.location.search.substring(1); + var params = []; + + if (paramStr.length > 0) { + params = paramStr.split('&'); + } + return params; +} +jasmine.HtmlReporter.sectionLink = function(sectionName) { + var link = '?'; + var params = []; + + if (sectionName) { + params.push('spec=' + encodeURIComponent(sectionName)); + } + if (!jasmine.CATCH_EXCEPTIONS) { + params.push("catch=false"); + } + if (params.length > 0) { + link += params.join("&"); + } + + return link; +}; +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter); diff --git a/src/html/ReporterView.js b/src/html/ReporterView.js index 6a6d0056..419accec 100644 --- a/src/html/ReporterView.js +++ b/src/html/ReporterView.js @@ -81,14 +81,14 @@ jasmine.HtmlReporter.ReporterView = function(dom) { // currently running UI if (isUndefined(this.runningAlert)) { - this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"}); + this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" }); dom.alert.appendChild(this.runningAlert); } this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount); // skipped specs UI if (isUndefined(this.skippedAlert)) { - this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"}); + this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" }); } this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; @@ -99,7 +99,7 @@ jasmine.HtmlReporter.ReporterView = function(dom) { // passing specs UI if (isUndefined(this.passedAlert)) { - this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"}); + this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" }); } this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount); diff --git a/src/html/SpecView.js b/src/html/SpecView.js index 8769bb84..b9bcf08a 100644 --- a/src/html/SpecView.js +++ b/src/html/SpecView.js @@ -7,11 +7,11 @@ jasmine.HtmlReporter.SpecView = function(spec, dom, views) { this.dom.symbolSummary.appendChild(this.symbol); this.summary = this.createDom('div', { className: 'specSummary' }, - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(this.spec.getFullName()), - title: this.spec.getFullName() - }, this.spec.description) + this.createDom('a', { + className: 'description', + href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()), + title: this.spec.getFullName() + }, this.spec.description) ); this.detail = this.createDom('div', { className: 'specDetail' }, diff --git a/src/html/SuiteView.js b/src/html/SuiteView.js index 19a1efaf..a7f433f5 100644 --- a/src/html/SuiteView.js +++ b/src/html/SuiteView.js @@ -4,7 +4,7 @@ jasmine.HtmlReporter.SuiteView = function(suite, dom, views) { this.views = views; this.element = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description) + this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description) ); this.appendToSummary(this.suite, this.element); diff --git a/src/html/_HTMLReporter.scss b/src/html/_HTMLReporter.scss index 8abbddf2..04f42cca 100644 --- a/src/html/_HTMLReporter.scss +++ b/src/html/_HTMLReporter.scss @@ -136,167 +136,174 @@ body { } } } - + + .exceptions { + color: #fff; + float: right; + margin-top: 5px; + margin-right: 5px; + } + //--- Alert ---// - + .bar { line-height: $line-height * 2; font-size: $large-font-size; - + display: block; color: #eee; } - + .runningAlert { background-color: $light-text-color; } - + .skippedAlert { background-color: $feint-text-color; - + &:first-child { background-color: $text-color; } - + &:hover { text-decoration: none; color: white; text-decoration: underline; } } - + .passingAlert { background-color: $light-passing-color; - + &:first-child { background-color: $passing-color; } } - + .failingAlert { background-color: $light-failing-color; - + &:first-child { background-color: $failing-color } } //--- Results ---// - + .results { margin-top: $line-height; } //--- Results menu ---// - + #details { display: none; } - + .resultsMenu, .resultsMenu a { background-color: #fff; color: $text-color; } - + &.showDetails { - + .summaryMenuItem { font-weight: normal; text-decoration: inherit; - + &:hover { text-decoration: underline; } } - + .detailsMenuItem { font-weight: bold; - text-decoration: underline; + text-decoration: underline; } - + .summary { display: none; } - + #details { display: block; } } - - .summaryMenuItem { + + .summaryMenuItem { font-weight: bold; text-decoration: underline; } - + //--- Results summary ---// - + .summary { margin-top: $margin-unit; - + .suite .suite, .specSummary { margin-left: $margin-unit; } - + .specSummary { &.passed a { - color: $passing-color; + color: $passing-color; } &.failed a { color: $failing-color; } } } - + .description+.suite { margin-top: 0; } - + .suite { margin-top: $margin-unit; - + a { color: $text-color; } } - + //--- Results details ---// - + #details { .specDetail { margin-bottom: $line-height * 2; - + .description { //line-height: $line-height * 2; display: block; - + color: white; background-color: $failing-color; - + //font-size: $large-font-size; } } } - + .resultMessage { padding-top: $line-height; - + color: $text-color; } - + .resultMessage span.result { display: block; } - + .stackTrace { margin: 5px 0 0 0; max-height: $line-height * 16; overflow: auto; line-height: 18px; - + color: $light-text-color; border: 1px solid #ddd; background: white; white-space: pre; } -} \ No newline at end of file +} diff --git a/src/html/jasmine.css b/src/html/jasmine.css index 826e5753..8c008dc7 100644 --- a/src/html/jasmine.css +++ b/src/html/jasmine.css @@ -19,6 +19,7 @@ body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } #HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } #HTMLReporter .symbolSummary li.pending { line-height: 11px; } #HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } +#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } #HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } #HTMLReporter .runningAlert { background-color: #666666; } #HTMLReporter .skippedAlert { background-color: #aaaaaa; }