DEV: Move `run-qunit.js` out of the vendor directory

DEV: Move run-qunit.js out of the vendor directory

From 404acef6e3ca8f6444a1784677f3e889429f92cc Mon Sep 17 00:00:00 2001
From: David Taylor <david@taylorhq.com>
Date: Mon, 3 Dec 2018 16:16:37 +0000
Subject: [PATCH] DEV: Move `run-qunit.js` out of the vendor directory


diff --git a/lib/autospec/qunit_runner.rb b/lib/autospec/qunit_runner.rb
index 66f87a8..6598207 100644
--- a/lib/autospec/qunit_runner.rb
+++ b/lib/autospec/qunit_runner.rb
@@ -68,7 +68,7 @@ module Autospec
         end
       end
 
-      cmd = "node #{Rails.root}/vendor/assets/javascripts/run-qunit.js \"#{qunit_url}\" 3000000 ./tmp/qunit_result"
+      cmd = "node #{Rails.root}/test/run-qunit.js \"#{qunit_url}\" 3000000 ./tmp/qunit_result"
 
       @pid = Process.spawn(cmd)
       _, status = Process.wait2(@pid)
diff --git a/lib/tasks/qunit.rake b/lib/tasks/qunit.rake
index 884cc69..a34bd92 100644
--- a/lib/tasks/qunit.rake
+++ b/lib/tasks/qunit.rake
@@ -50,7 +50,7 @@ task "qunit:test", [:timeout, :qunit_path] => :environment do |_, args|
 
   begin
     success = true
-    test_path = "#{Rails.root}/vendor/assets/javascripts"
+    test_path = "#{Rails.root}/test"
     qunit_path = args[:qunit_path] || "/qunit"
     cmd = "node #{test_path}/run-qunit.js http://localhost:#{port}#{qunit_path}"
     options = { seed: (ENV["QUNIT_SEED"] || Random.new.seed) }
