DEV: Drop `/theme-qunit` from smoke test (#23562)
We will soon be dropping support for `/theme-qunit` in production, so this will start failing if we don't remove it. Plus, we now have system specs which verify the end-to-end functionality of the Theme QUnit system. This was the last thing which was using the legacy `run-qunit` script, so that can also be dropped.
This commit is contained in:
parent
ef0a049b87
commit
e0daacf3ef
|
@ -74,21 +74,4 @@ task "smoke:test" do
|
||||||
end
|
end
|
||||||
|
|
||||||
raise "FAILED" if results !~ /ALL PASSED/
|
raise "FAILED" if results !~ /ALL PASSED/
|
||||||
|
|
||||||
api_key = ENV["ADMIN_API_KEY"]
|
|
||||||
api_username = ENV["ADMIN_API_USERNAME"]
|
|
||||||
theme_url = ENV["SMOKE_TEST_THEME_URL"]
|
|
||||||
|
|
||||||
next if api_key.blank? && api_username.blank? && theme_url.blank?
|
|
||||||
|
|
||||||
puts "Running QUnit tests for theme #{theme_url.inspect} using API key #{api_key[0..3]}... and username #{api_username.inspect}"
|
|
||||||
|
|
||||||
query_params = { seed: Random.new.seed, theme_url: theme_url, hidepassed: 1, report_requests: 1 }
|
|
||||||
url += "/" if !url.end_with?("/")
|
|
||||||
full_url = "#{url}theme-qunit?#{query_params.to_query}"
|
|
||||||
timeout = 1000 * 20
|
|
||||||
|
|
||||||
sh("node", "#{Rails.root}/test/run-qunit.js", full_url, timeout.to_s)
|
|
||||||
|
|
||||||
raise "THEME TESTS FAILED!" if !$?.success?
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,339 +0,0 @@
|
||||||
/*eslint no-console: ["error", { allow: ["log", "error"] }] */
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
let 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, (unlinkErr) => {
|
|
||||||
if (unlinkErr) {
|
|
||||||
console.log("Error deleting " + QUNIT_RESULT + " " + unlinkErr);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runAllTests() {
|
|
||||||
function launchChrome() {
|
|
||||||
const options = {
|
|
||||||
chromeFlags: [
|
|
||||||
"--disable-gpu",
|
|
||||||
"--headless=new",
|
|
||||||
"--no-sandbox",
|
|
||||||
"--disable-dev-shm-usage",
|
|
||||||
"--mute-audio",
|
|
||||||
"--window-size=1440,900",
|
|
||||||
"--enable-precise-memory-info",
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
if (process.env.REMOTE_DEBUG) {
|
|
||||||
options.port = 9222;
|
|
||||||
}
|
|
||||||
|
|
||||||
return chromeLauncher.launch(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
let chrome = await launchChrome();
|
|
||||||
|
|
||||||
let protocol = null;
|
|
||||||
let connectAttempts = 0;
|
|
||||||
while (!protocol) {
|
|
||||||
// Workaround for intermittent CI error caused by
|
|
||||||
// https://github.com/GoogleChrome/chrome-launcher/issues/145
|
|
||||||
try {
|
|
||||||
protocol = await CDP({ port: chrome.port, host: "127.0.0.1" });
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message === "No inspectable targets" && connectAttempts < 50) {
|
|
||||||
connectAttempts++;
|
|
||||||
console.log(
|
|
||||||
"Unable to establish connection to chrome target - trying again..."
|
|
||||||
);
|
|
||||||
// eslint-disable-next-line
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { Inspector, Page, Runtime, Log } = protocol;
|
|
||||||
// eslint-disable-next-line
|
|
||||||
await Promise.all([
|
|
||||||
Inspector.enable(),
|
|
||||||
Page.enable(),
|
|
||||||
Runtime.enable(),
|
|
||||||
Log.enable(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Documentation https://chromedevtools.github.io/devtools-protocol/tot/Log/#type-LogEntry
|
|
||||||
Log.entryAdded(({ entry }) => {
|
|
||||||
let message = `${new Date(entry.timestamp).toISOString()} - (type: ${
|
|
||||||
entry.source
|
|
||||||
}/${entry.level}) message: ${entry.text}`;
|
|
||||||
if (entry.url) {
|
|
||||||
message += `, url: ${entry.url}`;
|
|
||||||
}
|
|
||||||
console.log(message);
|
|
||||||
});
|
|
||||||
|
|
||||||
Inspector.targetCrashed((entry) => {
|
|
||||||
console.log("Chrome target crashed:");
|
|
||||||
console.log(entry);
|
|
||||||
});
|
|
||||||
|
|
||||||
Runtime.exceptionThrown((exceptionInfo) => {
|
|
||||||
console.log(exceptionInfo.exceptionDetails.exception.description);
|
|
||||||
});
|
|
||||||
|
|
||||||
Runtime.consoleAPICalled((response) => {
|
|
||||||
const message = response["args"][0].value;
|
|
||||||
|
|
||||||
// Not finished yet, don't add a newline
|
|
||||||
if (message?.startsWith?.("↪")) {
|
|
||||||
process.stdout.write(message);
|
|
||||||
} else if (message?.startsWith?.("AUTOSPEC:")) {
|
|
||||||
fs.appendFileSync(QUNIT_RESULT, `${message.slice(10)}\n`);
|
|
||||||
} else {
|
|
||||||
console.log(...response["args"].map((m) => m.value));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let url = args[0] + "&qunit_disable_auto_start=1";
|
|
||||||
|
|
||||||
const apiKey = process.env.ADMIN_API_KEY;
|
|
||||||
const apiUsername = process.env.ADMIN_API_USERNAME;
|
|
||||||
if (apiKey && apiUsername) {
|
|
||||||
const { Fetch } = protocol;
|
|
||||||
await Fetch.enable();
|
|
||||||
const urlObj = new URL(url);
|
|
||||||
Fetch.requestPaused((data) => {
|
|
||||||
const requestURL = new URL(data.request.url);
|
|
||||||
if (requestURL.hostname !== urlObj.hostname) {
|
|
||||||
Fetch.continueRequest({
|
|
||||||
requestId: data.requestId,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Fetch.continueRequest({
|
|
||||||
requestId: data.requestId,
|
|
||||||
headers: [
|
|
||||||
{ name: "Api-Key", value: apiKey },
|
|
||||||
{ name: "Api-Username", value: apiUsername },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("navigate to", url);
|
|
||||||
Page.navigate({ url });
|
|
||||||
|
|
||||||
Page.loadEventFired(async () => {
|
|
||||||
let qff = process.env.QUNIT_FAIL_FAST;
|
|
||||||
await Runtime.evaluate({
|
|
||||||
expression:
|
|
||||||
`const QUNIT_FAIL_FAST = ` +
|
|
||||||
(qff === "1" || qff === "true").toString() +
|
|
||||||
";",
|
|
||||||
});
|
|
||||||
await Runtime.evaluate({
|
|
||||||
expression: `(${qunit_script})();`,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (args[0].includes("report_requests=1")) {
|
|
||||||
await Runtime.evaluate({
|
|
||||||
expression: "QUnit.config.logAllRequests = true",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const timeout = parseInt(args[1] || 300000, 10);
|
|
||||||
let start = Date.now();
|
|
||||||
|
|
||||||
let interval;
|
|
||||||
|
|
||||||
let runTests = async function () {
|
|
||||||
if (Date.now() > start + timeout) {
|
|
||||||
console.error("\n\nTests timed out\n");
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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 evaluated
|
|
||||||
function logQUnit() {
|
|
||||||
const QUnit = window.QUnit;
|
|
||||||
let testErrors = [];
|
|
||||||
let assertionErrors = [];
|
|
||||||
|
|
||||||
console.log("\nRunning: " + JSON.stringify(QUnit.urlParams) + "\n");
|
|
||||||
|
|
||||||
let durations = {};
|
|
||||||
|
|
||||||
let inTest = false;
|
|
||||||
QUnit.testStart(function (context) {
|
|
||||||
console.log("↪ " + context.module + "::" + context.name);
|
|
||||||
inTest = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
QUnit.testDone(function (context) {
|
|
||||||
durations[context.module + "::" + context.name] = context.runtime;
|
|
||||||
|
|
||||||
if (context.failed) {
|
|
||||||
const msg =
|
|
||||||
" Test Failed: " +
|
|
||||||
context.name +
|
|
||||||
assertionErrors.join(" ") +
|
|
||||||
"\n" +
|
|
||||||
context.source;
|
|
||||||
testErrors.push(msg);
|
|
||||||
assertionErrors = [];
|
|
||||||
|
|
||||||
// Pass QUNIT_FAIL_FAST on the command line to quit after the first failure
|
|
||||||
// eslint-disable-next-line
|
|
||||||
if (QUNIT_FAIL_FAST) {
|
|
||||||
QUnit.config.queue.length = 0;
|
|
||||||
}
|
|
||||||
if (inTest) {
|
|
||||||
console.log(" [✘]");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (inTest) {
|
|
||||||
console.log(" [✔]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inTest = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
QUnit.log(function (context) {
|
|
||||||
if (context.result) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let 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");
|
|
||||||
|
|
||||||
console.log("Slowest tests");
|
|
||||||
console.log("----------------------------------------------");
|
|
||||||
let ary = Object.keys(durations).map((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");
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("\n");
|
|
||||||
|
|
||||||
if (testErrors.length) {
|
|
||||||
console.log("Test Errors");
|
|
||||||
console.log("----------------------------------------------");
|
|
||||||
testErrors.forEach((e) => {
|
|
||||||
console.error(e);
|
|
||||||
});
|
|
||||||
console.log("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
let stats = [
|
|
||||||
"Time: " + context.runtime + "ms",
|
|
||||||
"Total: " + context.total,
|
|
||||||
"Passed: " + context.passed,
|
|
||||||
"Failed: " + context.failed,
|
|
||||||
];
|
|
||||||
console.log(stats.join(", "));
|
|
||||||
|
|
||||||
if (context.failed) {
|
|
||||||
console.log("\nUse this filter to run in the same order:");
|
|
||||||
console.log(
|
|
||||||
"QUNIT_FAIL_FAST=1 QUNIT_SEED=" +
|
|
||||||
QUnit.config.seed +
|
|
||||||
" rake qunit:test\n"
|
|
||||||
);
|
|
||||||
console.log("If you have a web environment running, you can visit:");
|
|
||||||
console.log(
|
|
||||||
"http://localhost:3000/qunit?hidepassed&seed=" +
|
|
||||||
QUnit.config.seed +
|
|
||||||
"\n\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.qunitDone = context;
|
|
||||||
});
|
|
||||||
|
|
||||||
QUnit.start();
|
|
||||||
}
|
|
||||||
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();
|
|
Loading…
Reference in New Issue