@qavajs/create 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.MD CHANGED
@@ -10,6 +10,12 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
10
10
 
11
11
  :x: - deprecation
12
12
 
13
+ ## [2.3.0]
14
+ - :rocket: removed ejs and fs-extra dependencies
15
+
16
+ ## [2.2.2]
17
+ - :beetle: fixed issue with mandatory ESM js extension
18
+
13
19
  ## [2.2.1]
14
20
  - :beetle: fixed readme template
15
21
 
package/README.md CHANGED
@@ -12,4 +12,8 @@ npm init @qavajs
12
12
 
13
13
  ```
14
14
  npm run test
15
- ```
15
+ ```
16
+
17
+ ## Dependencies
18
+
19
+ - [`@inquirer/prompts`](https://github.com/SBoudrias/Inquirer.js) — interactive CLI prompts
package/lib/install.js CHANGED
@@ -32,19 +32,9 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
35
  Object.defineProperty(exports, "__esModule", { value: true });
45
36
  exports.default = install;
46
37
  const promises_1 = require("node:fs/promises");
47
- const fs_extra_1 = require("fs-extra");
48
38
  const node_path_1 = require("node:path");
49
39
  const node_child_process_1 = require("node:child_process");
50
40
  function installModules({ deps, cwd }) {
@@ -52,7 +42,6 @@ function installModules({ deps, cwd }) {
52
42
  (0, node_child_process_1.execSync)(`npm install ${modules}`, { cwd });
53
43
  }
54
44
  const deps_1 = __importStar(require("./deps"));
55
- const ejs_1 = require("ejs");
56
45
  const prompts_1 = require("@inquirer/prompts");
57
46
  const packs = (deps) => deps.map(({ module }) => ({ value: module }));
58
47
  const packages = (moduleList, packageMap) => {
@@ -73,123 +62,220 @@ const requireGlob = (moduleList, packageMap) => {
73
62
  return `node_modules/${pkg.packageName}/index.js`;
74
63
  });
75
64
  };
76
- const replaceNewLines = (text) => text.replace(/(\r?\n\r?)+/g, '\n');
77
- function install() {
78
- return __awaiter(this, void 0, void 0, function* () {
79
- const requiredDeps = [...deps_1.default];
80
- const answers = {
81
- moduleSystem: yield (0, prompts_1.select)({
82
- message: 'select module system you want to use:',
83
- choices: [
84
- { value: 'CommonJS' },
85
- { value: 'ES Modules' },
86
- { value: 'Typescript' }
87
- ]
88
- }),
89
- steps: yield (0, prompts_1.checkbox)({
90
- message: 'select step packages to install:',
91
- choices: packs(deps_1.steps)
92
- }),
93
- formats: yield (0, prompts_1.checkbox)({
94
- message: 'select formatters (reporters) to install:',
95
- choices: packs(deps_1.format)
96
- })
97
- };
98
- const stepsPackages = ['@qavajs/steps-memory@2', ...packages(answers.steps, deps_1.steps)];
99
- const formatPackages = packages(answers.formats, deps_1.format);
100
- const isTypescript = answers.moduleSystem === 'Typescript';
101
- const isWdioIncluded = answers.steps.includes('wdio');
102
- const isPlaywrightIncluded = answers.steps.includes('playwright');
103
- const isApiIncluded = answers.steps.includes('api');
104
- //checking if user selected only one browser driver
105
- if (isPlaywrightIncluded && isWdioIncluded) {
106
- throw new Error('Please select only one browser driver');
107
- }
108
- const isPOIncluded = isWdioIncluded || isPlaywrightIncluded;
109
- // add gitignore
110
- const gitignoreTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/gitignore'), 'utf-8');
111
- yield (0, promises_1.writeFile)(`./.gitignore`, gitignoreTemplate, 'utf-8');
112
- // add package.json
113
- const packageJsonTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/package.json'), 'utf-8');
114
- yield (0, promises_1.writeFile)(`./package.json`, packageJsonTemplate, 'utf-8');
115
- // add ts-node and typescript packages if module system is typescript
116
- // put tsconfig
117
- if (isTypescript) {
118
- requiredDeps.push('ts-node');
119
- requiredDeps.push('typescript');
120
- const tsconfig = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/tsconfig.json'), 'utf-8');
121
- yield (0, promises_1.writeFile)(`./tsconfig.json`, tsconfig, 'utf-8');
122
- }
123
- const configTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/config.ejs'), 'utf-8');
124
- const configEjs = (0, ejs_1.compile)(configTemplate);
125
- const stepDefinitionGlob = `step_definition/*.${isTypescript ? 'ts' : 'js'}`;
126
- const stepsPackagesGlobs = ['node_modules/@qavajs/steps-memory/index.js', ...requireGlob(answers.steps, deps_1.steps)];
127
- const config = configEjs({
128
- steps: JSON.stringify([...stepsPackagesGlobs, stepDefinitionGlob]),
129
- moduleSystem: answers.moduleSystem,
130
- format: JSON.stringify(deps_1.format
131
- .filter(p => formatPackages.includes(p.packageName))
132
- .map(p => p.out ? [p.packageName, p.out] : p.packageName)),
133
- isWdioIncluded,
134
- isPlaywrightIncluded,
135
- });
136
- yield (0, fs_extra_1.ensureDir)('./features');
137
- yield (0, fs_extra_1.ensureDir)('./memory');
138
- yield (0, fs_extra_1.ensureDir)('./report');
139
- yield (0, fs_extra_1.ensureDir)('./step_definition');
140
- if (isPOIncluded) {
141
- let poModule;
142
- if (isWdioIncluded)
143
- poModule = '@qavajs/steps-wdio/po';
144
- if (isPlaywrightIncluded)
145
- poModule = '@qavajs/steps-playwright/po';
146
- if (!poModule)
147
- throw new Error('No PO module');
148
- const featureTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/feature.ejs'), 'utf-8');
149
- const featureEjs = (0, ejs_1.compile)(featureTemplate);
150
- const featureFile = featureEjs();
151
- yield (0, promises_1.writeFile)('./features/qavajs.feature', replaceNewLines(featureFile), 'utf-8');
152
- //create page object folder
153
- yield (0, fs_extra_1.ensureDir)('./page_object');
154
- const poTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/po.ejs'), 'utf-8');
155
- const poEjs = (0, ejs_1.compile)(poTemplate);
156
- const poFile = poEjs({
157
- moduleSystem: answers.moduleSystem,
158
- poModule
159
- });
160
- yield (0, promises_1.writeFile)(`./page_object/index.${isTypescript ? 'ts' : 'js'}`, replaceNewLines(poFile), 'utf-8');
161
- }
162
- if (isApiIncluded) {
163
- const featureTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/featureApi.ejs'), 'utf-8');
164
- const featureEjs = (0, ejs_1.compile)(featureTemplate);
165
- const featureFile = featureEjs();
166
- yield (0, promises_1.writeFile)('./features/qavajsApi.feature', replaceNewLines(featureFile), 'utf-8');
167
- }
168
- yield (0, promises_1.writeFile)(`config.${isTypescript ? 'ts' : 'js'}`, replaceNewLines(config), 'utf-8');
169
- const memoryTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/memory.ejs'), 'utf-8');
170
- const memoryEjs = (0, ejs_1.compile)(memoryTemplate);
171
- const memoryFile = memoryEjs({
172
- moduleSystem: answers.moduleSystem
173
- });
174
- yield (0, promises_1.writeFile)(`./memory/index.${isTypescript ? 'ts' : 'js'}`, replaceNewLines(memoryFile), 'utf-8');
175
- const readmeTemplate = yield (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/readme.ejs'), 'utf-8');
176
- const readmeEjs = (0, ejs_1.compile)(readmeTemplate);
177
- const readmeFile = readmeEjs({
178
- moduleSystem: answers.moduleSystem
179
- });
180
- yield (0, promises_1.writeFile)(`./README.MD`, replaceNewLines(readmeFile), 'utf-8');
181
- const modulesToInstall = [
182
- ...requiredDeps,
183
- ...stepsPackages,
184
- ...formatPackages,
65
+ function generateConfig({ steps, moduleSystem, format, isWdioIncluded, isPlaywrightIncluded }) {
66
+ const isESM = moduleSystem === 'ES Modules';
67
+ const isPOIncluded = isWdioIncluded || isPlaywrightIncluded;
68
+ const browserName = isWdioIncluded ? '"chrome"' : '"chromium"';
69
+ if (moduleSystem === 'CommonJS') {
70
+ const lines = [
71
+ `const Memory = require("./memory");`,
72
+ ...(isPOIncluded ? [`const App = require("./page_object");`] : []),
73
+ `module.exports = {`,
74
+ ` default: {`,
75
+ ` paths: ["features/**/*.feature"],`,
76
+ ` require: ${steps},`,
77
+ ` format: ${format},`,
78
+ ` memory: new Memory(),`,
79
+ ...(isPOIncluded ? [
80
+ ` pageObject: new App(),`,
81
+ ` browser: {`,
82
+ ` capabilities: {`,
83
+ ` browserName: ${browserName}`,
84
+ ` }`,
85
+ ` },`,
86
+ ] : []),
87
+ ` }`,
88
+ `}`,
89
+ ];
90
+ return lines.join('\n') + '\n';
91
+ }
92
+ else {
93
+ const ext = isESM ? '/index.js' : '';
94
+ const importKey = isESM ? 'import' : 'require';
95
+ const lines = [
96
+ `import Memory from "./memory${ext}";`,
97
+ ...(isPOIncluded ? [`import App from "./page_object${ext}";`] : []),
98
+ `export default {`,
99
+ ` paths: ["features/**/*.feature"],`,
100
+ ` ${importKey}: ${steps},`,
101
+ ` format: ${format},`,
102
+ ` memory: new Memory(),`,
103
+ ...(isPOIncluded ? [
104
+ ` pageObject: new App(),`,
105
+ ` browser: {`,
106
+ ` capabilities: {`,
107
+ ` browserName: ${browserName}`,
108
+ ` }`,
109
+ ` },`,
110
+ ] : []),
111
+ `}`,
185
112
  ];
186
- console.log('installing packages...');
187
- console.log(modulesToInstall);
188
- installModules({
189
- deps: modulesToInstall,
190
- cwd: process.cwd()
191
- });
192
- console.log('test script:');
193
- console.log(`npx qavajs --config config.${isTypescript ? 'ts' : 'js'}`);
113
+ return lines.join('\n') + '\n';
114
+ }
115
+ }
116
+ function generateMemory(moduleSystem) {
117
+ const prefix = (moduleSystem === 'ES Modules' || moduleSystem === 'Typescript') ? 'export default ' : 'module.exports = ';
118
+ return `${prefix}class Constants {\n}\n`;
119
+ }
120
+ function generatePo(moduleSystem, poModule) {
121
+ const isESM = moduleSystem === 'ES Modules';
122
+ const isESMorTS = isESM || moduleSystem === 'Typescript';
123
+ const ext = isESM ? '.js' : '';
124
+ if (isESMorTS) {
125
+ return [
126
+ `import { locator } from "${poModule}${ext}";`,
127
+ `export default class App {`,
128
+ ` Body = locator("body");`,
129
+ ` GetStartedButton = locator("a.button[href='/docs/intro']");`,
130
+ `}`,
131
+ '',
132
+ ].join('\n');
133
+ }
134
+ else {
135
+ return [
136
+ `const { locator } = require("${poModule}");`,
137
+ `module.exports = class App {`,
138
+ ` Body = locator("body");`,
139
+ ` GetStartedButton = locator("a.button[href='/docs/intro']");`,
140
+ `}`,
141
+ '',
142
+ ].join('\n');
143
+ }
144
+ }
145
+ function generateReadme(moduleSystem) {
146
+ const ext = moduleSystem === 'Typescript' ? 'ts' : 'js';
147
+ return [
148
+ `# qavajs`,
149
+ `## Docs`,
150
+ `https://qavajs.github.io/`,
151
+ `## Install Modules`,
152
+ '```bash',
153
+ `npm install`,
154
+ '```',
155
+ `## Execute Tests`,
156
+ '```bash',
157
+ `npx qavajs run --config config.${ext}`,
158
+ '```',
159
+ `## Project Structure`,
160
+ `- [config](./config.${ext}) - main config`,
161
+ `- [features](./features) - test cases`,
162
+ `- [memory](./memory) - test data`,
163
+ `- [page_object](./page_object) - page objects`,
164
+ `- [step_definition](./step_definition) - custom step definitions`,
165
+ `- [report](./report) - reports`,
166
+ '',
167
+ ].join('\n');
168
+ }
169
+ const featureTemplate = [
170
+ `Feature: qavajs framework`,
171
+ ` Scenario: Open qavajs docs`,
172
+ ` Given I open 'https://qavajs.github.io/' url`,
173
+ ` Then I expect text of 'Body' to contain 'qavajs'`,
174
+ '',
175
+ ].join('\n');
176
+ const featureApiTemplate = [
177
+ `Feature: qavajs framework`,
178
+ ` Scenario: Request qavajs site`,
179
+ ` When I create 'GET' request 'request'`,
180
+ ` And I add 'https://qavajs.github.io/' url to '$request'`,
181
+ ` And I send '$request' request and save response as 'response'`,
182
+ ` And I parse '$response' body as text`,
183
+ ` Then I expect '$response.payload' contains '@qavajs'`,
184
+ '',
185
+ ].join('\n');
186
+ async function install() {
187
+ const requiredDeps = [...deps_1.default];
188
+ const answers = {
189
+ moduleSystem: await (0, prompts_1.select)({
190
+ message: 'select module system you want to use:',
191
+ choices: [
192
+ { value: 'CommonJS' },
193
+ { value: 'ES Modules' },
194
+ { value: 'Typescript' }
195
+ ]
196
+ }),
197
+ steps: await (0, prompts_1.checkbox)({
198
+ message: 'select step packages to install:',
199
+ choices: packs(deps_1.steps)
200
+ }),
201
+ formats: await (0, prompts_1.checkbox)({
202
+ message: 'select formatters (reporters) to install:',
203
+ choices: packs(deps_1.format)
204
+ })
205
+ };
206
+ const stepsPackages = ['@qavajs/steps-memory@2', ...packages(answers.steps, deps_1.steps)];
207
+ const formatPackages = packages(answers.formats, deps_1.format);
208
+ const isTypescript = answers.moduleSystem === 'Typescript';
209
+ const isWdioIncluded = answers.steps.includes('wdio');
210
+ const isPlaywrightIncluded = answers.steps.includes('playwright');
211
+ const isApiIncluded = answers.steps.includes('api');
212
+ //checking if user selected only one browser driver
213
+ if (isPlaywrightIncluded && isWdioIncluded) {
214
+ throw new Error('Please select only one browser driver');
215
+ }
216
+ const isPOIncluded = isWdioIncluded || isPlaywrightIncluded;
217
+ // add gitignore
218
+ const gitignoreTemplate = await (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/gitignore'), 'utf-8');
219
+ await (0, promises_1.writeFile)(`./.gitignore`, gitignoreTemplate, 'utf-8');
220
+ // add package.json
221
+ const packageJsonTemplate = await (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/package.json'), 'utf-8');
222
+ await (0, promises_1.writeFile)(`./package.json`, packageJsonTemplate, 'utf-8');
223
+ // add ts-node and typescript packages if module system is typescript
224
+ // put tsconfig
225
+ if (isTypescript) {
226
+ requiredDeps.push('ts-node');
227
+ requiredDeps.push('typescript');
228
+ const tsconfig = await (0, promises_1.readFile)((0, node_path_1.resolve)(__dirname, '../templates/tsconfig.json'), 'utf-8');
229
+ await (0, promises_1.writeFile)(`./tsconfig.json`, tsconfig, 'utf-8');
230
+ }
231
+ const stepDefinitionGlob = `step_definition/*.${isTypescript ? 'ts' : 'js'}`;
232
+ const stepsPackagesGlobs = ['node_modules/@qavajs/steps-memory/index.js', ...requireGlob(answers.steps, deps_1.steps)];
233
+ const config = generateConfig({
234
+ steps: JSON.stringify([...stepsPackagesGlobs, stepDefinitionGlob]),
235
+ moduleSystem: answers.moduleSystem,
236
+ format: JSON.stringify(deps_1.format
237
+ .filter(p => formatPackages.includes(p.packageName))
238
+ .map(p => p.out ? [p.packageName, p.out] : p.packageName)),
239
+ isWdioIncluded,
240
+ isPlaywrightIncluded,
241
+ });
242
+ await (0, promises_1.mkdir)('./features', { recursive: true });
243
+ await (0, promises_1.mkdir)('./memory', { recursive: true });
244
+ await (0, promises_1.mkdir)('./report', { recursive: true });
245
+ await (0, promises_1.mkdir)('./step_definition', { recursive: true });
246
+ if (isPOIncluded) {
247
+ let poModule;
248
+ if (isWdioIncluded)
249
+ poModule = '@qavajs/steps-wdio/po';
250
+ if (isPlaywrightIncluded)
251
+ poModule = '@qavajs/steps-playwright/po';
252
+ if (!poModule)
253
+ throw new Error('No PO module');
254
+ await (0, promises_1.writeFile)('./features/qavajs.feature', featureTemplate, 'utf-8');
255
+ //create page object folder
256
+ await (0, promises_1.mkdir)('./page_object', { recursive: true });
257
+ const poFile = generatePo(answers.moduleSystem, poModule);
258
+ await (0, promises_1.writeFile)(`./page_object/index.${isTypescript ? 'ts' : 'js'}`, poFile, 'utf-8');
259
+ }
260
+ if (isApiIncluded) {
261
+ await (0, promises_1.writeFile)('./features/qavajsApi.feature', featureApiTemplate, 'utf-8');
262
+ }
263
+ await (0, promises_1.writeFile)(`config.${isTypescript ? 'ts' : 'js'}`, config, 'utf-8');
264
+ const memoryFile = generateMemory(answers.moduleSystem);
265
+ await (0, promises_1.writeFile)(`./memory/index.${isTypescript ? 'ts' : 'js'}`, memoryFile, 'utf-8');
266
+ const readmeFile = generateReadme(answers.moduleSystem);
267
+ await (0, promises_1.writeFile)(`./README.MD`, readmeFile, 'utf-8');
268
+ const modulesToInstall = [
269
+ ...requiredDeps,
270
+ ...stepsPackages,
271
+ ...formatPackages,
272
+ ];
273
+ console.log('installing packages...');
274
+ console.log(modulesToInstall);
275
+ installModules({
276
+ deps: modulesToInstall,
277
+ cwd: process.cwd()
194
278
  });
279
+ console.log('test script:');
280
+ console.log(`npx qavajs --config config.${isTypescript ? 'ts' : 'js'}`);
195
281
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qavajs/create",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "@qavajs init",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -10,23 +10,29 @@
10
10
  "bin": {
11
11
  "create-qavajs": "./index.js"
12
12
  },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/qavajs/create.git"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/qavajs/create/issues"
19
+ },
20
+ "homepage": "https://github.com/qavajs",
13
21
  "keywords": [
14
- "Testing",
15
- "QA"
22
+ "testing",
23
+ "qa",
24
+ "test-automation",
25
+ "qavajs"
16
26
  ],
17
27
  "author": "Alexandr Galichenko",
18
28
  "license": "MIT",
19
29
  "dependencies": {
20
- "@inquirer/prompts": "^7.8.4",
21
- "ejs": "^3.1.10",
22
- "fs-extra": "^11.3.1",
23
- "typescript": "^5.9.2"
30
+ "@inquirer/prompts": "^7.10.1"
24
31
  },
25
32
  "devDependencies": {
26
- "@types/ejs": "^3.1.5",
27
- "@types/fs-extra": "^11.0.4",
28
- "@types/node": "^24.3.1",
29
- "@vitest/coverage-v8": "^3.2.4",
30
- "vitest": "^3.2.4"
33
+ "@types/node": "^25.6.0",
34
+ "@vitest/coverage-v8": "^4.1.4",
35
+ "typescript": "^6.0.2",
36
+ "vitest": "^4.1.4"
31
37
  }
32
38
  }
package/src/install.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { readFile, writeFile } from 'node:fs/promises';
2
- import { ensureDir } from 'fs-extra';
1
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
3
2
  import { resolve } from 'node:path';
4
3
  import { execSync } from 'node:child_process';
5
4
 
@@ -9,7 +8,6 @@ function installModules({ deps, cwd }: { deps: any[], cwd: string }) {
9
8
  }
10
9
 
11
10
  import deps, { steps, format, ModuleDefinition } from './deps';
12
- import { compile } from 'ejs';
13
11
  import { select, checkbox } from '@inquirer/prompts';
14
12
 
15
13
  const packs = (deps: Array<ModuleDefinition>) => deps.map(({module}) => ({ value: module }));
@@ -30,7 +28,134 @@ const requireGlob = (moduleList: Array<string>, packageMap: Array<ModuleDefiniti
30
28
  }) as Array<string>
