From 70b61c60c0ce9725c15a3e1c2f9e7b21472b7223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=AB=E9=9B=A8=E6=B0=B4=E8=BF=87=E6=BB=A4=E7=9A=84?= =?UTF-8?q?=E7=A9=BA=E6=B0=94-Rain?= <958414905@qq.com> Date: Fri, 6 Oct 2023 18:59:59 +0800 Subject: [PATCH] chore(e2e): make stability (#2751) --- package.json | 3 +- scripts/codegen.setup.ts | 20 ++++------- scripts/nocobase.setup.ts | 2 +- scripts/runE2e.setup.ts | 20 ++++------- scripts/utils.ts | 74 +++++++++++++++++++++++++++++++++++---- 5 files changed, 84 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index 59d364442..e9d834d7a 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,8 @@ "ts-jest": "^29.1.1", "typescript": "5.1.3", "vite": "^4.4.9", - "vitest": "^0.34.3" + "vitest": "^0.34.3", + "axios": "^0.26.1" }, "volta": { "node": "18.14.2", diff --git a/scripts/codegen.setup.ts b/scripts/codegen.setup.ts index 4ff49164a..b6405eb93 100644 --- a/scripts/codegen.setup.ts +++ b/scripts/codegen.setup.ts @@ -20,19 +20,13 @@ const runCodegenSync = () => { }; const run = async () => { - const { kill } = await runNocoBase(); + const { kill, awaitForNocoBase } = await runNocoBase(); - if (kill) { - // 等待服务成功启动 - setTimeout(() => { - console.log('Starting codegen...'); - runCodegenSync(); - kill?.('SIGKILL'); - }, 5000); - } else { - console.log('Starting codegen...'); - runCodegenSync(); - } + await awaitForNocoBase(); + + console.log('Starting codegen...'); + runCodegenSync(); + kill?.('SIGKILL'); }; -void run(); +run(); diff --git a/scripts/nocobase.setup.ts b/scripts/nocobase.setup.ts index fb0db9295..5cc1a7522 100644 --- a/scripts/nocobase.setup.ts +++ b/scripts/nocobase.setup.ts @@ -1,3 +1,3 @@ import { runNocoBase } from './utils'; -void runNocoBase(); +runNocoBase(); diff --git a/scripts/runE2e.setup.ts b/scripts/runE2e.setup.ts index b6e3cb453..2f5fabb54 100644 --- a/scripts/runE2e.setup.ts +++ b/scripts/runE2e.setup.ts @@ -1,21 +1,15 @@ import { runCommand, runNocoBase } from './utils'; const run = async () => { - const { kill } = await runNocoBase({ + const { kill, awaitForNocoBase } = await runNocoBase({ stdio: 'ignore', // 不输出服务的日志,避免干扰测试的日志 }); - if (kill) { - // 等待服务成功启动 - setTimeout(() => { - console.log('Start running tests...'); - void runCommand('npx', ['playwright', 'test', ...process.argv.slice(2)]); - kill?.('SIGKILL'); - }, 5000); - } else { - console.log('Start running tests...'); - void runCommand('npx', ['playwright', 'test', ...process.argv.slice(2)]); - } + await awaitForNocoBase(); + + console.log('Start running tests...'); + runCommand('npx', ['playwright', 'test', ...process.argv.slice(2)]); + kill?.('SIGKILL'); }; -void run(); +run(); diff --git a/scripts/utils.ts b/scripts/utils.ts index a656310da..05461cc64 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -1,3 +1,4 @@ +import axios from 'axios'; import dotenv from 'dotenv'; import type { CommonOptions } from 'execa'; import execa from 'execa'; @@ -40,6 +41,57 @@ function checkPort(port) { }); } +/** + * 检查服务是否启动成功 + */ +const checkServer = async (duration = 1000) => { + return new Promise((resolve, reject) => { + const timer = setInterval(async () => { + if (!(await checkPort(process.env.APP_PORT))) { + return; + } + + axios + .get(`http://localhost:${process.env.APP_PORT}/api/__health_check`) + .then((response) => { + if (response.status === 200) { + clearInterval(timer); + resolve(true); + } + }) + .catch((error) => { + clearInterval(timer); + console.error('Request error:', error); + reject(error); + }); + }, duration); + }); +}; + +/** + * 检查 UI 是否启动成功 + * @param duration + */ +const checkUI = async (duration = 1000) => { + return new Promise((resolve, reject) => { + const timer = setInterval(async () => { + axios + .get(`http://localhost:${process.env.APP_PORT}/__umi/api/bundle-status`) + .then((response) => { + if (response.data.bundleStatus.done) { + clearInterval(timer); + resolve(true); + } + }) + .catch((error) => { + clearInterval(timer); + console.error('Request error:', error); + reject(error); + }); + }, duration); + }); +}; + export const runNocoBase = async (options?: CommonOptions) => { // 用于存放 playwright 自动生成的相关的文件 if (!fs.existsSync('playwright')) { @@ -57,25 +109,33 @@ export const runNocoBase = async (options?: CommonOptions) => { dotenv.config({ path: path.resolve(process.cwd(), '.env.e2e') }); + const awaitForNocoBase = async () => { + console.log('check server...'); + await checkServer(); + console.log('server is ready, check UI...'); + await checkUI(); + console.log('UI is ready.'); + }; + if (process.env.CI) { console.log('yarn nocobase install'); await runCommand('yarn', ['nocobase', 'install'], options); console.log(`yarn start -d -p ${process.env.APP_PORT}`); await runCommand('yarn', ['start', '-d', `-p ${process.env.APP_PORT}`], options); - return {}; - } - - if (await checkPort(process.env.APP_PORT)) { - console.log('Server is running, skip starting server.'); - return {}; + return { awaitForNocoBase }; } // 加上 -f 会清空数据库 console.log('yarn nocobase install -f'); await runCommand('yarn', ['nocobase', 'install', '-f'], options); + if (await checkPort(process.env.APP_PORT)) { + console.log('Server is running, skip starting server.'); + return { awaitForNocoBase }; + } + console.log('starting server...'); const { cancel, kill } = runCommand('yarn', ['dev', `-p ${process.env.APP_PORT}`, ...process.argv.slice(2)], options); - return { cancel, kill }; + return { cancel, kill, awaitForNocoBase }; };