Przeglądaj źródła

Support Skipped Tests and Fix JSHint Issues

The test runner now will not break when Mocha skips tests,
and will properly report them.  Additionally, several JSHint
warnings were fixed, and a `--debug` option was added to see
output from the provider.
Solly Ross 11 lat temu
rodzic
commit
8eb88937cc

+ 28 - 19
tests/run_from_console.casper.js

@@ -3,7 +3,7 @@ var path = require('path');
 
 
 var phantom_path = require('phantomjs').path;
 var phantom_path = require('phantomjs').path;
 var casper_path = path.resolve(__dirname, 'node_modules/casperjs/bin/casperjs');
 var casper_path = path.resolve(__dirname, 'node_modules/casperjs/bin/casperjs');
-process.env['PHANTOMJS_EXECUTABLE'] = phantom_path;
+process.env.PHANTOMJS_EXECUTABLE = phantom_path;
 var casper_opts = {
 var casper_opts = {
   child: {
   child: {
     transport: 'http',
     transport: 'http',
@@ -13,7 +13,7 @@ var casper_opts = {
     logLevel: 'debug',
     logLevel: 'debug',
     verbose: true
     verbose: true
   }
   }
-}
+};
 
 
 var provide_emitter = function(file_paths) {
 var provide_emitter = function(file_paths) {
   var spooky = new Spooky(casper_opts, function(err) {
   var spooky = new Spooky(casper_opts, function(err) {
@@ -29,22 +29,24 @@ var provide_emitter = function(file_paths) {
       spooky.then([{ path_ind: path_ind }, function() {
       spooky.then([{ path_ind: path_ind }, function() {
         var res_json = {
         var res_json = {
           file_ind: path_ind
           file_ind: path_ind
-        }
+        };
 
 
-        res_json.num_tests = this.evaluate(function() { return document.querySelectorAll('li.test').length });
-        res_json.num_passes = this.evaluate(function() { return document.querySelectorAll('li.test.pass').length });
-        res_json.num_fails = this.evaluate(function() { return document.querySelectorAll('li.test.fail').length });
-        res_json.num_slow = this.evaluate(function() { return document.querySelectorAll('li.test.pass:not(.fast)').length });
-        res_json.duration = this.evaluate(function() { return document.querySelector('li.duration em').textContent });
+        res_json.num_tests = this.evaluate(function() { return document.querySelectorAll('li.test').length; });
+        res_json.num_passes = this.evaluate(function() { return document.querySelectorAll('li.test.pass').length; });
+        res_json.num_fails = this.evaluate(function() { return document.querySelectorAll('li.test.fail').length; });
+        res_json.num_slow = this.evaluate(function() { return document.querySelectorAll('li.test.pass:not(.fast):not(.pending)').length; });
+        res_json.num_skipped = this.evaluate(function () { return document.querySelectorAll('li.test.pending').length; });
+        res_json.duration = this.evaluate(function() { return document.querySelector('li.duration em').textContent; });
 
 
         res_json.suites = this.evaluate(function() {
         res_json.suites = this.evaluate(function() {
           var traverse_node = function(elem) {
           var traverse_node = function(elem) {
+            var res;
             if (elem.classList.contains('suite')) {
             if (elem.classList.contains('suite')) {
-              var res = {
+              res = {
                 type: 'suite',
                 type: 'suite',
                 name: elem.querySelector('h1').textContent,
                 name: elem.querySelector('h1').textContent,
                 has_subfailures: elem.querySelectorAll('li.test.fail').length > 0,
                 has_subfailures: elem.querySelectorAll('li.test.fail').length > 0,
-              }
+              };
 
 
               var child_elems = elem.querySelector('ul').children;
               var child_elems = elem.querySelector('ul').children;
               res.children = Array.prototype.map.call(child_elems, traverse_node);
               res.children = Array.prototype.map.call(child_elems, traverse_node);
@@ -52,15 +54,22 @@ var provide_emitter = function(file_paths) {
             }
             }
             else {
             else {
               var h2_content = elem.querySelector('h2').childNodes;
               var h2_content = elem.querySelector('h2').childNodes;
-              var res = {
+              res = {
                 type: 'test',
                 type: 'test',
                 text: h2_content[0].textContent,
                 text: h2_content[0].textContent,
-              }
+              };
 
 
               if (elem.classList.contains('pass')) {
               if (elem.classList.contains('pass')) {
                 res.pass = true;
                 res.pass = true;
-                res.slow = !elem.classList.contains('fast');
-                res.duration = h2_content[1].textContent;
+                if (elem.classList.contains('pending')) {
+                  res.slow = false;
+                  res.skipped = true;
+                }
+                else {
+                  res.slow = !elem.classList.contains('fast');
+                  res.skipped = false;
+                  res.duration = h2_content[1].textContent;
+                }
               }
               }
               else {
               else {
                 res.error = elem.querySelector('pre.error').textContent;
                 res.error = elem.querySelector('pre.error').textContent;
@@ -68,23 +77,23 @@ var provide_emitter = function(file_paths) {
 
 
               return res;
               return res;
             }
             }
-          }
+          };
           var top_suites = document.querySelectorAll('#mocha-report > li.suite');
           var top_suites = document.querySelectorAll('#mocha-report > li.suite');
           return Array.prototype.map.call(top_suites, traverse_node);
           return Array.prototype.map.call(top_suites, traverse_node);
         });
         });
 
 
-        res_json.replay = this.evaluate(function() { return document.querySelector('a.replay').textContent });
+        res_json.replay = this.evaluate(function() { return document.querySelector('a.replay').textContent; });
 
 
         this.emit('test_ready', res_json);
         this.emit('test_ready', res_json);
       }]);
       }]);
     });
     });
     spooky.run();
     spooky.run();
   });
   });
-  
+
   return spooky;
   return spooky;
-}
+};
 
 
 module.exports = {
 module.exports = {
   provide_emitter: provide_emitter,
   provide_emitter: provide_emitter,
   name: 'SpookyJS (CapserJS on PhantomJS)'
   name: 'SpookyJS (CapserJS on PhantomJS)'
-}
+};

+ 39 - 19
tests/run_from_console.js

@@ -5,7 +5,7 @@ var path = require('path');
 
 
 var make_list = function(val) {
 var make_list = function(val) {
   return val.split(',');
   return val.split(',');
-}
+};
 
 
 program
 program
   .option('-t, --tests <testlist>', 'Run the specified html-file-based test(s). \'testlist\' should be a comma-separated list', make_list, [])
   .option('-t, --tests <testlist>', 'Run the specified html-file-based test(s). \'testlist\' should be a comma-separated list', make_list, [])
@@ -16,6 +16,7 @@ program
   .option('-p, --provider <name>', 'Use the given provider (defaults to "casper").  Currently, may be "casper" or "zombie"', 'casper')
   .option('-p, --provider <name>', 'Use the given provider (defaults to "casper").  Currently, may be "casper" or "zombie"', 'casper')
   .option('-g, --generate-html', 'Instead of running the tests, just return the path to the generated HTML file, then wait for user interaction to exit (should be used with -i)')
   .option('-g, --generate-html', 'Instead of running the tests, just return the path to the generated HTML file, then wait for user interaction to exit (should be used with -i)')
   .option('-o, --output-html', 'Instead of running the tests, just output the generated HTML source to STDOUT (should be used with -i)')
   .option('-o, --output-html', 'Instead of running the tests, just output the generated HTML source to STDOUT (should be used with -i)')
+  .option('-d, --debug', 'Show debug output (the "console" event) from the provider')
   .parse(process.argv);
   .parse(process.argv);
 
 
 var file_paths = [];
 var file_paths = [];
@@ -26,13 +27,15 @@ if (program.autoInject) {
   temp.track();
   temp.track();
 
 
   var template = {
   var template = {
-    header: "<html>\n<head>\n<meta charset='utf-8' />\<link rel='stylesheet' href='node_modules/mocha/mocha.css'/>\n</head>\n<body><div id='mocha'></div>",
-    script_tag: function(p) { return "<script src='" + p + "'></script>" },
+    header: "<html>\n<head>\n<meta charset='utf-8' />\n<link rel='stylesheet' href='" + path.resolve(__dirname, 'node_modules/mocha/mocha.css') + "'/>\n</head>\n<body><div id='mocha'></div>",
+    script_tag: function(p) { return "<script src='" + p + "'></script>"; },
     footer: "<script>\nmocha.checkLeaks();\nmocha.globals(['navigator', 'create', 'ClientUtils', '__utils__']);\nmocha.run();\n</script>\n</body>\n</html>"
     footer: "<script>\nmocha.checkLeaks();\nmocha.globals(['navigator', 'create', 'ClientUtils', '__utils__']);\nmocha.run();\n</script>\n</body>\n</html>"
   };
   };
 
 
   template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/chai/chai.js'));
   template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/chai/chai.js'));
   template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/mocha/mocha.js'));
   template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/mocha/mocha.js'));
+  template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/sinon/pkg/sinon.js'));
+  template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/sinon-chai/lib/sinon-chai.js'));
   template.header += "\n<script>mocha.setup('bdd');</script>";
   template.header += "\n<script>mocha.setup('bdd');</script>";
 
 
 
 
@@ -74,7 +77,7 @@ if (program.outputHtml) {
         console.warn(error.stack);
         console.warn(error.stack);
         return;
         return;
       }
       }
-      
+
       cursor
       cursor
         .bold()
         .bold()
         .write(program.tests[path_ind])
         .write(program.tests[path_ind])
@@ -137,8 +140,8 @@ if (!program.outputHtml && !program.generateHtml) {
 
 
     console.log('');
     console.log('');
 
 
-    cursor.write(''+test_json.num_tests+' tests run, ')
     cursor
     cursor
+      .write(''+test_json.num_tests+' tests run, ')
       .green()
       .green()
       .write(''+test_json.num_passes+' passed');
       .write(''+test_json.num_passes+' passed');
     if (test_json.num_slow > 0) {
     if (test_json.num_slow > 0) {
@@ -157,9 +160,16 @@ if (!program.outputHtml && !program.generateHtml) {
     cursor
     cursor
       .red()
       .red()
       .write(''+test_json.num_fails+' failed');
       .write(''+test_json.num_fails+' failed');
+    if (test_json.num_skipped > 0) {
+      cursor
+        .reset()
+        .write(', ')
+        .grey()
+        .write(''+test_json.num_skipped+' skipped');
+    }
     cursor
     cursor
       .reset()
       .reset()
-      .write(' -- duration: '+test_json.duration+"\n");
+      .write(' -- duration: '+test_json.duration+"s\n");
 
 
     console.log('');
     console.log('');
 
 
@@ -168,7 +178,7 @@ if (!program.outputHtml && !program.generateHtml) {
         if (node.type == 'suite') {
         if (node.type == 'suite') {
           if (!node.has_subfailures && !program.printAll) return;
           if (!node.has_subfailures && !program.printAll) return;
 
 
-          if (indentation == 0) {
+          if (indentation === 0) {
             cursor.bold();
             cursor.bold();
             console.log(node.name);
             console.log(node.name);
             console.log(Array(node.name.length+1).join('-'));
             console.log(Array(node.name.length+1).join('-'));
@@ -195,17 +205,25 @@ if (!program.outputHtml && !program.generateHtml) {
             cursor.magenta();
             cursor.magenta();
             console.log('- failed: '+node.text+test_json.replay);
             console.log('- failed: '+node.text+test_json.replay);
             cursor.red();
             cursor.red();
-            console.log('          '+node.error.split("\n")[0]);  // the split is to avoid a weird thing where in PhantomJS, we get a stack trace too
+            console.log('          '+node.error.split("\n")[0]);  // the split is to avoid a weird thing where in PhantomJS where we get a stack trace too
             cursor.reset();
             cursor.reset();
             console.log('');
             console.log('');
           }
           }
           else if (program.printAll) {
           else if (program.printAll) {
-            if (node.slow) cursor.yellow();
-            else cursor.green();
-            cursor
-              .write('- pass: '+node.text)
-              .grey()
-              .write(' ('+node.duration+') ');
+            if (node.skipped) {
+              cursor
+                .grey()
+                .write('- skipped: '+node.text);
+            }
+            else {
+              if (node.slow) cursor.yellow();
+              else cursor.green();
+
+              cursor
+                .write('- pass: '+node.text)
+                .grey()
+                .write(' ('+node.duration+') ');
+            }
             /*if (node.slow) cursor.yellow();
             /*if (node.slow) cursor.yellow();
             else cursor.green();*/
             else cursor.green();*/
             cursor
             cursor
@@ -215,23 +233,25 @@ if (!program.outputHtml && !program.generateHtml) {
             console.log('');
             console.log('');
           }
           }
         }
         }
-      }
+      };
 
 
       for (var i = 0; i < test_json.suites.length; i++) {
       for (var i = 0; i < test_json.suites.length; i++) {
         traverse_tree(0, test_json.suites[i]);
         traverse_tree(0, test_json.suites[i]);
       }
       }
     }
     }
 
 
-    if (test_json.num_fails == 0) {
+    if (test_json.num_fails === 0) {
       cursor.fg.green();
       cursor.fg.green();
       console.log('all tests passed :-)');
       console.log('all tests passed :-)');
       cursor.reset();
       cursor.reset();
     }
     }
   });
   });
 
 
-  /*provider.on('console', function(line) {
-    //console.log(line);
-  });*/
+  if (program.debug) {
+    provider.on('console', function(line) {
+      console.log(line);
+    });
+  }
 
 
   /*gprom.finally(function(ph) {
   /*gprom.finally(function(ph) {
     ph.exit();
     ph.exit();

+ 18 - 9
tests/run_from_console.zombie.js

@@ -18,16 +18,18 @@ var provide_emitter = function(file_paths) {
         res_json.num_fails = browser.querySelectorAll('li.test.fail').length;
         res_json.num_fails = browser.querySelectorAll('li.test.fail').length;
         res_json.num_passes = browser.querySelectorAll('li.test.pass').length;
         res_json.num_passes = browser.querySelectorAll('li.test.pass').length;
         res_json.num_slow = browser.querySelectorAll('li.test.pass:not(.fast)').length;
         res_json.num_slow = browser.querySelectorAll('li.test.pass:not(.fast)').length;
+        res_json.num_skipped = browser.querySelectorAll('li.test.pending').length;
         res_json.duration = browser.text('li.duration em');
         res_json.duration = browser.text('li.duration em');
 
 
         var traverse_node = function(elem) {
         var traverse_node = function(elem) {
           var classList = elem.className.split(' ');
           var classList = elem.className.split(' ');
+          var res;
           if (classList.indexOf('suite') > -1) {
           if (classList.indexOf('suite') > -1) {
-            var res = {
+            res = {
               type: 'suite',
               type: 'suite',
               name: elem.querySelector('h1').textContent,
               name: elem.querySelector('h1').textContent,
               has_subfailures: elem.querySelectorAll('li.test.fail').length > 0
               has_subfailures: elem.querySelectorAll('li.test.fail').length > 0
-            }
+            };
 
 
             var child_elems = elem.querySelector('ul').children;
             var child_elems = elem.querySelector('ul').children;
             res.children = Array.prototype.map.call(child_elems, traverse_node);
             res.children = Array.prototype.map.call(child_elems, traverse_node);
@@ -35,15 +37,22 @@ var provide_emitter = function(file_paths) {
           }
           }
           else {
           else {
             var h2_content = elem.querySelector('h2').childNodes;
             var h2_content = elem.querySelector('h2').childNodes;
-            var res = {
+            res = {
               type: 'test',
               type: 'test',
               text: h2_content[0].textContent
               text: h2_content[0].textContent
-            }
+            };
 
 
             if (classList.indexOf('pass') > -1) {
             if (classList.indexOf('pass') > -1) {
               res.pass = true;
               res.pass = true;
-              res.slow = classList.indexOf('fast') < 0;
-              res.duration = h2_content[1].textContent;
+              if (classList.indexOf('pending') > -1) {
+                res.slow = false;
+                res.skipped = true;
+              }
+              else {
+                res.slow = classList.indexOf('fast') < 0;
+                res.skipped = false;
+                res.duration = h2_content[1].textContent;
+              }
             }
             }
             else {
             else {
               res.error = elem.querySelector('pre.error').textContent;
               res.error = elem.querySelector('pre.error').textContent;
@@ -51,7 +60,7 @@ var provide_emitter = function(file_paths) {
 
 
             return res;
             return res;
           }
           }
-        }
+        };
 
 
         var top_suites = browser.querySelectorAll('#mocha-report > li.suite');
         var top_suites = browser.querySelectorAll('#mocha-report > li.suite');
         res_json.suites = Array.prototype.map.call(top_suites, traverse_node);
         res_json.suites = Array.prototype.map.call(top_suites, traverse_node);
@@ -65,9 +74,9 @@ var provide_emitter = function(file_paths) {
   }, Q(new Browser()));
   }, Q(new Browser()));
 
 
   return emitter;
   return emitter;
-}
+};
 
 
 module.exports = {
 module.exports = {
   provide_emitter: provide_emitter,
   provide_emitter: provide_emitter,
   name: 'ZombieJS'
   name: 'ZombieJS'
-}
+};