@qavajs/create 2.2.2 → 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 +3 -0
- package/README.md +5 -1
- package/lib/install.js +214 -128
- package/package.json +6 -10
- package/src/install.ts +146 -60
- package/tsconfig.json +7 -3
package/CHANGELOG.MD
CHANGED
package/README.md
CHANGED
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "@qavajs init",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -27,16 +27,12 @@
|
|
|
27
27
|
"author": "Alexandr Galichenko",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@inquirer/prompts": "^7.
|
|
31
|
-
"ejs": "^3.1.10",
|
|
32
|
-
"fs-extra": "^11.3.2",
|
|
33
|
-
"typescript": "^5.9.3"
|
|
30
|
+
"@inquirer/prompts": "^7.10.1"
|
|
34
31
|
},
|
|
35
32
|
"devDependencies": {
|
|
36
|
-
"@types/
|
|
37
|
-
"@
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"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"
|
|
41
37
|
}
|
|
42
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
114
|
-
await
|
|
115
|
-
await
|
|
116
|
-
await
|
|
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
|
-
|
|
124
|
-
|
|
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
|
|
133
|
-
const
|
|
134
|
-
|
|
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
|
-
|
|
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'}`,
|
|
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
|
-
|
|
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
|
-
|
|
262
|
+
const readmeFile = generateReadme(answers.moduleSystem);
|
|
263
|
+
await writeFile(`./README.MD`, readmeFile, 'utf-8');
|
|
178
264
|
|
|
179
265
|
const modulesToInstall = [
|
|
180
266
|
...requiredDeps,
|
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": "
|
|
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
|
}
|