31
29
  }
32
30
 
33
- const replaceNewLines = (text: string) => text.replace(/(\r?\n\r?)+/g, '\n');
31
+ function generateConfig({ steps, moduleSystem, format, isWdioIncluded, isPlaywrightIncluded }: {
32
+ steps: string, moduleSystem: string, format: string, isWdioIncluded: boolean, isPlaywrightIncluded: boolean
33
+ }): string {
34
+ const isESM = moduleSystem === 'ES Modules';
35
+ const isPOIncluded = isWdioIncluded || isPlaywrightIncluded;
36
+ const browserName = isWdioIncluded ? '"chrome"' : '"chromium"';
37
+
38
+ if (moduleSystem === 'CommonJS') {
39
+ const lines: string[] = [
40
+ `const Memory = require("./memory");`,
41
+ ...(isPOIncluded ? [`const App = require("./page_object");`] : []),
42
+ `module.exports = {`,
43
+ ` default: {`,
44
+ ` paths: ["features/**/*.feature"],`,
45
+ ` require: ${steps},`,
46
+ ` format: ${format},`,
47
+ ` memory: new Memory(),`,
48
+ ...(isPOIncluded ? [
49
+ ` pageObject: new App(),`,
50
+ ` browser: {`,
51
+ ` capabilities: {`,
52
+ ` browserName: ${browserName}`,
53
+ ` }`,
54
+ ` },`,
55
+ ] : []),
56
+ ` }`,
57
+ `}`,
58
+ ];
59
+ return lines.join('\n') + '\n';
60
+ } else {
61
+ const ext = isESM ? '/index.js' : '';
62
+ const importKey = isESM ? 'import' : 'require';
63
+ const lines: string[] = [
64
+ `import Memory from "./memory${ext}";`,
65
+ ...(isPOIncluded ? [`import App from "./page_object${ext}";`] : []),
66
+ `export default {`,
67
+ ` paths: ["features/**/*.feature"],`,
68
+ ` ${importKey}: ${steps},`,
69
+ ` format: ${format},`,
70
+ ` memory: new Memory(),`,
71
+ ...(isPOIncluded ? [
72
+ ` pageObject: new App(),`,
73
+ ` browser: {`,
74
+ ` capabilities: {`,
75
+ ` browserName: ${browserName}`,
76
+ ` }`,
77
+ ` },`,
78
+ ] : []),
79
+ `}`,
80
+ ];
81
+ return lines.join('\n') + '\n';
82
+ }
83
+ }
84
+
85
+ function generateMemory(moduleSystem: string): string {
86
+ const prefix = (moduleSystem === 'ES Modules' || moduleSystem === 'Typescript') ? 'export default ' : 'module.exports = ';
87
+ return `${prefix}class Constants {\n}\n`;
88
+ }
89
+
90
+ function generatePo(moduleSystem: string, poModule: string): string {
91
+ const isESM = moduleSystem === 'ES Modules';
92
+ const isESMorTS = isESM || moduleSystem === 'Typescript';
93
+ const ext = isESM ? '.js' : '';
94
+
95
+ if (isESMorTS) {
96
+ return [
97
+ `import { locator } from "${poModule}${ext}";`,
98
+ `export default class App {`,
99
+ ` Body = locator("body");`,
100
+ ` GetStartedButton = locator("a.button[href='/docs/intro']");`,
101
+ `}`,
102
+ '',
103
+ ].join('\n');
104
+ } else {
105
+ return [
106
+ `const { locator } = require("${poModule}");`,
107
+ `module.exports = class App {`,
108
+ ` Body = locator("body");`,
109
+ ` GetStartedButton = locator("a.button[href='/docs/intro']");`,
110
+ `}`,
111
+ '',
112
+ ].join('\n');
113
+ }
114
+ }
115
+
116
+ function generateReadme(moduleSystem: string): string {
117
+ const ext = moduleSystem === 'Typescript' ? 'ts' : 'js';
118
+ return [
119
+ `# qavajs`,
120
+ `## Docs`,
121
+ `https://qavajs.github.io/`,
122
+ `## Install Modules`,
123
+ '```bash',
124
+ `npm install`,
125
+ '```',
126
+ `## Execute Tests`,
127
+ '```bash',
128
+ `npx qavajs run --config config.${ext}`,
129
+ '```',
130
+ `## Project Structure`,
131
+ `- [config](./config.${ext}) - main config`,
132
+ `- [features](./features) - test cases`,
133
+ `- [memory](./memory) - test data`,
134
+ `- [page_object](./page_object) - page objects`,
135
+ `- [step_definition](./step_definition) - custom step definitions`,
136
+ `- [report](./report) - reports`,
137
+ '',
138
+ ].join('\n');
139
+ }
140
+
141
+ const featureTemplate = [
142
+ `Feature: qavajs framework`,
143
+ ` Scenario: Open qavajs docs`,
144
+ ` Given I open 'https://qavajs.github.io/' url`,
145
+ ` Then I expect text of 'Body' to contain 'qavajs'`,
146
+ '',
147
+ ].join('\n');
148
+
149
+ const featureApiTemplate = [
150
+ `Feature: qavajs framework`,
151
+ ` Scenario: Request qavajs site`,
152
+ ` When I create 'GET' request 'request'`,
153
+ ` And I add 'https://qavajs.github.io/' url to '$request'`,
154
+ ` And I send '$request' request and save response as 'response'`,
155
+ ` And I parse '$response' body as text`,
156
+ ` Then I expect '$response.payload' contains '@qavajs'`,
157
+ '',
158
+ ].join('\n');
34
159
 