diff --git a/test/run-qunit.js b/test/run-qunit.js
new file mode 100644
index 0000000..f7eb97c
--- /dev/null
+++ b/test/run-qunit.js
@@ -0,0 +1,214 @@
+// Chrome QUnit Test Runner
+// Author: David Taylor
+// Requires chrome-launcher and chrome-remote-interface from npm
+// An up-to-date version of chrome is also required
+
+/* globals Promise */
+
+var args = process.argv.slice(2);
+
+if (args.length < 1 || args.length > 3) {
+  console.log("Usage: node run-qunit.js <URL> <timeout> <result_file>");
+  process.exit(1);
+}
+
+const chromeLauncher = require("chrome-launcher");
+const CDP = require("chrome-remote-interface");
+
+const QUNIT_RESULT = args[2];
+const fs = require("fs");
+
+if (QUNIT_RESULT) {
+  (async () => {
+    await fs.stat(QUNIT_RESULT, (err, stats) => {
+      if (stats && stats.isFile()) fs.unlink(QUNIT_RESULT);
+    });
+  })();
+}
+
+async function runAllTests() {
+  function launchChrome() {
+    const options = {
+      chromeFlags: ["--disable-gpu", "--headless", "--no-sandbox"]
+    };
+
+    if (process.env.REMOTE_DEBUG) {
+      options.port = 9222;
+    }
+
+    return chromeLauncher.launch(options);
+  }
+
+  let chrome = await launchChrome();
+  let protocol = await CDP({ port: chrome.port });
+
+  const { Page, Runtime } = protocol;
+
+  await Promise.all([Page.enable(), Runtime.enable()]);
+
+  Runtime.consoleAPICalled(response => {
+    const message = response["args"][0].value;
+
+    // If it's a simple test result, write without newline
+    if (message === "." || message === "F") {
+      process.stdout.write(message);
+    } else if (
+      message &&
+      message.startsWith &&
+      message.startsWith("AUTOSPEC:")
+    ) {
+      fs.appendFileSync(QUNIT_RESULT, `${message.slice(10)}\n`);
+    } else {
+      console.log(message);
+    }
+  });
+
+  console.log("navigate to " + args[0]);
+  Page.navigate({ url: args[0] });
+
+  Page.loadEventFired(async () => {
+    await Runtime.evaluate({ expression: `(${qunit_script})()` });
+
+    const timeout = parseInt(args[1] || 300000, 10);
+    var start = Date.now();
+
+    var interval;
+
+    let runTests = async function() {
+      if (Date.now() > start + timeout) {
+        console.error("Tests timed out");
+        protocol.close();
+        chrome.kill();
+        process.exit(124);
+      }
+
+      let numFails = await Runtime.evaluate({
+        expression: `(${check_script})()`
+      });
+
+      if (numFails && numFails.result && numFails.result.type !== "undefined") {
+        clearInterval(interval);
+        protocol.close();
+        chrome.kill();
+
+        if (numFails.result.value > 0) {
+          process.exit(1);
+        } else {
+          process.exit();
+        }
+      }
+    };
+
+    interval = setInterval(runTests, 250);
+  });
+}
+
+try {
+  runAllTests();
+} catch (e) {
+  console.log("Failed to run tests: " + e);
+  process.exit(1);
+}
+
+// The following functions are converted to strings
+// And then sent to chrome to be evalaluated
+function logQUnit() {
+  var moduleErrors = [];
+  var testErrors = [];
+  var assertionErrors = [];
+
+  console.log("\nRunning: " + JSON.stringify(QUnit.urlParams) + "\n");
+
+  QUnit.config.testTimeout = 10000;
+
+  QUnit.moduleDone(function(context) {
+    if (context.failed) {
+      var msg = "Module Failed: " + context.name + "\n" + testErrors.join("\n");
+      moduleErrors.push(msg);
+      testErrors = [];
+    }
+  });
+
+  let durations = {};
+
+  QUnit.testDone(function(context) {
+    durations[context.module + "::" + context.name] = context.runtime;
+
+    if (context.failed) {
+      var msg = "  Test Failed: " + context.name + assertionErrors.join("    ");
+
+      /* QUNIT_RESULT */
+
+      testErrors.push(msg);
+      assertionErrors = [];
+      console.log("F");
+    } else {
+      console.log(".");
+    }
+  });
+
+  QUnit.log(function(context) {
+    if (context.result) {
+      return;
+    }
+
+    var msg = "\n    Assertion Failed:";
+    if (context.message) {
+      msg += " " + context.message;
+    }
+
+    if (context.expected) {
+      msg +=
+        "\n      Expected: " + context.expected + ", Actual: " + context.actual;
+    }
+
+    assertionErrors.push(msg);
+  });
+
+  QUnit.done(function(context) {
+    console.log("\n");
+
+    if (moduleErrors.length > 0) {
+      for (var idx = 0; idx < moduleErrors.length; idx++) {
+        console.error(moduleErrors[idx] + "\n");
+      }
+    }
+
+    console.log("Slowest tests");
+    console.log("----------------------------------------------");
+    let ary = Object.keys(durations).map(key => ({
+      key: key,
+      value: durations[key]
+    }));
+    ary.sort((p1, p2) => p2.value - p1.value);
+    ary.slice(0, 30).forEach(pair => {
+      console.log(pair.key + ": " + pair.value + "ms");
+    });
+
+    var stats = [
+      "Time: " + context.runtime + "ms",
+      "Total: " + context.total,
+      "Passed: " + context.passed,
+      "Failed: " + context.failed
+    ];
+    console.log(stats.join(", "));
+
+    window.qunitDone = context;
+  });
+}
+let qunit_script = logQUnit.toString();
+
+if (QUNIT_RESULT) {
+  qunit_script = qunit_script.replace(
+    "/* QUNIT_RESULT */",
+    "console.log(`AUTOSPEC: ${context.module}:::${context.testId}:::${context.name}`);"
+  );
+}
+
+function check() {
+  if (window.qunitDone) {
+    return window.qunitDone.failed;
+  }
+}
+
+const check_script = check.toString();
diff --git a/vendor/assets/javascripts/run-qunit.js b/vendor/assets/javascripts/run-qunit.js
deleted file mode 100644
index f7eb97c..0000000
--- a/vendor/assets/javascripts/run-qunit.js
+++ /dev/null
@@ -1,214 +0,0 @@
-// Chrome QUnit Test Runner
-// Author: David Taylor
-// Requires chrome-launcher and chrome-remote-interface from npm
-// An up-to-date version of chrome is also required
-
-/* globals Promise */
-
-var args = process.argv.slice(2);
-
-if (args.length < 1 || args.length > 3) {
-  console.log("Usage: node run-qunit.js <URL> <timeout> <result_file>");
-  process.exit(1);
-}
-
-const chromeLauncher = require("chrome-launcher");
-const CDP = require("chrome-remote-interface");
-
-const QUNIT_RESULT = args[2];
-const fs = require("fs");
-
-if (QUNIT_RESULT) {
-  (async () => {
-    await fs.stat(QUNIT_RESULT, (err, stats) => {
-      if (stats && stats.isFile()) fs.unlink(QUNIT_RESULT);
-    });
-  })();
-}
-
-async function runAllTests() {
-  function launchChrome() {
-    const options = {
-      chromeFlags: ["--disable-gpu", "--headless", "--no-sandbox"]
-    };
-
-    if (process.env.REMOTE_DEBUG) {
-      options.port = 9222;
-    }
-
-    return chromeLauncher.launch(options);
-  }
-
-  let chrome = await launchChrome();
-

GitHub

2 Likes