优化分批执行点击菜单
This commit is contained in:
parent
f7fdf43abb
commit
47d7883874
22
.env.uat
22
.env.uat
@ -1,23 +1,25 @@
|
|||||||
# 基础配置
|
# 基础配置
|
||||||
BASE_URL=https://ibp-test.longi.com/main/#/login?debug=ly
|
BASE_URL=https://ibp-test.longi.com/main/#/login?debug=ly
|
||||||
USERNAME=zidonghuatest
|
|
||||||
PASSWORD=Lianyu_123
|
# 登录配置
|
||||||
|
IBP_USERNAME=zidonghuatest
|
||||||
|
IBP_PASSWORD=Lianyu_123
|
||||||
|
|
||||||
# 测试配置
|
# 测试配置
|
||||||
TEST_DATA_DIR=test-data
|
TEST_DATA_DIR=test-data
|
||||||
TEST_BATCH_SIZE=5
|
TEST_BATCH_SIZE=2
|
||||||
TEST_RETRY_COUNT=3
|
TEST_RETRY_COUNT=3
|
||||||
TEST_BATCH_INTERVAL=1000
|
TEST_BATCH_INTERVAL=2000
|
||||||
TEST_MAX_RETRY_DELAY=5000
|
TEST_MAX_RETRY_DELAY=10000
|
||||||
|
|
||||||
# 超时配置
|
# 超时配置
|
||||||
MENU_TIME_OUT=30000
|
MENU_TIME_OUT=60000
|
||||||
EXPECT_TIMEOUT=3600000
|
EXPECT_TIMEOUT=3600000
|
||||||
|
|
||||||
# 浏览器配置
|
# 浏览器配置
|
||||||
BROWSER_HEADLESS=false
|
BROWSER_HEADLESS=false
|
||||||
BROWSER_SLOW_MO=50
|
BROWSER_SLOW_MO=100
|
||||||
BROWSER_TIMEOUT=60000
|
BROWSER_TIMEOUT=120000
|
||||||
VIEWPORT_WIDTH=1920
|
VIEWPORT_WIDTH=1920
|
||||||
VIEWPORT_HEIGHT=1080
|
VIEWPORT_HEIGHT=1080
|
||||||
|
|
||||||
@ -27,5 +29,5 @@ TEST_PROGRESS_FILE_PATH=test-data/test-progress.json
|
|||||||
|
|
||||||
# 页面加载配置
|
# 页面加载配置
|
||||||
PAGE_LOAD_MAX_RETRIES=5
|
PAGE_LOAD_MAX_RETRIES=5
|
||||||
PAGE_LOAD_RETRY_INTERVAL=2000
|
PAGE_LOAD_RETRY_INTERVAL=3000
|
||||||
PAGE_LOAD_STABILITY_DELAY=1000
|
PAGE_LOAD_STABILITY_DELAY=2000
|
||||||
BIN
login-error.png
BIN
login-error.png
Binary file not shown.
|
Before Width: | Height: | Size: 228 KiB |
@ -9,61 +9,70 @@ $scriptPath = Join-Path $currentPath "run-tests.bat"
|
|||||||
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
|
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
|
||||||
|
|
||||||
# Task Configuration
|
# Task Configuration
|
||||||
$taskName = "Playwright_AutoTest"
|
$taskNamePrefix = "Playwright_AutoTest"
|
||||||
$taskDesc = "Run Playwright tests daily"
|
$taskDesc = "Run Playwright tests daily"
|
||||||
|
|
||||||
function Show-Menu {
|
function Show-Menu {
|
||||||
Clear-Host
|
Clear-Host
|
||||||
Write-Host "`n================== Playwright Test Manager ==================`n"
|
Write-Host "`n================== Playwright Test Manager ==================`n"
|
||||||
Write-Host "1. View Task Status"
|
Write-Host "1. View All Tasks Status"
|
||||||
Write-Host "2. Set Daily Task (Default: 23:00)"
|
Write-Host "2. Set Daily Task - DEV Environment (Default: 23:00)"
|
||||||
Write-Host "3. Change Task Time"
|
Write-Host "3. Set Daily Task - UAT Environment"
|
||||||
Write-Host "4. Run Test Now"
|
Write-Host "4. Run Test Now"
|
||||||
Write-Host "5. Delete Task"
|
Write-Host "5. Delete Tasks"
|
||||||
Write-Host "Q. Exit"
|
Write-Host "Q. Exit"
|
||||||
Write-Host "`nEnter your choice (1-5, or Q to exit): " -NoNewline
|
Write-Host "`nEnter your choice (1-5, or Q to exit): " -NoNewline
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-TaskStatus {
|
function Get-TaskStatus {
|
||||||
$task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
$environments = @("Dev", "UAT")
|
||||||
if ($task) {
|
$found = $false
|
||||||
Write-Host "`nTask Status:"
|
|
||||||
Write-Host "Name: $taskName"
|
|
||||||
Write-Host "State: $($task.State)"
|
|
||||||
|
|
||||||
$trigger = $task.Triggers[0]
|
Write-Host "`nTasks Status:"
|
||||||
if ($trigger) {
|
foreach ($env in $environments) {
|
||||||
Write-Host "Schedule: Daily at $($trigger.StartBoundary.Split('T')[1].Substring(0,5))"
|
$taskName = "${taskNamePrefix}_$env"
|
||||||
# 安全地处理 NextRunTime
|
$task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
||||||
try {
|
|
||||||
if ($task.NextRunTime) {
|
if ($task) {
|
||||||
Write-Host "Next Run: $($task.NextRunTime.ToString('yyyy-MM-dd HH:mm'))"
|
$found = $true
|
||||||
} else {
|
Write-Host "`n$env Environment Task:"
|
||||||
Write-Host "Next Run: Not yet scheduled"
|
Write-Host "Name: $taskName"
|
||||||
|
Write-Host "State: $($task.State)"
|
||||||
|
|
||||||
|
$trigger = $task.Triggers[0]
|
||||||
|
if ($trigger) {
|
||||||
|
Write-Host "Schedule: Daily at $($trigger.StartBoundary.Split('T')[1].Substring(0,5))"
|
||||||
|
try {
|
||||||
|
if ($task.NextRunTime) {
|
||||||
|
Write-Host "Next Run: $($task.NextRunTime.ToString('yyyy-MM-dd HH:mm'))"
|
||||||
|
} else {
|
||||||
|
Write-Host "Next Run: Not yet scheduled"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "Next Run: Not available"
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
Write-Host "Next Run: Not available"
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Write-Host "Warning: No trigger found. Task needs to be reconfigured."
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Last Result: $($task.LastTaskResult)"
|
Write-Host "Last Result: $($task.LastTaskResult)"
|
||||||
Write-Host "Working Directory: $($task.Actions[0].WorkingDirectory)"
|
Write-Host "Working Directory: $($task.Actions[0].WorkingDirectory)"
|
||||||
Write-Host "Run As User: $($task.Principal.UserId)"
|
Write-Host "Run As User: $($task.Principal.UserId)"
|
||||||
Write-Host "Run Level: $($task.Principal.RunLevel)"
|
}
|
||||||
} else {
|
}
|
||||||
Write-Host "`nNo task found. Please set up a task using option 2."
|
|
||||||
|
if (-not $found) {
|
||||||
|
Write-Host "`nNo tasks found. Please set up tasks using options 2 or 3."
|
||||||
}
|
}
|
||||||
Pause-Script
|
Pause-Script
|
||||||
}
|
}
|
||||||
|
|
||||||
function Set-DailyTask {
|
function Set-DailyTask {
|
||||||
param (
|
param (
|
||||||
[string]$runTime = "23:00"
|
[string]$runTime = "23:00",
|
||||||
|
[string]$environment
|
||||||
)
|
)
|
||||||
|
|
||||||
Write-Host "`nSetting up daily task..."
|
$taskName = "${taskNamePrefix}_$environment"
|
||||||
|
Write-Host "`nSetting up daily task for $environment environment..."
|
||||||
|
|
||||||
$scriptPath = Join-Path $PSScriptRoot "run-tests.bat"
|
$scriptPath = Join-Path $PSScriptRoot "run-tests.bat"
|
||||||
if (-not (Test-Path $scriptPath)) {
|
if (-not (Test-Path $scriptPath)) {
|
||||||
@ -81,8 +90,9 @@ function Set-DailyTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
# 创建任务操作
|
# 创建任务操作 - 添加环境参数
|
||||||
$action = New-ScheduledTaskAction -Execute $scriptPath -WorkingDirectory $PSScriptRoot
|
$envArg = $environment.ToLower()
|
||||||
|
$action = New-ScheduledTaskAction -Execute $scriptPath -WorkingDirectory $PSScriptRoot -Argument $envArg
|
||||||
if (-not $action) {
|
if (-not $action) {
|
||||||
throw "Failed to create task action"
|
throw "Failed to create task action"
|
||||||
}
|
}
|
||||||
@ -127,7 +137,7 @@ function Set-DailyTask {
|
|||||||
} else {
|
} else {
|
||||||
# 创建新任务
|
# 创建新任务
|
||||||
$result = Register-ScheduledTask -TaskName $taskName `
|
$result = Register-ScheduledTask -TaskName $taskName `
|
||||||
-Description $taskDesc `
|
-Description "$taskDesc ($environment Environment)" `
|
||||||
-Action $action `
|
-Action $action `
|
||||||
-Trigger $trigger `
|
-Trigger $trigger `
|
||||||
-Settings $settings `
|
-Settings $settings `
|
||||||
@ -145,6 +155,7 @@ function Set-DailyTask {
|
|||||||
if ($updatedTask) {
|
if ($updatedTask) {
|
||||||
Write-Host "`nTask Details:"
|
Write-Host "`nTask Details:"
|
||||||
Write-Host "Task Name: $taskName"
|
Write-Host "Task Name: $taskName"
|
||||||
|
Write-Host "Environment: $environment"
|
||||||
Write-Host "Run Time: Daily at $runTime"
|
Write-Host "Run Time: Daily at $runTime"
|
||||||
if ($updatedTask.NextRunTime) {
|
if ($updatedTask.NextRunTime) {
|
||||||
Write-Host "Next Run: $($updatedTask.NextRunTime.ToString('yyyy-MM-dd HH:mm'))"
|
Write-Host "Next Run: $($updatedTask.NextRunTime.ToString('yyyy-MM-dd HH:mm'))"
|
||||||
@ -166,10 +177,25 @@ function Set-DailyTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Update-TaskTime {
|
function Update-TaskTime {
|
||||||
|
Write-Host "`nSelect environment:"
|
||||||
|
Write-Host "1. Development (dev)"
|
||||||
|
Write-Host "2. UAT"
|
||||||
|
Write-Host "`nEnter your choice (1-2): " -NoNewline
|
||||||
|
|
||||||
|
$envChoice = Read-Host
|
||||||
|
$environment = switch ($envChoice) {
|
||||||
|
"1" { "dev" }
|
||||||
|
"2" { "uat" }
|
||||||
|
default {
|
||||||
|
Write-Host "`nInvalid choice. Using default (dev)"
|
||||||
|
"dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "`nEnter new time (HH:mm, e.g. 02:00): " -NoNewline
|
Write-Host "`nEnter new time (HH:mm, e.g. 02:00): " -NoNewline
|
||||||
$newTime = Read-Host
|
$newTime = Read-Host
|
||||||
if ($newTime -match "^([01]?[0-9]|2[0-3]):[0-5][0-9]$") {
|
if ($newTime -match "^([01]?[0-9]|2[0-3]):[0-5][0-9]$") {
|
||||||
Set-DailyTask -runTime $newTime
|
Set-DailyTask -runTime $newTime -environment $environment
|
||||||
} else {
|
} else {
|
||||||
Write-Host "`nInvalid time format"
|
Write-Host "`nInvalid time format"
|
||||||
Pause-Script
|
Pause-Script
|
||||||
@ -177,11 +203,26 @@ function Update-TaskTime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Start-TestNow {
|
function Start-TestNow {
|
||||||
Write-Host "`nStarting test..."
|
Write-Host "`nSelect environment:"
|
||||||
|
Write-Host "1. Development (dev)"
|
||||||
|
Write-Host "2. UAT"
|
||||||
|
Write-Host "`nEnter your choice (1-2): " -NoNewline
|
||||||
|
|
||||||
|
$envChoice = Read-Host
|
||||||
|
$env = switch ($envChoice) {
|
||||||
|
"1" { "dev" }
|
||||||
|
"2" { "uat" }
|
||||||
|
default {
|
||||||
|
Write-Host "`nInvalid choice. Using default (dev)"
|
||||||
|
"dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nStarting test in $env environment..."
|
||||||
try {
|
try {
|
||||||
$scriptPath = Join-Path $PSScriptRoot "run-tests.bat"
|
$scriptPath = Join-Path $PSScriptRoot "run-tests.bat"
|
||||||
# 使用cmd直接运行,这样可以看到实时输出
|
# 使用cmd直接运行,这样可以看到实时输出
|
||||||
& cmd /c $scriptPath
|
& cmd /c $scriptPath $env
|
||||||
Write-Host "`nTest completed"
|
Write-Host "`nTest completed"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Host "`nError: $_"
|
Write-Host "`nError: $_"
|
||||||
@ -190,16 +231,37 @@ function Start-TestNow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Remove-AutomationTask {
|
function Remove-AutomationTask {
|
||||||
$task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
Write-Host "`nSelect tasks to delete:"
|
||||||
if ($task) {
|
Write-Host "1. DEV Environment Task"
|
||||||
try {
|
Write-Host "2. UAT Environment Task"
|
||||||
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
|
Write-Host "3. Both Tasks"
|
||||||
Write-Host "`nTask deleted"
|
Write-Host "`nEnter your choice (1-3): " -NoNewline
|
||||||
} catch {
|
|
||||||
Write-Host "`nError: $_"
|
$choice = Read-Host
|
||||||
|
$tasksToDelete = switch ($choice) {
|
||||||
|
"1" { @("Dev") }
|
||||||
|
"2" { @("UAT") }
|
||||||
|
"3" { @("Dev", "UAT") }
|
||||||
|
default {
|
||||||
|
Write-Host "`nInvalid choice."
|
||||||
|
Pause-Script
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($env in $tasksToDelete) {
|
||||||
|
$taskName = "${taskNamePrefix}_$env"
|
||||||
|
$task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
||||||
|
if ($task) {
|
||||||
|
try {
|
||||||
|
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
|
||||||
|
Write-Host "`nTask '$taskName' deleted"
|
||||||
|
} catch {
|
||||||
|
Write-Host "`nError deleting task '$taskName': $_"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "`nTask '$taskName' not found"
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Write-Host "`nNo task found"
|
|
||||||
}
|
}
|
||||||
Pause-Script
|
Pause-Script
|
||||||
}
|
}
|
||||||
@ -216,8 +278,17 @@ do {
|
|||||||
|
|
||||||
switch ($choice.ToUpper()) {
|
switch ($choice.ToUpper()) {
|
||||||
"1" { Get-TaskStatus }
|
"1" { Get-TaskStatus }
|
||||||
"2" { Set-DailyTask }
|
"2" { Set-DailyTask -environment "Dev" }
|
||||||
"3" { Update-TaskTime }
|
"3" {
|
||||||
|
Write-Host "`nEnter time for UAT task (HH:mm, e.g. 02:00): " -NoNewline
|
||||||
|
$uatTime = Read-Host
|
||||||
|
if ($uatTime -match "^([01]?[0-9]|2[0-3]):[0-5][0-9]$") {
|
||||||
|
Set-DailyTask -runTime $uatTime -environment "UAT"
|
||||||
|
} else {
|
||||||
|
Write-Host "`nInvalid time format"
|
||||||
|
Pause-Script
|
||||||
|
}
|
||||||
|
}
|
||||||
"4" { Start-TestNow }
|
"4" { Start-TestNow }
|
||||||
"5" { Remove-AutomationTask }
|
"5" { Remove-AutomationTask }
|
||||||
"Q" { exit }
|
"Q" { exit }
|
||||||
|
|||||||
@ -2,6 +2,18 @@
|
|||||||
const {defineConfig, devices} = require('@playwright/test');
|
const {defineConfig, devices} = require('@playwright/test');
|
||||||
const testLifecycle = require('./src/hooks/testLifecycle');
|
const testLifecycle = require('./src/hooks/testLifecycle');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read environment variables and process them
|
||||||
|
*/
|
||||||
|
function getBaseUrl() {
|
||||||
|
const baseUrl = process.env.BASE_URL;
|
||||||
|
if (!baseUrl) {
|
||||||
|
throw new Error('BASE_URL environment variable is not set');
|
||||||
|
}
|
||||||
|
// 确保基础URL不包含hash和query参数
|
||||||
|
return baseUrl.split('#')[0].split('?')[0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://playwright.dev/docs/test-configuration
|
* @see https://playwright.dev/docs/test-configuration
|
||||||
* @type {import('@playwright/test').PlaywrightTestConfig}
|
* @type {import('@playwright/test').PlaywrightTestConfig}
|
||||||
@ -25,7 +37,7 @@ const config = {
|
|||||||
/* 共享设置 */
|
/* 共享设置 */
|
||||||
use: {
|
use: {
|
||||||
/* 基础URL */
|
/* 基础URL */
|
||||||
baseURL: process.env.BASE_URL,
|
baseURL: getBaseUrl(),
|
||||||
/* 收集测试追踪信息 */
|
/* 收集测试追踪信息 */
|
||||||
trace: 'on-first-retry',
|
trace: 'on-first-retry',
|
||||||
/* 自动截图 */
|
/* 自动截图 */
|
||||||
|
|||||||
@ -5,9 +5,19 @@ cd /d %~dp0
|
|||||||
:: 设置控制台编码为UTF-8
|
:: 设置控制台编码为UTF-8
|
||||||
chcp 65001 > nul
|
chcp 65001 > nul
|
||||||
|
|
||||||
|
:: 设置默认环境为dev
|
||||||
|
if "%1"=="" (
|
||||||
|
set TEST_ENV=dev
|
||||||
|
) else (
|
||||||
|
set TEST_ENV=%1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo [Batch] Preparing to run tests in %TEST_ENV% environment...
|
||||||
|
|
||||||
:: 运行测试并发送报告
|
:: 运行测试并发送报告
|
||||||
|
set NODE_ENV=%TEST_ENV%
|
||||||
node src/scripts/runTestsAndSendReport.js
|
node src/scripts/runTestsAndSendReport.js
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Execution completed
|
echo [Batch] Execution completed
|
||||||
pause
|
pause
|
||||||
@ -76,10 +76,34 @@ class BasePage {
|
|||||||
* @param {string} url 目标URL
|
* @param {string} url 目标URL
|
||||||
*/
|
*/
|
||||||
async navigate(url) {
|
async navigate(url) {
|
||||||
|
// 先进行初始导航
|
||||||
await this.page.goto(url, {
|
await this.page.goto(url, {
|
||||||
waitUntil: 'networkidle',
|
waitUntil: 'networkidle',
|
||||||
timeout: this.config.timeout.navigate
|
timeout: this.config.timeout.navigate
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 获取当前URL
|
||||||
|
const currentUrl = await this.page.url();
|
||||||
|
|
||||||
|
// 如果原始URL包含hash或query参数,但当前URL没有,则重新导航
|
||||||
|
if (url !== currentUrl) {
|
||||||
|
// 解析原始URL中的hash和query参数
|
||||||
|
const urlParts = url.split('#');
|
||||||
|
if (urlParts.length > 1) {
|
||||||
|
// 等待一下以确保页面已经初步加载
|
||||||
|
await this.page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
// 使用evaluate来设置完整的URL
|
||||||
|
await this.page.evaluate((fullUrl) => {
|
||||||
|
window.location.href = fullUrl;
|
||||||
|
}, url);
|
||||||
|
|
||||||
|
// 等待页面加载完成
|
||||||
|
await this.page.waitForLoadState('networkidle', {
|
||||||
|
timeout: this.config.timeout.navigate
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -51,8 +51,12 @@ class LongiLoginPage extends BasePage {
|
|||||||
* 导航到登录页面
|
* 导航到登录页面
|
||||||
*/
|
*/
|
||||||
async navigateToLoginPage() {
|
async navigateToLoginPage() {
|
||||||
console.log('当前使用的 BASE_URL:', process.env.BASE_URL);
|
const baseUrl = process.env.BASE_URL;
|
||||||
await this.navigate(process.env.BASE_URL);
|
console.log('当前使用的 BASE_URL:', baseUrl);
|
||||||
|
|
||||||
|
// 确保使用完整的URL,包括hash和query参数
|
||||||
|
const fullUrl = baseUrl.includes('#') ? baseUrl : `${baseUrl}#/login?debug=ly`;
|
||||||
|
await this.navigate(fullUrl);
|
||||||
await this.waitForPageLoad();
|
await this.waitForPageLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,72 +2,122 @@ const { execSync } = require('child_process');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const emailService = require('../services/EmailService');
|
const emailService = require('../services/EmailService');
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
|
||||||
|
// 获取环境参数
|
||||||
|
const env = process.env.TEST_ENV || 'dev'; // 默认使用dev环境
|
||||||
|
console.log(`[Node] Starting test execution process...`);
|
||||||
|
console.log(`[Node] Current environment: ${env}`);
|
||||||
|
|
||||||
async function runTestsAndSendReport() {
|
async function runTestsAndSendReport() {
|
||||||
let testOutput = '';
|
let testOutput = '';
|
||||||
let testSuccess = false;
|
let testSuccess = false;
|
||||||
const startTime = new Date();
|
const startTime = new Date();
|
||||||
|
console.log(`[Node] Test started at: ${startTime.toLocaleString()}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 根据环境设置加载对应的环境变量文件
|
||||||
|
const envFile = `.env.${env}`;
|
||||||
|
console.log(`[Node] Loading environment file: ${envFile}`);
|
||||||
|
|
||||||
|
// 检查环境文件是否存在
|
||||||
|
if (!fs.existsSync(envFile)) {
|
||||||
|
console.error(`[Node] Error: Environment file ${envFile} not found!`);
|
||||||
|
throw new Error(`Environment file ${envFile} not found`);
|
||||||
|
}
|
||||||
|
console.log(`[Node] Environment file found successfully`);
|
||||||
|
|
||||||
|
// 加载环境变量
|
||||||
|
dotenv.config({ path: envFile });
|
||||||
|
console.log(`[Node] Environment variables loaded successfully`);
|
||||||
|
|
||||||
// 运行测试并捕获输出
|
// 运行测试并捕获输出
|
||||||
console.log('开始执行测试...');
|
console.log('[Node] ==========================================');
|
||||||
testOutput = execSync('npx playwright test', { encoding: 'utf8' });
|
console.log('[Node] Starting Playwright test execution...');
|
||||||
|
console.log('[Node] ==========================================');
|
||||||
|
|
||||||
|
testOutput = execSync('npx playwright test', {
|
||||||
|
encoding: 'utf8',
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
NODE_ENV: env
|
||||||
|
},
|
||||||
|
stdio: 'inherit' // 这将允许实时显示测试输出
|
||||||
|
});
|
||||||
|
|
||||||
testSuccess = true;
|
testSuccess = true;
|
||||||
console.log('测试执行完成');
|
console.log('[Node] ==========================================');
|
||||||
|
console.log('[Node] Test execution completed successfully');
|
||||||
|
console.log('[Node] ==========================================');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log('[Node] ==========================================');
|
||||||
|
console.error('[Node] Test execution failed with error:');
|
||||||
|
console.error(error.message);
|
||||||
|
console.log('[Node] ==========================================');
|
||||||
testOutput = error.output ? error.output.join('\n') : error.message;
|
testOutput = error.output ? error.output.join('\n') : error.message;
|
||||||
console.error('测试执行失败:', testOutput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const endTime = new Date();
|
const endTime = new Date();
|
||||||
const duration = (endTime - startTime) / 1000 / 60; // 转换为分钟
|
const duration = (endTime - startTime) / 1000 / 60; // 转换为分钟
|
||||||
|
console.log(`[Node] Test duration: ${duration.toFixed(2)} minutes`);
|
||||||
|
|
||||||
// 读取性能报告
|
// 读取性能报告
|
||||||
|
console.log('[Node] Attempting to read performance report...');
|
||||||
let performanceData = '';
|
let performanceData = '';
|
||||||
try {
|
try {
|
||||||
const reportPath = path.join(process.cwd(), 'test-results', 'performance-report.html');
|
const reportPath = path.join(process.cwd(), 'test-results', 'performance-report.html');
|
||||||
if (fs.existsSync(reportPath)) {
|
if (fs.existsSync(reportPath)) {
|
||||||
performanceData = fs.readFileSync(reportPath, 'utf8');
|
performanceData = fs.readFileSync(reportPath, 'utf8');
|
||||||
|
console.log('[Node] Performance report read successfully');
|
||||||
|
} else {
|
||||||
|
console.log('[Node] No performance report found');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('读取性能报告失败:', error);
|
console.error('[Node] Failed to read performance report:', error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建邮件内容
|
// 构建邮件内容
|
||||||
|
console.log('[Node] Preparing email report...');
|
||||||
const emailHtml = `
|
const emailHtml = `
|
||||||
<h1>Playwright 自动化测试报告</h1>
|
<h1>Playwright 自动化测试报告 (${env}环境)</h1>
|
||||||
<div style="margin: 20px 0; padding: 10px; background-color: ${testSuccess ? '#e6ffe6' : '#ffe6e6'}; border-radius: 5px;">
|
<div style="margin: 20px 0; padding: 10px; background-color: ${testSuccess ? '#e6ffe6' : '#ffe6e6'}; border-radius: 5px;">
|
||||||
<h2>测试结果: ${testSuccess ? '成功 ✅' : '失败 ❌'}</h2>
|
<h2>测试结果: ${testSuccess ? '成功 ✅' : '失败 ❌'}</h2>
|
||||||
|
<p>执行环境: ${env}</p>
|
||||||
<p>执行时间: ${startTime.toLocaleString()}</p>
|
<p>执行时间: ${startTime.toLocaleString()}</p>
|
||||||
<p>持续时间: ${duration.toFixed(2)} 分钟</p>
|
<p>持续时间: ${duration.toFixed(2)} 分钟</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>测试输出</h2>
|
|
||||||
<pre style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; overflow-x: auto;">
|
|
||||||
${testOutput}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
${performanceData ? '<h2>性能报告</h2>' + performanceData : ''}
|
${performanceData ? '<h2>性能报告</h2>' + performanceData : ''}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// 发送邮件
|
// 发送邮件
|
||||||
try {
|
try {
|
||||||
console.log('正在发送测试报告邮件...');
|
console.log('[Node] ==========================================');
|
||||||
|
console.log('[Node] Sending test report email...');
|
||||||
const result = await emailService.sendMail({
|
const result = await emailService.sendMail({
|
||||||
to: 'dengqichen@iscmtech.com',
|
to: 'dengqichen@iscmtech.com',
|
||||||
subject: `[${testSuccess ? '成功' : '失败'}] Playwright自动化测试报告 - ${startTime.toLocaleDateString()}`,
|
subject: `[${testSuccess ? '成功' : '失败'}] Playwright自动化测试报告 (${env}) - ${startTime.toLocaleDateString()}`,
|
||||||
html: emailHtml
|
html: emailHtml
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
console.log('测试报告邮件发送成功');
|
console.log('[Node] Test report email sent successfully');
|
||||||
} else {
|
} else {
|
||||||
console.error('测试报告邮件发送失败:', result.error);
|
console.error('[Node] Failed to send test report email:', result.error);
|
||||||
}
|
}
|
||||||
|
console.log('[Node] ==========================================');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('发送邮件时发生错误:', error);
|
console.log('[Node] ==========================================');
|
||||||
|
console.error('[Node] Error sending email:', error.message);
|
||||||
|
console.log('[Node] ==========================================');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行脚本
|
// 执行脚本
|
||||||
runTestsAndSendReport();
|
console.log('[Node] ==========================================');
|
||||||
|
console.log('[Node] Starting test automation process...');
|
||||||
|
console.log('[Node] ==========================================');
|
||||||
|
runTestsAndSendReport().catch(error => {
|
||||||
|
console.error('[Node] Fatal error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user