@nxextensions/firebase-cypress
Version:
An NX Plugin for Firebase Applications that would like to use emulators for E2E testing with Cypress
148 lines • 6.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.nxBaseCypressPreset = nxBaseCypressPreset;
exports.nxE2EPreset = nxE2EPreset;
const tslib_1 = require("tslib");
const devkit_1 = require("@nx/devkit");
const path_1 = require("path");
const fs_1 = require("fs");
// TODO: vitePreprocessor
const target_generator_1 = require("../target-generator");
const process = tslib_1.__importStar(require("node:process"));
const request_1 = tslib_1.__importDefault(require("../utils/request"));
const child_process_1 = require("child_process");
function nxBaseCypressPreset(pathToConfig, options) {
process.env.NX_CYPRESS_COMPONENT_TEST =
(options === null || options === void 0 ? void 0 : options.testingType) === 'component' ? 'true' : 'false';
const normalizedPath = (0, fs_1.lstatSync)(pathToConfig).isDirectory()
? pathToConfig
: (0, path_1.dirname)(pathToConfig);
const projectPath = (0, path_1.relative)(devkit_1.workspaceRoot, normalizedPath);
const offset = (0, path_1.relative)(normalizedPath, devkit_1.workspaceRoot);
const videosFolder = (0, path_1.join)(offset, 'dist', 'cypress', projectPath, 'videos');
const screenshotsFolder = (0, path_1.join)(offset, 'dist', 'cypress', projectPath, 'screenshots');
return {
chromeWebSecurity: false,
screenshotsFolder,
videosFolder
};
}
function nxE2EPreset(pathToConfig, options) {
var _a;
const basePath = (options === null || options === void 0 ? void 0 : options.cypressDir) || 'src';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const baseConfig = {
...nxBaseCypressPreset(pathToConfig),
fileServerFolder: '.',
supportFile: `${basePath}/support/e2e.{js,ts}`,
specPattern: `${basePath}/**/*.cy.{js,jsx,ts,tsx}`,
fixturesFolder: `${basePath}/fixtures`,
[target_generator_1.NX_PLUGIN_OPTIONS]: {
webServerCommand: (_a = options === null || options === void 0 ? void 0 : options.webServerCommands) === null || _a === void 0 ? void 0 : _a.default,
webServerCommands: options === null || options === void 0 ? void 0 : options.webServerCommands,
ciWebServerCommand: options === null || options === void 0 ? void 0 : options.ciWebServerCommand,
emulatorCommand: options === null || options === void 0 ? void 0 : options.emulatorCommand
},
async setupNodeEvents(on, config) {
var _a, _b, _c, _d;
const webServerCommands = (_a = config.env.webServerCommands) !== null && _a !== void 0 ? _a : options.webServerCommands;
const webServerCommand = (_b = config.env.webServerCommand) !== null && _b !== void 0 ? _b : webServerCommands === null || webServerCommands === void 0 ? void 0 : webServerCommands.default;
if ((options === null || options === void 0 ? void 0 : options.bundler) === 'vite') {
// TODO: vite preprocessor
}
if (!(options === null || options === void 0 ? void 0 : options.webServerCommands)) {
return;
}
if (!webServerCommand) {
return;
}
const baseUrl = config.baseUrl;
if (baseUrl && webServerCommand) {
if (await isServerUp(baseUrl)) {
if (((_c = options === null || options === void 0 ? void 0 : options.webServerConfig) === null || _c === void 0 ? void 0 : _c.reuseExistingServer) === undefined ? true : (_d = options === null || options === void 0 ? void 0 : options.webServerConfig) === null || _d === void 0 ? void 0 : _d.reuseExistingServer) {
console.log(`Reusing the server already running at ${baseUrl}`);
return;
}
throw new Error(`Web server is already running at ${baseUrl}`);
}
}
const killWebServer = startWebServer(webServerCommand);
on('after:run', () => {
killWebServer();
});
await waitForServer(baseUrl, options === null || options === void 0 ? void 0 : options.webServerConfig);
}
};
return baseConfig;
}
function isServerUp(url) {
return new Promise((res) => {
void (0, request_1.default)(url, () => res(true), () => res(false));
});
}
function startWebServer(webServerCommand) {
if (!validateCommand(webServerCommand)) {
throw new Error(`Command is in improper format: "${webServerCommand}" should be in the format of "[npx] nx run <targetForWebServer>"`);
}
const serverProcess = (0, child_process_1.spawn)(webServerCommand, {
cwd: devkit_1.workspaceRoot,
shell: true,
detached: process.platform !== 'win32',
stdio: 'inherit'
});
return () => {
if (process.platform === 'win32') {
(0, child_process_1.spawn)('taskkill', ['/pid', serverProcess.pid.toString(), '/f', '/t']);
}
else {
process.kill(-serverProcess.pid, 'SIGKILL');
}
};
}
function waitForServer(url, webServerConfig) {
return new Promise((resolve, reject) => {
var _a;
let pollTimeout;
const timeoutDuration = (_a = webServerConfig === null || webServerConfig === void 0 ? void 0 : webServerConfig.timeout) !== null && _a !== void 0 ? _a : 60 * 1000;
const timeout = setTimeout(() => {
clearTimeout(pollTimeout);
reject(new Error(`Web server failed to start in ${timeoutDuration / 1000}s. This can be configured in cypress.config.ts.`));
}, timeoutDuration);
function pollForServer() {
void (0, request_1.default)(url, () => {
clearTimeout(timeout);
resolve();
}, () => {
pollTimeout = setTimeout(pollForServer, 100);
});
}
pollForServer();
});
}
function validateCommand(command) {
if (!command.includes(' ')) {
return false;
}
const commandParts = command.split(' ');
let isValid = true;
for (let i = 0; i < commandParts.length; i++) {
const commandPart = commandParts[i];
if (i === 0) {
isValid = commandPart === 'nx' || commandPart === 'npx';
}
else if (i === 1) {
isValid = commandPart === 'nx' || commandPart === 'run';
}
else if (i === 2) {
isValid = commandPart.includes(':') || commandPart === 'run';
}
else {
isValid = commandPart.includes(':');
}
if (!isValid) {
return false;
}
}
return isValid;
}
//# sourceMappingURL=index.js.map