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

284 lines (283 loc) 15.3 kB
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()); }); }; import path from 'path'; import fs from 'fs-extra'; import { promisify } from 'util'; import { exec } from 'child_process'; import Listr from 'listr'; import chalk from 'chalk'; import nunjucks from 'nunjucks'; import { ValidationError } from 'yup'; import { getPathToNodeModulesRoot } from '../../utils/path'; import { addScript, removeScript } from './add-remove-script-package-json'; export class CreateExampleProject { constructor(cliOptions) { this.cliOptions = cliOptions; this.exampleTemplateDirectoryName = 'askui_example'; this.projectRootDirectoryPath = process.cwd(); this.automationsDirectoryName = this.getAutomationsDirectoryName(); this.automationsDirectoryPath = path.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 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.join('example_projects_templates', 'typescript', this.exampleTemplateDirectoryName); const runCommand = promisify(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.copy(path.join(getPathToNodeModulesRoot(), exampleProjectPath), this.automationsDirectoryPath); }), }, { title: 'Install askui dependency', task: () => __awaiter(this, void 0, void 0, function* () { yield runCommand('npm init -y'); yield 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.join(getPathToNodeModulesRoot(), 'example_projects_templates', 'configs', frameworkConfigs.jest); yield fs.copyFile(configFilePath, path.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 addScript(`${this.projectRootDirectoryPath}/package.json`, 'askui', frameworkExecutionCommand.jest); }); } addESLintRunCommand() { return __awaiter(this, void 0, void 0, function* () { yield 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([ { title: 'Create askui-helper.ts ', task: () => __awaiter(this, void 0, void 0, function* () { const askuiHelperTemplateFilePath = path.join(getPathToNodeModulesRoot(), 'example_projects_templates', 'templates'); const templateFileName = 'askui-helper.nj'; nunjucks.configure(askuiHelperTemplateFilePath, { autoescape: false }); const result = nunjucks.render(templateFileName, this.helperTemplateConfig); const filePath = path.join(this.automationsDirectoryPath, 'helpers', 'askui-helper.ts'); if (!fs.existsSync(path.join(this.automationsDirectoryPath, 'helpers'))) { yield fs.mkdir(path.join(this.automationsDirectoryPath, 'helpers')); } yield fs.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([ { 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 = promisify(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.join('example_projects_templates', 'typescript', '.eslintrc.json-template'); const esLintIgnoreFilePath = path.join('example_projects_templates', 'typescript', '.eslintignore-template'); return [{ title: 'Copy ESLint config files', task: () => __awaiter(this, void 0, void 0, function* () { return new Listr([ { title: 'Add eslintrc.json', task: () => __awaiter(this, void 0, void 0, function* () { return fs.copyFile(path.join(getPathToNodeModulesRoot(), esLintRcFilePath), path.join(this.projectRootDirectoryPath, '.eslintrc.json')); }), }, { title: 'Add .eslintignore', task: () => __awaiter(this, void 0, void 0, function* () { return fs.copyFile(path.join(getPathToNodeModulesRoot(), esLintIgnoreFilePath), path.join(this.projectRootDirectoryPath, '.eslintignore')); }), }, ]); }), }, ]; }); } copyGitignore() { return __awaiter(this, void 0, void 0, function* () { const gitignoreFilePath = path.join('example_projects_templates', 'typescript', 'gitignore'); return [{ title: 'Copy .gitignore', task: () => __awaiter(this, void 0, void 0, function* () { return new Listr([ { title: 'Add .gitignore', task: () => __awaiter(this, void 0, void 0, function* () { return fs.copyFile(path.join(getPathToNodeModulesRoot(), gitignoreFilePath), path.join(this.projectRootDirectoryPath, '.gitignore')); }), }, ]); }), }, ]; }); } addVSCodeSettings() { return __awaiter(this, void 0, void 0, function* () { const vscodeSettingsFilePath = path.join('example_projects_templates', 'configs', 'vscode-settings.json'); const vscodeSettingsTargetDirPath = path.join(this.projectRootDirectoryPath, '.vscode'); const vscodeSettingsTargetFilePath = path.join(vscodeSettingsTargetDirPath, 'settings.json'); return [{ enabled: () => !fs.existsSync(vscodeSettingsTargetFilePath), task: () => __awaiter(this, void 0, void 0, function* () { yield fs.mkdir(vscodeSettingsTargetDirPath, { recursive: true }); yield fs.copyFile(path.join(getPathToNodeModulesRoot(), vscodeSettingsFilePath), vscodeSettingsTargetFilePath); }), title: 'Copy VSCode settings', }]; }); } copyTsConfigFile() { return __awaiter(this, void 0, void 0, function* () { const tsConfigFilePath = path.join('example_projects_templates', 'typescript', 'tsconfig.json'); const tsConfigTargetFilePath = path.join(this.projectRootDirectoryPath, 'tsconfig.json'); return [ { enabled: () => this.cliOptions.typescriptConfig || !fs.existsSync(tsConfigTargetFilePath), task: () => __awaiter(this, void 0, void 0, function* () { return fs.copyFile(path.join(getPathToNodeModulesRoot(), tsConfigFilePath), tsConfigTargetFilePath); }), title: 'Copy ts config file', }, ]; }); } createExampleProject() { return __awaiter(this, void 0, void 0, function* () { const tasks = new Listr(); 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.greenBright('\nCongratulations!')); console.log(`askui example was created under ${chalk.gray(this.automationsDirectoryPath)}`); console.log(chalk.redBright(`\nPlease make sure the AskUI Controller is running: ${this.askUIControllerUrl}\n`)); console.log(`You can start your automation with this command ${chalk.green('AskUI-RunProject')}`); /* eslint-enable no-console */ }); } }