cucumber-html
Advanced tools
+1
-1
@@ -6,3 +6,3 @@ { | ||
| "description": "Cross platform HTML formatter for all implementations of Cucumber", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "homepage": "https://github.com/cucumber/cucumber-html", | ||
@@ -9,0 +9,0 @@ "repository": { |
@@ -1,145 +0,183 @@ | ||
| var Cucumber = {}; | ||
| var CucumberHTML = {}; | ||
| Cucumber.DOMFormatter = function(rootNode) { | ||
| var currentUri; | ||
| var currentFeature; | ||
| var currentElement; | ||
| var currentSteps; | ||
| CucumberHTML.DOMFormatter = function(rootNode) { | ||
| var currentUri; | ||
| var currentFeature; | ||
| var currentElement; | ||
| var currentSteps; | ||
| var currentStepIndex; | ||
| var currentStep; | ||
| var currentStepIndex; | ||
| var currentStep; | ||
| var $templates = $(CucumberHTML.templates); | ||
| this.uri = function(uri) { | ||
| currentUri = uri; | ||
| }; | ||
| this.feature = function(feature) { | ||
| currentFeature = blockElement(rootNode, feature, 'feature'); | ||
| }; | ||
| this.uri = function(uri) { | ||
| currentUri = uri; | ||
| }; | ||
| this.background = function(background) { | ||
| currentElement = featureElement(background, 'background'); | ||
| currentStepIndex = 1; | ||
| }; | ||
| this.feature = function(feature) { | ||
| currentFeature = blockElement(rootNode, feature, 'feature'); | ||
| }; | ||
| this.scenario = function(scenario) { | ||
| currentElement = featureElement(scenario, 'scenario'); | ||
| currentStepIndex = 1; | ||
| }; | ||
| this.background = function(background) { | ||
| currentElement = featureElement(background, 'background'); | ||
| currentStepIndex = 1; | ||
| }; | ||
| this.scenarioOutline = function(scenarioOutline) { | ||
| currentElement = featureElement(scenarioOutline, 'scenario_outline'); | ||
| currentStepIndex = 1; | ||
| }; | ||
| this.scenario = function(scenario) { | ||
| currentElement = featureElement(scenario, 'scenario'); | ||
| currentStepIndex = 1; | ||
| }; | ||
| this.step = function(step) { | ||
| var stepElement = $('#cucumber-templates .step').clone(); | ||
| stepElement.appendTo(currentSteps); | ||
| populate(stepElement, step, 'step'); | ||
| this.scenarioOutline = function(scenarioOutline) { | ||
| currentElement = featureElement(scenarioOutline, 'scenario_outline'); | ||
| currentStepIndex = 1; | ||
| }; | ||
| if (step.doc_string) { | ||
| docString = $('#cucumber-templates .doc_string').clone(); | ||
| docString.appendTo(stepElement); | ||
| // TODO: use a syntax highlighter based on the content_type | ||
| docString.text(step.doc_string.value); | ||
| } | ||
| if (step.rows) { | ||
| dataTable = $('#cucumber-templates .data_table').clone(); | ||
| dataTable.appendTo(stepElement); | ||
| var tBody = dataTable.find('tbody'); | ||
| $.each(step.rows, function(index, row) { | ||
| var tr = $('<tr></tr>').appendTo(tBody); | ||
| $.each(row.cells, function(index, cell) { | ||
| var td = $('<td>' + cell + '</td>').appendTo(tBody); | ||
| }); | ||
| }); | ||
| } | ||
| }; | ||
| this.examples = function(examples) { | ||
| var examplesElement = blockElement(currentElement.children('details'), examples, 'examples'); | ||
| var examplesTable = $('#cucumber-templates .examples_table').clone(); | ||
| examplesTable.appendTo(examplesElement.children('details')); | ||
| this.step = function(step) { | ||
| var stepElement = $('.step', $templates).clone(); | ||
| stepElement.appendTo(currentSteps); | ||
| populate(stepElement, step, 'step'); | ||
| $.each(examples.rows, function(index, row) { | ||
| var parent = index == 0 ? examplesTable.find('thead') : examplesTable.find('tbody'); | ||
| var tr = $('<tr></tr>').appendTo(parent); | ||
| $.each(row.cells, function(index, cell) { | ||
| var td = $('<td>' + cell + '</td>').appendTo(tr); | ||
| }); | ||
| if (step.doc_string) { | ||
| docString = $('.doc_string', $templates).clone(); | ||
| docString.appendTo(stepElement); | ||
| // TODO: use a syntax highlighter based on the content_type | ||
| docString.text(step.doc_string.value); | ||
| } | ||
| if (step.rows) { | ||
| dataTable = $('.data_table', $templates).clone(); | ||
| dataTable.appendTo(stepElement); | ||
| var tBody = dataTable.find('tbody'); | ||
| $.each(step.rows, function(index, row) { | ||
| var tr = $('<tr></tr>').appendTo(tBody); | ||
| $.each(row.cells, function(index, cell) { | ||
| var td = $('<td>' + cell + '</td>').appendTo(tBody); | ||
| }); | ||
| }; | ||
| }); | ||
| } | ||
| }; | ||
| this.match = function(match) { | ||
| currentStep = currentSteps.find('li:nth-child(' + currentStepIndex + ')'); | ||
| currentStepIndex++; | ||
| }; | ||
| this.examples = function(examples) { | ||
| var examplesElement = blockElement(currentElement.children('details'), examples, 'examples'); | ||
| var examplesTable = $('.examples_table', $templates).clone(); | ||
| examplesTable.appendTo(examplesElement.children('details')); | ||
| this.result = function(result) { | ||
| currentStep.addClass(result.status); | ||
| currentElement.addClass(result.status); | ||
| var isLastStep = currentSteps.find('li:nth-child(' + currentStepIndex + ')').length == 0; | ||
| if(isLastStep) { | ||
| if(currentSteps.find('.failed').length == 0) { | ||
| // No failed steps. Collapse it. | ||
| currentElement.find('details').removeAttr('open'); | ||
| } | ||
| } | ||
| }; | ||
| $.each(examples.rows, function(index, row) { | ||
| var parent = index == 0 ? examplesTable.find('thead') : examplesTable.find('tbody'); | ||
| var tr = $('<tr></tr>').appendTo(parent); | ||
| $.each(row.cells, function(index, cell) { | ||
| var td = $('<td>' + cell + '</td>').appendTo(tr); | ||
| }); | ||
| }); | ||
| }; | ||
| this.embedding = function(mimeType, data) { | ||
| if(mimeType.match(/^image\//)) { | ||
| currentStep.append("<div><img src='" + data + "'></div>"); | ||
| } | ||
| this.match = function(match) { | ||
| currentStep = currentSteps.find('li:nth-child(' + currentStepIndex + ')'); | ||
| currentStepIndex++; | ||
| }; | ||
| this.result = function(result) { | ||
| currentStep.addClass(result.status); | ||
| currentElement.addClass(result.status); | ||
| var isLastStep = currentSteps.find('li:nth-child(' + currentStepIndex + ')').length == 0; | ||
| if(isLastStep) { | ||
| if(currentSteps.find('.failed').length == 0) { | ||
| // No failed steps. Collapse it. | ||
| currentElement.find('details').removeAttr('open'); | ||
| } | ||
| } | ||
| }; | ||
| function featureElement(statement, itemtype) { | ||
| var e = blockElement(currentFeature.children('details'), statement, itemtype); | ||
| this.embedding = function(mimeType, data) { | ||
| if(mimeType.match(/^image\//)) { | ||
| currentStep.append("<div><img src='" + data + "'></div>"); | ||
| } | ||
| } | ||
| currentSteps = $('#cucumber-templates .steps').clone(); | ||
| currentSteps.appendTo(e.children('details')); | ||
| function featureElement(statement, itemtype) { | ||
| var e = blockElement(currentFeature.children('details'), statement, itemtype); | ||
| return e; | ||
| } | ||
| currentSteps = $('.steps', $templates).clone(); | ||
| currentSteps.appendTo(e.children('details')); | ||
| function blockElement(parent, statement, itemtype) { | ||
| var e = $('#cucumber-templates .blockelement').clone(); | ||
| e.appendTo(parent); | ||
| return populate(e, statement, itemtype); | ||
| } | ||
| return e; | ||
| } | ||
| function populate(e, statement, itemtype) { | ||
| populateTags(e, statement.tags); | ||
| populateComments(e, statement.comments); | ||
| e.find('.keyword').text(statement.keyword); | ||
| e.find('.name').text(statement.name); | ||
| e.find('.description').text(statement.description); | ||
| e.attr('itemtype', 'http://cukes.info/microformat/' + itemtype); | ||
| e.addClass(itemtype); | ||
| return e; | ||
| } | ||
| function blockElement(parent, statement, itemtype) { | ||
| var e = $('.blockelement', $templates).clone(); | ||
| e.appendTo(parent); | ||
| return populate(e, statement, itemtype); | ||
| } | ||
| function populateComments(e, comments) { | ||
| if (comments !== undefined) { | ||
| var commentsNode = $('#cucumber-templates .comments').clone().prependTo(e.find('.header')); | ||
| $.each(comments, function(index, comment) { | ||
| var commentNode = $('#cucumber-templates .comment').clone().appendTo(commentsNode); | ||
| commentNode.text(comment.value); | ||
| }); | ||
| } | ||
| function populate(e, statement, itemtype) { | ||
| populateTags(e, statement.tags); | ||
| populateComments(e, statement.comments); | ||
| e.find('.keyword').text(statement.keyword); | ||
| e.find('.name').text(statement.name); | ||
| e.find('.description').text(statement.description); | ||
| e.attr('itemtype', 'http://cukes.info/microformat/' + itemtype); | ||
| e.addClass(itemtype); | ||
| return e; | ||
| } | ||
| function populateComments(e, comments) { | ||
| if (comments !== undefined) { | ||
| var commentsNode = $('.comments', $templates).clone().prependTo(e.find('.header')); | ||
| $.each(comments, function(index, comment) { | ||
| var commentNode = $('.comment', $templates).clone().appendTo(commentsNode); | ||
| commentNode.text(comment.value); | ||
| }); | ||
| } | ||
| } | ||
| function populateTags(e, tags) { | ||
| if (tags !== undefined) { | ||
| var tagsNode = $('#cucumber-templates .tags').clone().prependTo(e.find('.header')); | ||
| $.each(tags, function(index, tag) { | ||
| var tagNode = $('#cucumber-templates .tag').clone().appendTo(tagsNode); | ||
| tagNode.text(tag.name); | ||
| }); | ||
| } | ||
| function populateTags(e, tags) { | ||
| if (tags !== undefined) { | ||
| var tagsNode = $('.tags', $templates).clone().prependTo(e.find('.header')); | ||
| $.each(tags, function(index, tag) { | ||
| var tagNode = $('.tag', $templates).clone().appendTo(tagsNode); | ||
| tagNode.text(tag.name); | ||
| }); | ||
| } | ||
| } | ||
| }; | ||
| CucumberHTML.templates = '<div>\ | ||
| <section class="blockelement" itemscope>\ | ||
| <details open>\ | ||
| <summary class="header">\ | ||
| <span class="keyword" itemprop="keyword">Keyword</span>: <span itemprop="name" class="name">This is the block name</span>\ | ||
| </summary>\ | ||
| <div itemprop="description" class="description">The description goes here</div>\ | ||
| </details>\ | ||
| </section>\ | ||
| \ | ||
| <ol class="steps"></ol>\ | ||
| \ | ||
| <ol>\ | ||
| <li class="step"><span class="keyword" itemprop="keyword">Keyword</span><span class="name" itemprop="name">Name</span></li>\ | ||
| </ol>\ | ||
| \ | ||
| <pre class="doc_string"></pre>\ | ||
| \ | ||
| <table class="data_table">\ | ||
| <tbody>\ | ||
| </tbody>\ | ||
| </table>\ | ||
| \ | ||
| <table class="examples_table">\ | ||
| <thead></thead>\ | ||
| <tbody></tbody>\ | ||
| </table>\ | ||
| \ | ||
| <section class="embed">\ | ||
| <img itemprop="screenshot" class="screenshot" />\ | ||
| </section>\ | ||
| <div class="tags"></div>\ | ||
| <span class="tag"></span>\ | ||
| <div class="comments"></div>\ | ||
| <div class="comment"></div>\ | ||
| <div>'; | ||
| if (typeof module !== 'undefined') { | ||
| module.exports = Cucumber; | ||
| module.exports = CucumberHTML; | ||
| } |
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>Cucumber Features</title> | ||
| <link href="style.css" rel="stylesheet"> | ||
| <script src="jquery-1.6.4.min.js"></script> | ||
| <script src="formatter.js"></script> | ||
| <script src="report.js"></script> | ||
| </head> | ||
| <body> | ||
| <div class="cucumber-report"> | ||
| </div> | ||
| <div id="cucumber-templates"> | ||
| <section class="blockelement" itemscope> | ||
| <details open> | ||
| <summary class="header"> | ||
| <span class="keyword" itemprop="keyword">Keyword</span>: <span itemprop="name" class="name">This is the block name</span> | ||
| </summary> | ||
| <div itemprop="description" class="description">The description goes here</div> | ||
| </details> | ||
| </section> | ||
| <ol class="steps"> | ||
| </ol> | ||
| <ol> | ||
| <li class="step"><span class="keyword" itemprop="keyword">Keyword</span><span class="name" itemprop="name">Name</span></li> | ||
| </ol> | ||
| <pre class="doc_string"> | ||
| </pre> | ||
| <table class="data_table"> | ||
| <tbody> | ||
| </tbody> | ||
| </table> | ||
| <table class="examples_table"> | ||
| <thead> | ||
| </thead> | ||
| <tbody> | ||
| </tbody> | ||
| </table> | ||
| <section class="embed"> | ||
| <img itemprop="screenshot" class="screenshot" /> | ||
| </section> | ||
| <div class="tags"></div> | ||
| <span class="tag"></span> | ||
| <div class="comments"></div> | ||
| <div class="comment"></div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>Cucumber Features</title> | ||
| <link href="style.css" rel="stylesheet"> | ||
| <script src="jquery-1.6.4.min.js"></script> | ||
| <script src="formatter.js"></script> | ||
| <script src="report.js"></script> | ||
| </head> | ||
| <body> | ||
| <div class="cucumber-report"></div> | ||
| </body> | ||
| </html> |
| $(document).ready(function() { | ||
| var formatter = new Cucumber.DOMFormatter($('.cucumber-report')); | ||
| formatter.uri('report.feature'); | ||
| formatter.feature({ | ||
| comments: [ | ||
| {value: "# A comment"}, | ||
| {value: "# Another comment"}, | ||
| ], | ||
| keyword:'Feature', | ||
| name:'Generating html report', | ||
| description: 'It could be useful to have an html report to facilitate documentation reading.', | ||
| line:2 | ||
| }); | ||
| var formatter = new CucumberHTML.DOMFormatter($('.cucumber-report')); | ||
| formatter.uri('report.feature'); | ||
| formatter.feature({ | ||
| comments: [ | ||
| {value: "# A comment"}, | ||
| {value: "# Another comment"}, | ||
| ], | ||
| keyword:'Feature', | ||
| name:'Generating html report', | ||
| description: 'It could be useful to have an html report to facilitate documentation reading.', | ||
| line:2 | ||
| }); | ||
| formatter.background({ | ||
| comments: [ | ||
| {value: "# Background comment"} | ||
| ], | ||
| keyword:'Background', | ||
| name:'Setting up the context', | ||
| line:3, | ||
| description: 'These steps will be executed before each scenario.' | ||
| }); | ||
| formatter.step({keyword:'Given ', name:'I have a background', line:4}); | ||
| formatter.step({keyword:'And ', name:'I set some context', line: 5}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.background({ | ||
| comments: [ | ||
| {value: "# Background comment"} | ||
| ], | ||
| keyword:'Background', | ||
| name:'Setting up the context', | ||
| line:3, | ||
| description: 'These steps will be executed before each scenario.' | ||
| }); | ||
| formatter.step({keyword:'Given ', name:'I have a background', line:4}); | ||
| formatter.step({keyword:'And ', name:'I set some context', line: 5}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.scenario({"tags":[{"name":"@foo","line":3},{"name":"@bar","line":4},{"name":"@doh","line":5}], keyword:'Scenario', name: 'Creating a simple report', line: 6}); | ||
| formatter.step({keyword:'Given ', name:'I have a feature', line: 7, doc_string:{value: "A\ndoc string\non several lines", content_type:"text/plain", line:8}}); | ||
| formatter.step({keyword:'When ', name:'I format it', line: 11}); | ||
| formatter.step({keyword:'Then ', name:'It should look pretty', line: 12}); | ||
| formatter.step({keyword:'And ', name:'It should show tables', line: 13, rows: [{cells:['name', 'price'], line: 14}, {cells:['milk', '9'], line: 15}]}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'failed', error_message:'something went wrong...', duration: 0}); | ||
| formatter.embedding('image/png', 'bubble_256x256.png'); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'undefined', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'skipped', duration: 0}); | ||
| formatter.scenario({"tags":[{"name":"@foo","line":3},{"name":"@bar","line":4},{"name":"@doh","line":5}], keyword:'Scenario', name: 'Creating a simple report', line: 6}); | ||
| formatter.step({keyword:'Given ', name:'I have a feature', line: 7, doc_string:{value: "A\ndoc string\non several lines", content_type:"text/plain", line:8}}); | ||
| formatter.step({keyword:'When ', name:'I format it', line: 11}); | ||
| formatter.step({keyword:'Then ', name:'It should look pretty', line: 12}); | ||
| formatter.step({keyword:'And ', name:'It should show tables', line: 13, rows: [{cells:['name', 'price'], line: 14}, {cells:['milk', '9'], line: 15}]}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'failed', error_message:'something went wrong...', duration: 0}); | ||
| formatter.embedding('image/png', 'bubble_256x256.png'); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'undefined', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'skipped', duration: 0}); | ||
| formatter.scenarioOutline({keyword:'Scenario Outline', name: 'Scenario with examples', description:'It should be good to format outlined arguments.', line: 16}); | ||
| formatter.step({keyword:'Given ', name:'I have a <name> which costs <price>', line: 17}); | ||
| formatter.examples({description:'', name:'Some good examples', keyword:'Examples', line: 18, rows:[{cells:['name', 'price'], line:19}, {cells:['milk', '9'], line:20}, {cells:['bread', '7'], line:21}, {cells:['soap', '5'], line:22}]}) | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'failed', error_message:'I didn\'t do it.', duration: 0}); | ||
| formatter.scenarioOutline({keyword:'Scenario Outline', name: 'Scenario with examples', description:'It should be good to format outlined arguments.', line: 16}); | ||
| formatter.step({keyword:'Given ', name:'I have a <name> which costs <price>', line: 17}); | ||
| formatter.examples({description:'', name:'Some good examples', keyword:'Examples', line: 18, rows:[{cells:['name', 'price'], line:19}, {cells:['milk', '9'], line:20}, {cells:['bread', '7'], line:21}, {cells:['soap', '5'], line:22}]}) | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'passed', duration: 0}); | ||
| formatter.match({uri:'report.feature'}); | ||
| formatter.result({status:'failed', error_message:'I didn\'t do it.', duration: 0}); | ||
| }); |
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
530
7.51%120670
-0.55%