35
160
  export default async function install(): Promise<void> {
36
161
  const requiredDeps = [...deps];
@@ -91,14 +216,10 @@ export default async function install(): Promise<void> {
91
216
  );
92
217
  await writeFile(`./tsconfig.json`, tsconfig, 'utf-8');
93
218
  }
94
- const configTemplate: string = await readFile(
95
- resolve(__dirname, '../templates/config.ejs'),
96
- 'utf-8'
97
- );
98
- const configEjs = compile(configTemplate);
219
+
99
220
  const stepDefinitionGlob = `step_definition/*.${isTypescript ? 'ts' : 'js'}`;
100
221
  const stepsPackagesGlobs = ['node_modules/@qavajs/steps-memory/index.js', ...requireGlob(answers.steps, steps)];
101
- const config = configEjs({
222
+ const config = generateConfig({
102
223
  steps: JSON.stringify([...stepsPackagesGlobs, stepDefinitionGlob]),
103
224
  moduleSystem: answers.moduleSystem,
104
225
  format: JSON.stringify(
@@ -110,71 +231,36 @@ export default async function install(): Promise<void> {
110
231
  isPlaywrightIncluded,
111
232
  });
112
233
 
113
- await ensureDir('./features');
114
- await ensureDir('./memory');
115
- await ensureDir('./report');
116
- await ensureDir('./step_definition');
234
+ await mkdir('./features', { recursive: true });
235
+ await mkdir('./memory', { recursive: true });
236
+ await mkdir('./report', { recursive: true });
237
+ await mkdir('./step_definition', { recursive: true });
117
238
 
118
239
  if (isPOIncluded) {
119
240
  let poModule: string | undefined;
120
241
  if (isWdioIncluded) poModule = '@qavajs/steps-wdio/po';
121
242
  if (isPlaywrightIncluded) poModule = '@qavajs/steps-playwright/po';
122
243
  if (!poModule) throw new Error('No PO module');
123
- const featureTemplate: string = await readFile(
124
- resolve(__dirname, '../templates/feature.ejs'),
125
- 'utf-8'
126
- );
127
- const featureEjs = compile(featureTemplate);
128
- const featureFile = featureEjs();
129
- await writeFile('./features/qavajs.feature', replaceNewLines(featureFile), 'utf-8');
244
+
245
+ await writeFile('./features/qavajs.feature', featureTemplate, 'utf-8');
130
246
 
131
247
  //create page object folder
132
- await ensureDir('./page_object');
133
- const poTemplate: string = await readFile(
134
- resolve(__dirname, '../templates/po.ejs'),
135
- 'utf-8'
136
- );
137
- const poEjs = compile(poTemplate);
138
- const poFile = poEjs({
139
- moduleSystem: answers.moduleSystem,
140
- poModule
141
- })
142
- await writeFile(`./page_object/index.${isTypescript ? 'ts' : 'js'}`, replaceNewLines(poFile), 'utf-8');
248
+ await mkdir('./page_object', { recursive: true });
249
+ const poFile = generatePo(answers.moduleSystem, poModule);
250
+ await writeFile(`./page_object/index.${isTypescript ? 'ts' : 'js'}`, poFile, 'utf-8');
143
251
  }
144
252
 
145
253
  if (isApiIncluded) {
146
- const featureTemplate: string = await readFile(
147
- resolve(__dirname, '../templates/featureApi.ejs'),
148
- 'utf-8'
149
- );
150
- const featureEjs = compile(featureTemplate);
151
- const featureFile = featureEjs();
152
- await writeFile('./features/qavajsApi.feature', replaceNewLines(featureFile), 'utf-8');
254
+ await writeFile('./features/qavajsApi.feature', featureApiTemplate, 'utf-8');
153
255
  }
154
256
 
155
- await writeFile(`config.${isTypescript ? 'ts' : 'js'}`, replaceNewLines(config), 'utf-8');
156
-
157
- const memoryTemplate: string = await readFile(
158
- resolve(__dirname, '../templates/memory.ejs'),
159
- 'utf-8'
160
- );
161
- const memoryEjs = compile(memoryTemplate);
162
- const memoryFile = memoryEjs({
163
- moduleSystem: answers.moduleSystem
164
- })
257
+ await writeFile(`config.${isTypescript ? 'ts' : 'js'}`, config, 'utf-8');
165
258
 
166
- await writeFile(`./memory/index.${isTypescript ? 'ts' : 'js'}`, replaceNewLines(memoryFile), 'utf-8');
167
-
168
- const readmeTemplate: string = await readFile(
169
- resolve(__dirname, '../templates/readme.ejs'),
170
- 'utf-8'
171
- );
172
- const readmeEjs = compile(readmeTemplate);
173
- const readmeFile = readmeEjs({
174
- moduleSystem: answers.moduleSystem
175
- })
259
+ const memoryFile = generateMemory(answers.moduleSystem);
260
+ await writeFile(`./memory/index.${isTypescript ? 'ts' : 'js'}`, memoryFile, 'utf-8');
176
261
 
177
- await writeFile(`./README.MD`, replaceNewLines(readmeFile), 'utf-8');
262
+ const readmeFile = generateReadme(answers.moduleSystem);
263
+ await writeFile(`./README.MD`, readmeFile, 'utf-8');
178
264
 
179
265
  const modulesToInstall = [
180
266
  ...requiredDeps,
package/templates/po.ejs CHANGED
@@ -1,5 +1,5 @@
1
1
  <% if (moduleSystem === 'ES Modules' || moduleSystem === 'Typescript') {-%>
2
- <%-'import { locator } from "'-%><%-poModule%>";
2
+ <%-'import { locator } from "'-%><%-poModule%><% if (moduleSystem === 'ES Modules') {-%>.js<%}%>";
3
3
  <%} else {-%>
4
4
  <%-'const { locator } = require('%>"<%-poModule%>");
5
5
  <%}%>
package/tsconfig.json CHANGED
@@ -1,18 +1,22 @@
1
1
  {
2
2
  "include": [
3
- "src/**/*.ts"
3
+ "src/**/*.ts",
4
4
  ],
5
5
  "exclude": [
6
6
  "test/**/*.spec.ts"
7
7
  ],
8
8
  "compilerOptions": {
9
- "target": "es2016",
9
+ "target": "es2022",
10
10
  "module": "node16",
11
11
  "moduleResolution": "node16",
12
12
  "outDir": "./lib",
13
+ "rootDir": "./src",
13
14
  "esModuleInterop": true,
14
15
  "forceConsistentCasingInFileNames": true,
15
16
  "strict": true,
16
- "skipLibCheck": true
17
+ "skipLibCheck": true,
18
+ "types": [
19
+ "node"
20
+ ]
17
21
  }
18
22
  }