UNPKG

firebase-tools

Version:
103 lines (102 loc) 4.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.command = void 0; const requireAuth_1 = require("../requireAuth"); const command_1 = require("../command"); const requireConfig_1 = require("../requireConfig"); const logger_1 = require("../logger"); const clc = require("colorette"); const parseTestFiles_1 = require("../apptesting/parseTestFiles"); const ora = require("ora"); const invokeTests_1 = require("../apptesting/invokeTests"); const error_1 = require("../error"); const marked_1 = require("marked"); const projectUtils_1 = require("../projectUtils"); const utils_1 = require("../utils"); const apps_1 = require("../management/apps"); exports.command = new command_1.Command("apptesting:execute <target>") .description("Run automated tests written in natural language driven by AI") .option("--app <app_id>", "The app id of your Firebase web app. Optional if the project contains exactly one web app.") .option("--test-file-pattern <pattern>", "Test file pattern. Only tests contained in files that match this pattern will be executed.") .option("--test-name-pattern <pattern>", "Test name pattern. Only tests with names that match this pattern will be executed.") .option("--tests-non-blocking", "Request test execution without waiting for them to complete.") .before(requireAuth_1.requireAuth) .before(requireConfig_1.requireConfig) .action(async (target, options) => { var _a, _b; const projectId = (0, projectUtils_1.needProjectId)(options); const appList = await (0, apps_1.listFirebaseApps)(projectId, apps_1.AppPlatform.WEB); let app = appList.find((a) => a.appId === options.app); if (!app && appList.length === 1) { app = appList[0]; logger_1.logger.info(`No app specified, defaulting to ${app.appId}`); } else if (!app) { throw new error_1.FirebaseError("Invalid app id"); } const testDir = ((_a = options.config.src.apptesting) === null || _a === void 0 ? void 0 : _a.testDir) || "tests"; const tests = await (0, parseTestFiles_1.parseTestFiles)(testDir, target, options.testFilePattern, options.testNamePattern); if (!tests.length) { throw new error_1.FirebaseError("No tests found"); } const invokeSpinner = ora("Requesting test execution"); invokeSpinner.start(); let invocationOperation; try { invocationOperation = await (0, invokeTests_1.invokeTests)(app.appId, target, tests); invokeSpinner.text = "Test execution requested"; invokeSpinner.succeed(); } catch (ex) { invokeSpinner.fail("Failed to request test execution"); throw ex; } logger_1.logger.info(clc.bold(`\n${clc.white("===")} Running ${pluralizeTests(tests.length)}`)); const invocationId = (_b = invocationOperation.name) === null || _b === void 0 ? void 0 : _b.split("/").pop(); const appWebId = app.webId; const url = (0, utils_1.consoleUrl)(projectId, `/apptesting/app/web:${appWebId}/invocations/${invocationId}`); logger_1.logger.info(await (0, marked_1.marked)(`**Invocation ID:** ${invocationId}`)); logger_1.logger.info(await (0, marked_1.marked)(`View progress and results in the [Firebase Console](${url})`)); if (options.testsNonBlocking) { logger_1.logger.info("Not waiting for results"); return; } if (!invocationOperation.metadata) { throw new error_1.FirebaseError("Invocation details unavailable"); } const executionSpinner = ora(getOutput(invocationOperation.metadata)); executionSpinner.start(); const invocationOp = await (0, invokeTests_1.pollInvocationStatus)(invocationOperation.name, (operation) => { if (!operation.done) { executionSpinner.text = getOutput(operation.metadata); } }); const response = invocationOp.resource.testInvocation; executionSpinner.text = `Testing complete\n${getOutput(response)}`; if (response.failedExecutions || response.cancelledExecutions) { executionSpinner.fail(); throw new error_1.FirebaseError("Testing complete with errors"); } else { executionSpinner.succeed(); } }); function pluralizeTests(numTests) { return `${numTests} test${numTests === 1 ? "" : "s"}`; } function getOutput(invocation) { const output = []; if (invocation.runningExecutions) { output.push(`${pluralizeTests(invocation.runningExecutions)} running (this may take a while)...`); } if (invocation.succeededExecutions) { output.push(`✔ ${pluralizeTests(invocation.succeededExecutions)} passed`); } if (invocation.failedExecutions) { output.push(`✖ ${pluralizeTests(invocation.failedExecutions)} failed`); } if (invocation.cancelledExecutions) { output.push(`⊝ ${pluralizeTests(invocation.cancelledExecutions)} cancelled`); } return output.length ? output.join("\n") : "Tests are starting"; }