UNPKG

askui

Version:

Reliable, automated end-to-end-testing that depends on what is shown on your screen instead of the technology you are running on

291 lines (290 loc) 16.5 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CreateExampleProject = void 0; const path_1 = __importDefault(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const util_1 = require("util"); const child_process_1 = require("child_process"); const listr_1 = __importDefault(require("listr")); const chalk_1 = __importDefault(require("chalk")); const nunjucks_1 = __importDefault(require("nunjucks")); const yup_1 = require("yup"); const path_2 = require("../../utils/path"); const add_remove_script_package_json_1 = require("./add-remove-script-package-json"); class CreateExampleProject { constructor(cliOptions) { this.cliOptions = cliOptions; this.exampleTemplateDirectoryName = 'askui_example'; this.projectRootDirectoryPath = process.cwd(); this.automationsDirectoryName = this.getAutomationsDirectoryName(); this.automationsDirectoryPath = path_1.default.join(this.projectRootDirectoryPath, this.automationsDirectoryName); this.askUIControllerUrl = 'https://docs.askui.com/docs/suite/Components/AskUI-Development-Environment#askui-startcontroller-command'; this.helperTemplateConfig = {}; } getAutomationsDirectoryName() { if (this.cliOptions.automationsDirectory) { if (/\s/g.test(this.cliOptions.automationsDirectory.trim())) { throw new yup_1.ValidationError('Automations directory (-ad, --automations-directory) must not contain whitespaces'); } return this.cliOptions.automationsDirectory.trim(); } return this.exampleTemplateDirectoryName; } copyTemplateProject() { return __awaiter(this, void 0, void 0, function* () { const exampleProjectPath = path_1.default.join('example_projects_templates', 'typescript', this.exampleTemplateDirectoryName); const runCommand = (0, util_1.promisify)(child_process_1.exec); return [ { title: 'Detect Operating System', task: () => __awaiter(this, void 0, void 0, function* () { if (process.platform === 'win32') { this.cliOptions.operatingSystem = 'windows'; } else if (process.platform === 'darwin') { this.cliOptions.operatingSystem = 'macos'; } else if (process.platform === 'linux' || process.platform === 'freebsd' || process.platform === 'openbsd') { this.cliOptions.operatingSystem = 'linux'; } else { throw new Error(`The detected operating system is ${process.platform}. We only support 'windows', 'macos' and 'linux'`); } }), }, { title: 'Copy project files', task: () => __awaiter(this, void 0, void 0, function* () { return fs_extra_1.default.copy(path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), exampleProjectPath), this.automationsDirectoryPath); }), }, { title: 'Install askui dependency', task: () => __awaiter(this, void 0, void 0, function* () { yield runCommand('npm init -y'); yield (0, add_remove_script_package_json_1.removeScript)(`${this.projectRootDirectoryPath}/package.json`, 'test'); yield runCommand('npm i -D askui '); }), }, ]; }); } copyTestFrameworkConfig() { return __awaiter(this, void 0, void 0, function* () { const frameworkConfigs = { jest: 'jest.config.ts', }; const configFilePath = path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), 'example_projects_templates', 'configs', frameworkConfigs.jest); yield fs_extra_1.default.copyFile(configFilePath, path_1.default.join(this.automationsDirectoryPath, frameworkConfigs.jest)); }); } addTestFrameWorkTimeout() { return __awaiter(this, void 0, void 0, function* () { const frameworkTimeoutstring = { jest: 'jest.setTimeout(60 * 1000 * 60);', }; this.helperTemplateConfig['timeout_placeholder'] = frameworkTimeoutstring.jest; }); } addReporterConfig() { return __awaiter(this, void 0, void 0, function* () { this.helperTemplateConfig['allure_stepreporter_import'] = "import { AskUIAllureStepReporter } from '@askui/askui-reporters';"; this.helperTemplateConfig['reporter_placeholder'] = 'reporter: new AskUIAllureStepReporter(),'; this.helperTemplateConfig['allure_stepreporter_attach_video'] = `const video = await aui.readVideoRecording(); await AskUIAllureStepReporter.attachVideo(video);`; }); } addAskuiRunCommand() { return __awaiter(this, void 0, void 0, function* () { const frameworkExecutionCommand = { jest: `jest --config ./${this.automationsDirectoryName}/jest.config.ts --runInBand`, }; yield (0, add_remove_script_package_json_1.addScript)(`${this.projectRootDirectoryPath}/package.json`, 'askui', frameworkExecutionCommand.jest); }); } addESLintRunCommand() { return __awaiter(this, void 0, void 0, function* () { yield (0, add_remove_script_package_json_1.addScript)(`${this.projectRootDirectoryPath}/package.json`, 'lint', 'eslint . --ext .ts'); }); } createAskUIHelperFromTemplate() { return __awaiter(this, void 0, void 0, function* () { return [{ title: 'Write askui config', task: () => __awaiter(this, void 0, void 0, function* () { return new listr_1.default([ { title: 'Create askui-helper.ts ', task: () => __awaiter(this, void 0, void 0, function* () { const askuiHelperTemplateFilePath = path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), 'example_projects_templates', 'templates'); const templateFileName = 'askui-helper.nj'; nunjucks_1.default.configure(askuiHelperTemplateFilePath, { autoescape: false }); const result = nunjucks_1.default.render(templateFileName, this.helperTemplateConfig); const filePath = path_1.default.join(this.automationsDirectoryPath, 'helpers', 'askui-helper.ts'); if (!fs_extra_1.default.existsSync(path_1.default.join(this.automationsDirectoryPath, 'helpers'))) { yield fs_extra_1.default.mkdir(path_1.default.join(this.automationsDirectoryPath, 'helpers')); } yield fs_extra_1.default.writeFile(filePath, result, 'utf8'); }), }, ]); }), }]; }); } setupTestFrameWork() { return __awaiter(this, void 0, void 0, function* () { return [{ title: 'Setup Test framework', task: () => __awaiter(this, void 0, void 0, function* () { return new listr_1.default([ { title: 'Install jest', task: () => __awaiter(this, void 0, void 0, function* () { return CreateExampleProject.installTestFrameworkPackages(); }), }, { title: 'Copy config file', task: () => __awaiter(this, void 0, void 0, function* () { return this.copyTestFrameworkConfig(); }), }, { title: 'Add timeout', task: () => __awaiter(this, void 0, void 0, function* () { return this.addTestFrameWorkTimeout(); }), }, { title: 'Add reporter', task: () => __awaiter(this, void 0, void 0, function* () { return this.addReporterConfig(); }), }, { title: 'Add askui run command', task: () => __awaiter(this, void 0, void 0, function* () { return this.addAskuiRunCommand(); }), }, { title: 'Add eslint run command', task: () => __awaiter(this, void 0, void 0, function* () { return this.addESLintRunCommand(); }), }, ]); }), }]; }); } static installTestFrameworkPackages() { return __awaiter(this, void 0, void 0, function* () { const runCommand = (0, util_1.promisify)(child_process_1.exec); const frameworkDependencies = { jest: 'npm i -D @askui/askui-reporters typescript ts-node @types/jest@30.0.0 ts-jest@29.4.0 jest@29.7.0 @askui/jest-allure-circus eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-import @askui/eslint-plugin-askui hpagent', }; yield runCommand(frameworkDependencies.jest); }); } copyESLintConfigFiles() { return __awaiter(this, void 0, void 0, function* () { const esLintRcFilePath = path_1.default.join('example_projects_templates', 'typescript', '.eslintrc.json-template'); const esLintIgnoreFilePath = path_1.default.join('example_projects_templates', 'typescript', '.eslintignore-template'); return [{ title: 'Copy ESLint config files', task: () => __awaiter(this, void 0, void 0, function* () { return new listr_1.default([ { title: 'Add eslintrc.json', task: () => __awaiter(this, void 0, void 0, function* () { return fs_extra_1.default.copyFile(path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), esLintRcFilePath), path_1.default.join(this.projectRootDirectoryPath, '.eslintrc.json')); }), }, { title: 'Add .eslintignore', task: () => __awaiter(this, void 0, void 0, function* () { return fs_extra_1.default.copyFile(path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), esLintIgnoreFilePath), path_1.default.join(this.projectRootDirectoryPath, '.eslintignore')); }), }, ]); }), }, ]; }); } copyGitignore() { return __awaiter(this, void 0, void 0, function* () { const gitignoreFilePath = path_1.default.join('example_projects_templates', 'typescript', 'gitignore'); return [{ title: 'Copy .gitignore', task: () => __awaiter(this, void 0, void 0, function* () { return new listr_1.default([ { title: 'Add .gitignore', task: () => __awaiter(this, void 0, void 0, function* () { return fs_extra_1.default.copyFile(path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), gitignoreFilePath), path_1.default.join(this.projectRootDirectoryPath, '.gitignore')); }), }, ]); }), }, ]; }); } addVSCodeSettings() { return __awaiter(this, void 0, void 0, function* () { const vscodeSettingsFilePath = path_1.default.join('example_projects_templates', 'configs', 'vscode-settings.json'); const vscodeSettingsTargetDirPath = path_1.default.join(this.projectRootDirectoryPath, '.vscode'); const vscodeSettingsTargetFilePath = path_1.default.join(vscodeSettingsTargetDirPath, 'settings.json'); return [{ enabled: () => !fs_extra_1.default.existsSync(vscodeSettingsTargetFilePath), task: () => __awaiter(this, void 0, void 0, function* () { yield fs_extra_1.default.mkdir(vscodeSettingsTargetDirPath, { recursive: true }); yield fs_extra_1.default.copyFile(path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), vscodeSettingsFilePath), vscodeSettingsTargetFilePath); }), title: 'Copy VSCode settings', }]; }); } copyTsConfigFile() { return __awaiter(this, void 0, void 0, function* () { const tsConfigFilePath = path_1.default.join('example_projects_templates', 'typescript', 'tsconfig.json'); const tsConfigTargetFilePath = path_1.default.join(this.projectRootDirectoryPath, 'tsconfig.json'); return [ { enabled: () => this.cliOptions.typescriptConfig || !fs_extra_1.default.existsSync(tsConfigTargetFilePath), task: () => __awaiter(this, void 0, void 0, function* () { return fs_extra_1.default.copyFile(path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), tsConfigFilePath), tsConfigTargetFilePath); }), title: 'Copy ts config file', }, ]; }); } createExampleProject() { return __awaiter(this, void 0, void 0, function* () { const tasks = new listr_1.default(); tasks.add([ ...(yield this.copyTemplateProject()), ...(yield this.addVSCodeSettings()), ...(yield this.setupTestFrameWork()), ...(yield this.copyESLintConfigFiles()), ...(yield this.copyGitignore()), ...(yield this.copyTsConfigFile()), ...(yield this.createAskUIHelperFromTemplate()), ]); yield tasks.run(); /* eslint-disable no-console */ console.log(chalk_1.default.greenBright('\nCongratulations!')); console.log(`askui example was created under ${chalk_1.default.gray(this.automationsDirectoryPath)}`); console.log(chalk_1.default.redBright(`\nPlease make sure the AskUI Controller is running: ${this.askUIControllerUrl}\n`)); console.log(`You can start your automation with this command ${chalk_1.default.green('AskUI-RunProject')}`); /* eslint-enable no-console */ }); } } exports.CreateExampleProject = CreateExampleProject;