bk-press 0.0.3 → 0.0.5
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/lib/command/fixture.js +42 -0
- package/lib/command/index.js +1 -0
- package/lib/command/init.js +24 -6
- package/lib/command/run.js +4 -1
- package/lib/index.js +14 -4
- package/package.json +1 -1
- package/src/command/fixture.ts +58 -0
- package/src/command/index.ts +1 -0
- package/src/command/init.ts +29 -6
- package/src/command/run.ts +3 -1
- package/src/index.ts +18 -6
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.fixture = fixture;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const util_1 = require("../util");
|
|
9
|
+
async function fixture() {
|
|
10
|
+
console.log("开始生成 fixture 文件...");
|
|
11
|
+
const logJsonFile = path_1.default.join(process.cwd(), "web-interaction-log.json");
|
|
12
|
+
const isExistJsonFile = await (0, util_1.isFileOrFolderExist)(logJsonFile);
|
|
13
|
+
if (!isExistJsonFile) {
|
|
14
|
+
throw new Error("web-interaction-log.json 文件不存在,请在 Chrome 应用商店安装 Web Interaction Logger 插件后,录制并导出 web-interaction-log.json 到项目根目录下。");
|
|
15
|
+
}
|
|
16
|
+
const logList = (await (0, util_1.readFile)(logJsonFile));
|
|
17
|
+
const validLogList = logList.filter((log) => log.type === "network" &&
|
|
18
|
+
log.subtype === "response-body" &&
|
|
19
|
+
log.url.startsWith("/"));
|
|
20
|
+
const commonPath = path_1.default.join(process.cwd(), "cypress_fixtures");
|
|
21
|
+
const isExistFolder = await (0, util_1.isFileOrFolderExist)(commonPath);
|
|
22
|
+
if (!isExistFolder) {
|
|
23
|
+
await (0, util_1.createFolder)(commonPath);
|
|
24
|
+
console.log(`创建 fixtures 文件夹: ${commonPath}`);
|
|
25
|
+
}
|
|
26
|
+
validLogList.forEach(async (log) => {
|
|
27
|
+
const jsonContent = log.responseBody;
|
|
28
|
+
const jsonString = JSON.stringify(jsonContent, null, 2);
|
|
29
|
+
const isExistQuery = log.url.includes("?");
|
|
30
|
+
let fileName = "";
|
|
31
|
+
if (isExistQuery) {
|
|
32
|
+
fileName = log.url.split("?")[0].replace(/\//g, "_");
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
fileName = log.url.replace(/\//g, "_");
|
|
36
|
+
}
|
|
37
|
+
fileName = `${log.method}_${fileName.substring(1, fileName.length - 1)}.json`;
|
|
38
|
+
console.log(`生成 fixture 文件: ${fileName}`);
|
|
39
|
+
const fixtureFile = path_1.default.join(commonPath, fileName);
|
|
40
|
+
await (0, util_1.writeFile)(fixtureFile, jsonString);
|
|
41
|
+
});
|
|
42
|
+
}
|
package/lib/command/index.js
CHANGED
package/lib/command/init.js
CHANGED
|
@@ -10,7 +10,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
10
10
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
11
|
const util_1 = require("../util");
|
|
12
12
|
async function init() {
|
|
13
|
-
console.log("开始初始化Cypress
|
|
13
|
+
console.log("开始初始化Cypress自动化测试环境...");
|
|
14
14
|
console.log("安装相关依赖...");
|
|
15
15
|
await installDependencies();
|
|
16
16
|
console.log("添加类型到 tsconfig.json 文件...");
|
|
@@ -57,6 +57,11 @@ async function addScriptsToPackageJson() {
|
|
|
57
57
|
}
|
|
58
58
|
// 创建 cypress 文件夹并拉取模板文件
|
|
59
59
|
async function addTemplateFiles() {
|
|
60
|
+
const isCypressExist = await (0, util_1.isFileOrFolderExist)(path_1.default.join(process.cwd(), "cypress"));
|
|
61
|
+
if (isCypressExist) {
|
|
62
|
+
console.log("cypress 文件夹已存在,跳过拉取模板文件");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
60
65
|
const isTsProject = await checkIsTsProject();
|
|
61
66
|
console.log("当前项目是否是 TypeScript 项目: ", isTsProject);
|
|
62
67
|
await createCypressFolder();
|
|
@@ -113,6 +118,11 @@ async function copyTemplateFiles() {
|
|
|
113
118
|
// 添加 cypress.config.ts 文件
|
|
114
119
|
async function addCypressConfigFile() {
|
|
115
120
|
const cypressConfigFile = path_1.default.join(process.cwd(), "cypress.config.ts");
|
|
121
|
+
const isExist = await (0, util_1.isFileOrFolderExist)(cypressConfigFile);
|
|
122
|
+
if (isExist) {
|
|
123
|
+
console.log("cypress.config.ts 文件已存在,跳过创建");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
116
126
|
const fileContent = `import { defineConfig } from 'cypress';
|
|
117
127
|
|
|
118
128
|
export default defineConfig({
|
|
@@ -141,6 +151,11 @@ async function addCypressEnvJsonFile() {
|
|
|
141
151
|
async function addIgnoreToGitignoreFile() {
|
|
142
152
|
const gitignoreFile = path_1.default.join(process.cwd(), ".gitignore");
|
|
143
153
|
const oldFileContent = await (0, util_1.readFile)(gitignoreFile, false);
|
|
154
|
+
const isExist = oldFileContent.includes("cypress");
|
|
155
|
+
if (isExist) {
|
|
156
|
+
console.log(".gitignore 文件中已存在 cypress 相关文件,跳过添加忽略文件");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
144
159
|
const fileContent = `${oldFileContent}\n
|
|
145
160
|
cypress/parallel-weights.json
|
|
146
161
|
cypress/screenshots
|
|
@@ -151,16 +166,19 @@ multi-reporter-config.json`;
|
|
|
151
166
|
}
|
|
152
167
|
// 添加 cypress 类型到 tsconfig.json 文件
|
|
153
168
|
async function addCypressTypesToTsconfigJsonFile() {
|
|
154
|
-
const
|
|
155
|
-
const tsconfigJson = (await (0, util_1.readFile)(
|
|
169
|
+
const tsconfigJsonFilePath = path_1.default.join(process.cwd(), "tsconfig.json");
|
|
170
|
+
const tsconfigJson = (await (0, util_1.readFile)(tsconfigJsonFilePath));
|
|
156
171
|
if (tsconfigJson.include) {
|
|
157
|
-
tsconfigJson.include.
|
|
172
|
+
if (!tsconfigJson.include.includes("cypress/**/*")) {
|
|
173
|
+
tsconfigJson.include.push("cypress/**/*");
|
|
174
|
+
}
|
|
158
175
|
}
|
|
159
176
|
else {
|
|
160
177
|
tsconfigJson.include = ["cypress/**/*"];
|
|
161
178
|
}
|
|
162
179
|
if (tsconfigJson.compilerOptions) {
|
|
163
|
-
if (tsconfigJson.compilerOptions.types
|
|
180
|
+
if (tsconfigJson.compilerOptions.types &&
|
|
181
|
+
!tsconfigJson.compilerOptions.types.includes("cypress")) {
|
|
164
182
|
tsconfigJson.compilerOptions.types.push("cypress");
|
|
165
183
|
}
|
|
166
184
|
else {
|
|
@@ -173,5 +191,5 @@ async function addCypressTypesToTsconfigJsonFile() {
|
|
|
173
191
|
};
|
|
174
192
|
}
|
|
175
193
|
const fileContent = JSON.stringify(tsconfigJson, null, 2);
|
|
176
|
-
await (0, util_1.writeFile)(
|
|
194
|
+
await (0, util_1.writeFile)(tsconfigJsonFilePath, fileContent);
|
|
177
195
|
}
|
package/lib/command/run.js
CHANGED
|
@@ -9,11 +9,14 @@ const login_1 = require("./login");
|
|
|
9
9
|
const os_1 = __importDefault(require("os"));
|
|
10
10
|
async function run() {
|
|
11
11
|
console.log("开始运行自动化测试...");
|
|
12
|
+
// console.log("当前工作目录: ", process.cwd());
|
|
12
13
|
const config = await (0, login_1.readCypressEnvConfig)();
|
|
13
14
|
const cpuCount = os_1.default.cpus().length;
|
|
14
15
|
console.log("当前CPU核心数: ", cpuCount, ", 设置测试并发数: ", cpuCount);
|
|
15
16
|
return new Promise((resolve, reject) => {
|
|
16
|
-
const child = (0, child_process_1.exec)(
|
|
17
|
+
const child = (0, child_process_1.exec)(
|
|
18
|
+
// `npm run dev & npx wait-on ${config.localUrl} && npx cypress-parallel -s e2e -t ${cpuCount} -d cypress/e2e`,
|
|
19
|
+
`npx start-server-and-test dev ${config.localUrl} "cypress-parallel -s e2e -t ${cpuCount} -d cypress/e2e"`, {
|
|
17
20
|
cwd: process.cwd(),
|
|
18
21
|
// @ts-ignore
|
|
19
22
|
stdio: "inherit",
|
package/lib/index.js
CHANGED
|
@@ -7,9 +7,19 @@ const program = new commander_1.Command();
|
|
|
7
7
|
program
|
|
8
8
|
.name("bk-press")
|
|
9
9
|
.description("一个用于 Cypress 自动化测试的 CLI 工具,帮助快速初始化和运行端到端测试")
|
|
10
|
-
.version("0.0.
|
|
11
|
-
program
|
|
12
|
-
|
|
10
|
+
.version("0.0.5");
|
|
11
|
+
program
|
|
12
|
+
.command("init")
|
|
13
|
+
.description("初始化 Cypress 自动化测试环境")
|
|
14
|
+
.action(command_1.init);
|
|
15
|
+
program
|
|
16
|
+
.command("login")
|
|
17
|
+
.description("登录本地开发环境并保存 Cookie")
|
|
18
|
+
.action(command_1.login);
|
|
13
19
|
// @ts-ignore
|
|
14
|
-
program.command("run").action(command_1.run);
|
|
20
|
+
program.command("run").description("并行运行自动化测试").action(command_1.run);
|
|
21
|
+
program
|
|
22
|
+
.command("fixture")
|
|
23
|
+
.description("根据 Chrome 插件 Web Interaction Logger 导出的 web-interaction-log.json 生成 fixture 拦截数据")
|
|
24
|
+
.action(command_1.fixture);
|
|
15
25
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import {
|
|
3
|
+
isFileOrFolderExist,
|
|
4
|
+
readFile,
|
|
5
|
+
writeFile,
|
|
6
|
+
createFolder,
|
|
7
|
+
} from "../util";
|
|
8
|
+
|
|
9
|
+
interface WebInteractionLog {
|
|
10
|
+
type: string;
|
|
11
|
+
subtype: string;
|
|
12
|
+
requestId: string;
|
|
13
|
+
url: string;
|
|
14
|
+
method: string;
|
|
15
|
+
status: number;
|
|
16
|
+
statusText: string;
|
|
17
|
+
responseHeaders: string;
|
|
18
|
+
responseBody: Record<string, any>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function fixture() {
|
|
22
|
+
console.log("开始生成 fixture 文件...");
|
|
23
|
+
const logJsonFile = path.join(process.cwd(), "web-interaction-log.json");
|
|
24
|
+
const isExistJsonFile = await isFileOrFolderExist(logJsonFile);
|
|
25
|
+
if (!isExistJsonFile) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
"web-interaction-log.json 文件不存在,请在 Chrome 应用商店安装 Web Interaction Logger 插件后,录制并导出 web-interaction-log.json 到项目根目录下。",
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
const logList = (await readFile(logJsonFile)) as WebInteractionLog[];
|
|
31
|
+
const validLogList = logList.filter(
|
|
32
|
+
(log) =>
|
|
33
|
+
log.type === "network" &&
|
|
34
|
+
log.subtype === "response-body" &&
|
|
35
|
+
log.url.startsWith("/"),
|
|
36
|
+
);
|
|
37
|
+
const commonPath = path.join(process.cwd(), "cypress_fixtures");
|
|
38
|
+
const isExistFolder = await isFileOrFolderExist(commonPath);
|
|
39
|
+
if (!isExistFolder) {
|
|
40
|
+
await createFolder(commonPath);
|
|
41
|
+
console.log(`创建 fixtures 文件夹: ${commonPath}`);
|
|
42
|
+
}
|
|
43
|
+
validLogList.forEach(async (log) => {
|
|
44
|
+
const jsonContent = log.responseBody;
|
|
45
|
+
const jsonString = JSON.stringify(jsonContent, null, 2);
|
|
46
|
+
const isExistQuery = log.url.includes("?");
|
|
47
|
+
let fileName = "";
|
|
48
|
+
if (isExistQuery) {
|
|
49
|
+
fileName = log.url.split("?")[0].replace(/\//g, "_");
|
|
50
|
+
} else {
|
|
51
|
+
fileName = log.url.replace(/\//g, "_");
|
|
52
|
+
}
|
|
53
|
+
fileName = `${log.method}_${fileName.substring(1, fileName.length - 1)}.json`;
|
|
54
|
+
console.log(`生成 fixture 文件: ${fileName}`);
|
|
55
|
+
const fixtureFile = path.join(commonPath, fileName);
|
|
56
|
+
await writeFile(fixtureFile, jsonString);
|
|
57
|
+
});
|
|
58
|
+
}
|
package/src/command/index.ts
CHANGED
package/src/command/init.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "../util";
|
|
12
12
|
|
|
13
13
|
export async function init() {
|
|
14
|
-
console.log("开始初始化Cypress
|
|
14
|
+
console.log("开始初始化Cypress自动化测试环境...");
|
|
15
15
|
console.log("安装相关依赖...");
|
|
16
16
|
await installDependencies();
|
|
17
17
|
console.log("添加类型到 tsconfig.json 文件...");
|
|
@@ -68,6 +68,13 @@ async function addScriptsToPackageJson() {
|
|
|
68
68
|
|
|
69
69
|
// 创建 cypress 文件夹并拉取模板文件
|
|
70
70
|
async function addTemplateFiles() {
|
|
71
|
+
const isCypressExist = await isFileOrFolderExist(
|
|
72
|
+
path.join(process.cwd(), "cypress")
|
|
73
|
+
);
|
|
74
|
+
if (isCypressExist) {
|
|
75
|
+
console.log("cypress 文件夹已存在,跳过拉取模板文件");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
71
78
|
const isTsProject = await checkIsTsProject();
|
|
72
79
|
console.log("当前项目是否是 TypeScript 项目: ", isTsProject);
|
|
73
80
|
await createCypressFolder();
|
|
@@ -134,6 +141,11 @@ async function copyTemplateFiles() {
|
|
|
134
141
|
// 添加 cypress.config.ts 文件
|
|
135
142
|
async function addCypressConfigFile() {
|
|
136
143
|
const cypressConfigFile = path.join(process.cwd(), "cypress.config.ts");
|
|
144
|
+
const isExist = await isFileOrFolderExist(cypressConfigFile);
|
|
145
|
+
if (isExist) {
|
|
146
|
+
console.log("cypress.config.ts 文件已存在,跳过创建");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
137
149
|
const fileContent = `import { defineConfig } from 'cypress';
|
|
138
150
|
|
|
139
151
|
export default defineConfig({
|
|
@@ -164,6 +176,12 @@ async function addCypressEnvJsonFile() {
|
|
|
164
176
|
async function addIgnoreToGitignoreFile() {
|
|
165
177
|
const gitignoreFile = path.join(process.cwd(), ".gitignore");
|
|
166
178
|
const oldFileContent = await readFile(gitignoreFile, false);
|
|
179
|
+
const isExist = oldFileContent.includes("cypress");
|
|
180
|
+
if (isExist) {
|
|
181
|
+
console.log(".gitignore 文件中已存在 cypress 相关文件,跳过添加忽略文件");
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
167
185
|
const fileContent = `${oldFileContent}\n
|
|
168
186
|
cypress/parallel-weights.json
|
|
169
187
|
cypress/screenshots
|
|
@@ -175,19 +193,24 @@ multi-reporter-config.json`;
|
|
|
175
193
|
|
|
176
194
|
// 添加 cypress 类型到 tsconfig.json 文件
|
|
177
195
|
async function addCypressTypesToTsconfigJsonFile() {
|
|
178
|
-
const
|
|
179
|
-
const tsconfigJson = (await readFile(
|
|
196
|
+
const tsconfigJsonFilePath = path.join(process.cwd(), "tsconfig.json");
|
|
197
|
+
const tsconfigJson = (await readFile(tsconfigJsonFilePath)) as Record<
|
|
180
198
|
string,
|
|
181
199
|
any
|
|
182
200
|
>;
|
|
183
201
|
if (tsconfigJson.include) {
|
|
184
|
-
tsconfigJson.include.
|
|
202
|
+
if (!tsconfigJson.include.includes("cypress/**/*")) {
|
|
203
|
+
tsconfigJson.include.push("cypress/**/*");
|
|
204
|
+
}
|
|
185
205
|
} else {
|
|
186
206
|
tsconfigJson.include = ["cypress/**/*"];
|
|
187
207
|
}
|
|
188
208
|
|
|
189
209
|
if (tsconfigJson.compilerOptions) {
|
|
190
|
-
if (
|
|
210
|
+
if (
|
|
211
|
+
tsconfigJson.compilerOptions.types &&
|
|
212
|
+
!tsconfigJson.compilerOptions.types.includes("cypress")
|
|
213
|
+
) {
|
|
191
214
|
tsconfigJson.compilerOptions.types.push("cypress");
|
|
192
215
|
} else {
|
|
193
216
|
tsconfigJson.compilerOptions.types = ["cypress"];
|
|
@@ -198,5 +221,5 @@ async function addCypressTypesToTsconfigJsonFile() {
|
|
|
198
221
|
};
|
|
199
222
|
}
|
|
200
223
|
const fileContent = JSON.stringify(tsconfigJson, null, 2);
|
|
201
|
-
await writeFile(
|
|
224
|
+
await writeFile(tsconfigJsonFilePath, fileContent);
|
|
202
225
|
}
|
package/src/command/run.ts
CHANGED
|
@@ -4,12 +4,14 @@ import os from "os";
|
|
|
4
4
|
|
|
5
5
|
export async function run() {
|
|
6
6
|
console.log("开始运行自动化测试...");
|
|
7
|
+
// console.log("当前工作目录: ", process.cwd());
|
|
7
8
|
const config = await readCypressEnvConfig();
|
|
8
9
|
const cpuCount = os.cpus().length;
|
|
9
10
|
console.log("当前CPU核心数: ", cpuCount, ", 设置测试并发数: ", cpuCount);
|
|
10
11
|
return new Promise((resolve, reject) => {
|
|
11
12
|
const child = exec(
|
|
12
|
-
`
|
|
13
|
+
// `npm run dev & npx wait-on ${config.localUrl} && npx cypress-parallel -s e2e -t ${cpuCount} -d cypress/e2e`,
|
|
14
|
+
`npx start-server-and-test dev ${config.localUrl} "cypress-parallel -s e2e -t ${cpuCount} -d cypress/e2e"`,
|
|
13
15
|
{
|
|
14
16
|
cwd: process.cwd(),
|
|
15
17
|
// @ts-ignore
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
-
import { login, init, run } from "./command";
|
|
4
|
+
import { login, init, run, fixture } from "./command";
|
|
5
5
|
|
|
6
6
|
const program = new Command();
|
|
7
7
|
|
|
8
8
|
program
|
|
9
9
|
.name("bk-press")
|
|
10
10
|
.description(
|
|
11
|
-
"一个用于 Cypress 自动化测试的 CLI 工具,帮助快速初始化和运行端到端测试"
|
|
11
|
+
"一个用于 Cypress 自动化测试的 CLI 工具,帮助快速初始化和运行端到端测试",
|
|
12
12
|
)
|
|
13
|
-
.version("0.0.
|
|
13
|
+
.version("0.0.5");
|
|
14
14
|
|
|
15
|
-
program
|
|
16
|
-
|
|
15
|
+
program
|
|
16
|
+
.command("init")
|
|
17
|
+
.description("初始化 Cypress 自动化测试环境")
|
|
18
|
+
.action(init);
|
|
19
|
+
program
|
|
20
|
+
.command("login")
|
|
21
|
+
.description("登录本地开发环境并保存 Cookie")
|
|
22
|
+
.action(login);
|
|
17
23
|
// @ts-ignore
|
|
18
|
-
program.command("run").action(run);
|
|
24
|
+
program.command("run").description("并行运行自动化测试").action(run);
|
|
25
|
+
program
|
|
26
|
+
.command("fixture")
|
|
27
|
+
.description(
|
|
28
|
+
"根据 Chrome 插件 Web Interaction Logger 导出的 web-interaction-log.json 生成 fixture 拦截数据",
|
|
29
|
+
)
|
|
30
|
+
.action(fixture);
|
|
19
31
|
program.parse(process.argv);
|