优化分批执行点击菜单
This commit is contained in:
parent
c9dc8a83ee
commit
f7fdf43abb
15
manage-automation.bat
Normal file
15
manage-automation.bat
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 > nul
|
||||||
|
echo Starting Task Manager...
|
||||||
|
|
||||||
|
net session >nul 2>&1
|
||||||
|
if %errorLevel% == 0 (
|
||||||
|
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0manage-task-new.ps1"
|
||||||
|
) else (
|
||||||
|
echo Run as Administrator required
|
||||||
|
echo Right-click and select "Run as Administrator"
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
exit
|
||||||
229
manage-task-new.ps1
Normal file
229
manage-task-new.ps1
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
# 设置控制台编码
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
|
||||||
|
# 获取当前目录的完整路径
|
||||||
|
$currentPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
|
||||||
|
$scriptPath = Join-Path $currentPath "run-tests.bat"
|
||||||
|
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
|
||||||
|
|
||||||
|
# Task Configuration
|
||||||
|
$taskName = "Playwright_AutoTest"
|
||||||
|
$taskDesc = "Run Playwright tests daily"
|
||||||
|
|
||||||
|
function Show-Menu {
|
||||||
|
Clear-Host
|
||||||
|
Write-Host "`n================== Playwright Test Manager ==================`n"
|
||||||
|
Write-Host "1. View Task Status"
|
||||||
|
Write-Host "2. Set Daily Task (Default: 23:00)"
|
||||||
|
Write-Host "3. Change Task Time"
|
||||||
|
Write-Host "4. Run Test Now"
|
||||||
|
Write-Host "5. Delete Task"
|
||||||
|
Write-Host "Q. Exit"
|
||||||
|
Write-Host "`nEnter your choice (1-5, or Q to exit): " -NoNewline
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-TaskStatus {
|
||||||
|
$task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
||||||
|
if ($task) {
|
||||||
|
Write-Host "`nTask Status:"
|
||||||
|
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))"
|
||||||
|
# 安全地处理 NextRunTime
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Warning: No trigger found. Task needs to be reconfigured."
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Last Result: $($task.LastTaskResult)"
|
||||||
|
Write-Host "Working Directory: $($task.Actions[0].WorkingDirectory)"
|
||||||
|
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."
|
||||||
|
}
|
||||||
|
Pause-Script
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-DailyTask {
|
||||||
|
param (
|
||||||
|
[string]$runTime = "23:00"
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "`nSetting up daily task..."
|
||||||
|
|
||||||
|
$scriptPath = Join-Path $PSScriptRoot "run-tests.bat"
|
||||||
|
if (-not (Test-Path $scriptPath)) {
|
||||||
|
Write-Host "`nError: Test script not found at: $scriptPath"
|
||||||
|
Write-Host "Path: $scriptPath"
|
||||||
|
Pause-Script
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# 确保时间格式正确
|
||||||
|
if ($runTime -notmatch "^([01]?[0-9]|2[0-3]):[0-5][0-9]$") {
|
||||||
|
Write-Host "`nError: Invalid time format. Please use HH:mm format (e.g., 23:00)"
|
||||||
|
Pause-Script
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
# 创建任务操作
|
||||||
|
$action = New-ScheduledTaskAction -Execute $scriptPath -WorkingDirectory $PSScriptRoot
|
||||||
|
if (-not $action) {
|
||||||
|
throw "Failed to create task action"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 创建任务触发器
|
||||||
|
$trigger = New-ScheduledTaskTrigger -Daily -At $runTime
|
||||||
|
if (-not $trigger) {
|
||||||
|
throw "Failed to create task trigger"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 创建任务设置
|
||||||
|
$settings = New-ScheduledTaskSettingsSet `
|
||||||
|
-RestartCount 3 `
|
||||||
|
-RestartInterval (New-TimeSpan -Minutes 5) `
|
||||||
|
-StartWhenAvailable `
|
||||||
|
-DontStopOnIdleEnd `
|
||||||
|
-ExecutionTimeLimit (New-TimeSpan -Hours 2)
|
||||||
|
if (-not $settings) {
|
||||||
|
throw "Failed to create task settings"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 创建任务主体
|
||||||
|
$principal = New-ScheduledTaskPrincipal -UserId $currentUser -RunLevel Highest
|
||||||
|
if (-not $principal) {
|
||||||
|
throw "Failed to create task principal"
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
||||||
|
if ($existingTask) {
|
||||||
|
# 更新现有任务
|
||||||
|
$result = Set-ScheduledTask -TaskName $taskName `
|
||||||
|
-Action $action `
|
||||||
|
-Trigger $trigger `
|
||||||
|
-Settings $settings `
|
||||||
|
-Principal $principal
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
Write-Host "`nTask successfully updated!"
|
||||||
|
} else {
|
||||||
|
throw "Failed to update task"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# 创建新任务
|
||||||
|
$result = Register-ScheduledTask -TaskName $taskName `
|
||||||
|
-Description $taskDesc `
|
||||||
|
-Action $action `
|
||||||
|
-Trigger $trigger `
|
||||||
|
-Settings $settings `
|
||||||
|
-Principal $principal
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
Write-Host "`nTask successfully created!"
|
||||||
|
} else {
|
||||||
|
throw "Failed to create task"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证任务创建/更新是否成功
|
||||||
|
$updatedTask = Get-ScheduledTask -TaskName $taskName -ErrorAction Stop
|
||||||
|
if ($updatedTask) {
|
||||||
|
Write-Host "`nTask Details:"
|
||||||
|
Write-Host "Task Name: $taskName"
|
||||||
|
Write-Host "Run Time: Daily at $runTime"
|
||||||
|
if ($updatedTask.NextRunTime) {
|
||||||
|
Write-Host "Next Run: $($updatedTask.NextRunTime.ToString('yyyy-MM-dd HH:mm'))"
|
||||||
|
} else {
|
||||||
|
Write-Host "Next Run: Not scheduled"
|
||||||
|
}
|
||||||
|
Write-Host "Status: $($updatedTask.State)"
|
||||||
|
Write-Host "Run As: $($updatedTask.Principal.UserId)"
|
||||||
|
} else {
|
||||||
|
Write-Host "`nWarning: Task was created but could not be verified."
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "`nError setting up task: $_"
|
||||||
|
Write-Host "Please make sure you have administrative privileges."
|
||||||
|
Write-Host "Error details: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
Pause-Script
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update-TaskTime {
|
||||||
|
Write-Host "`nEnter new time (HH:mm, e.g. 02:00): " -NoNewline
|
||||||
|
$newTime = Read-Host
|
||||||
|
if ($newTime -match "^([01]?[0-9]|2[0-3]):[0-5][0-9]$") {
|
||||||
|
Set-DailyTask -runTime $newTime
|
||||||
|
} else {
|
||||||
|
Write-Host "`nInvalid time format"
|
||||||
|
Pause-Script
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start-TestNow {
|
||||||
|
Write-Host "`nStarting test..."
|
||||||
|
try {
|
||||||
|
$scriptPath = Join-Path $PSScriptRoot "run-tests.bat"
|
||||||
|
# 使用cmd直接运行,这样可以看到实时输出
|
||||||
|
& cmd /c $scriptPath
|
||||||
|
Write-Host "`nTest completed"
|
||||||
|
} catch {
|
||||||
|
Write-Host "`nError: $_"
|
||||||
|
}
|
||||||
|
Pause-Script
|
||||||
|
}
|
||||||
|
|
||||||
|
function Remove-AutomationTask {
|
||||||
|
$task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
||||||
|
if ($task) {
|
||||||
|
try {
|
||||||
|
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
|
||||||
|
Write-Host "`nTask deleted"
|
||||||
|
} catch {
|
||||||
|
Write-Host "`nError: $_"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "`nNo task found"
|
||||||
|
}
|
||||||
|
Pause-Script
|
||||||
|
}
|
||||||
|
|
||||||
|
function Pause-Script {
|
||||||
|
Write-Host "`nPress Enter to continue..." -NoNewline
|
||||||
|
Read-Host
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main Loop
|
||||||
|
do {
|
||||||
|
Show-Menu
|
||||||
|
$choice = Read-Host
|
||||||
|
|
||||||
|
switch ($choice.ToUpper()) {
|
||||||
|
"1" { Get-TaskStatus }
|
||||||
|
"2" { Set-DailyTask }
|
||||||
|
"3" { Update-TaskTime }
|
||||||
|
"4" { Start-TestNow }
|
||||||
|
"5" { Remove-AutomationTask }
|
||||||
|
"Q" { exit }
|
||||||
|
default {
|
||||||
|
Write-Host "`nInvalid choice. Please try again."
|
||||||
|
Pause-Script
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ($true)
|
||||||
@ -27,7 +27,8 @@
|
|||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"commander": "^11.1.0",
|
"commander": "^11.1.0",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"faker": "^5.5.3"
|
"faker": "^5.5.3",
|
||||||
|
"nodemailer": "^6.10.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"allure-playwright": "^2.9.2",
|
"allure-playwright": "^2.9.2",
|
||||||
|
|||||||
13
run-tests.bat
Normal file
13
run-tests.bat
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@echo off
|
||||||
|
echo Starting automated tests...
|
||||||
|
cd /d %~dp0
|
||||||
|
|
||||||
|
:: 设置控制台编码为UTF-8
|
||||||
|
chcp 65001 > nul
|
||||||
|
|
||||||
|
:: 运行测试并发送报告
|
||||||
|
node src/scripts/runTestsAndSendReport.js
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Execution completed
|
||||||
|
pause
|
||||||
73
src/scripts/runTestsAndSendReport.js
Normal file
73
src/scripts/runTestsAndSendReport.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
const { execSync } = require('child_process');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const emailService = require('../services/EmailService');
|
||||||
|
|
||||||
|
async function runTestsAndSendReport() {
|
||||||
|
let testOutput = '';
|
||||||
|
let testSuccess = false;
|
||||||
|
const startTime = new Date();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 运行测试并捕获输出
|
||||||
|
console.log('开始执行测试...');
|
||||||
|
testOutput = execSync('npx playwright test', { encoding: 'utf8' });
|
||||||
|
testSuccess = true;
|
||||||
|
console.log('测试执行完成');
|
||||||
|
} catch (error) {
|
||||||
|
testOutput = error.output ? error.output.join('\n') : error.message;
|
||||||
|
console.error('测试执行失败:', testOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
const endTime = new Date();
|
||||||
|
const duration = (endTime - startTime) / 1000 / 60; // 转换为分钟
|
||||||
|
|
||||||
|
// 读取性能报告
|
||||||
|
let performanceData = '';
|
||||||
|
try {
|
||||||
|
const reportPath = path.join(process.cwd(), 'test-results', 'performance-report.html');
|
||||||
|
if (fs.existsSync(reportPath)) {
|
||||||
|
performanceData = fs.readFileSync(reportPath, 'utf8');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('读取性能报告失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建邮件内容
|
||||||
|
const emailHtml = `
|
||||||
|
<h1>Playwright 自动化测试报告</h1>
|
||||||
|
<div style="margin: 20px 0; padding: 10px; background-color: ${testSuccess ? '#e6ffe6' : '#ffe6e6'}; border-radius: 5px;">
|
||||||
|
<h2>测试结果: ${testSuccess ? '成功 ✅' : '失败 ❌'}</h2>
|
||||||
|
<p>执行时间: ${startTime.toLocaleString()}</p>
|
||||||
|
<p>持续时间: ${duration.toFixed(2)} 分钟</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>测试输出</h2>
|
||||||
|
<pre style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; overflow-x: auto;">
|
||||||
|
${testOutput}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
${performanceData ? '<h2>性能报告</h2>' + performanceData : ''}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
|
try {
|
||||||
|
console.log('正在发送测试报告邮件...');
|
||||||
|
const result = await emailService.sendMail({
|
||||||
|
to: 'dengqichen@iscmtech.com',
|
||||||
|
subject: `[${testSuccess ? '成功' : '失败'}] Playwright自动化测试报告 - ${startTime.toLocaleDateString()}`,
|
||||||
|
html: emailHtml
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
console.log('测试报告邮件发送成功');
|
||||||
|
} else {
|
||||||
|
console.error('测试报告邮件发送失败:', result.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('发送邮件时发生错误:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行脚本
|
||||||
|
runTestsAndSendReport();
|
||||||
31
src/scripts/testEmail.js
Normal file
31
src/scripts/testEmail.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
const emailService = require('../services/EmailService');
|
||||||
|
|
||||||
|
async function testEmailSending() {
|
||||||
|
const testEmail = {
|
||||||
|
to: 'dengqichen@iscmtech.com', // 修改为指定的收件邮箱
|
||||||
|
subject: '测试邮件 - Playwright自动化测试',
|
||||||
|
html: `
|
||||||
|
<h1>Playwright自动化测试邮件</h1>
|
||||||
|
<p>这是一封测试邮件,用于验证邮件发送功能是否正常工作。</p>
|
||||||
|
<p>发送时间:${new Date().toLocaleString()}</p>
|
||||||
|
`
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('开始发送测试邮件...');
|
||||||
|
const result = await emailService.sendMail(testEmail);
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
console.log('测试邮件发送成功!');
|
||||||
|
console.log('消息ID:', result.messageId);
|
||||||
|
} else {
|
||||||
|
console.error('测试邮件发送失败!');
|
||||||
|
console.error('错误信息:', result.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('执行测试时发生错误:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行测试
|
||||||
|
testEmailSending();
|
||||||
43
src/services/EmailService.js
Normal file
43
src/services/EmailService.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
const nodemailer = require('nodemailer');
|
||||||
|
|
||||||
|
class EmailService {
|
||||||
|
constructor() {
|
||||||
|
this.transporter = nodemailer.createTransport({
|
||||||
|
host: 'smtphz.qiye.163.com',
|
||||||
|
port: 465,
|
||||||
|
secure: true,
|
||||||
|
auth: {
|
||||||
|
user: 'monitor@iscmtech.com',
|
||||||
|
pass: 'qiye2024@'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮件
|
||||||
|
* @param {Object} options 邮件选项
|
||||||
|
* @param {string} options.to 收件人邮箱
|
||||||
|
* @param {string} options.subject 邮件主题
|
||||||
|
* @param {string} options.html HTML格式的邮件内容
|
||||||
|
* @returns {Promise<Object>} 发送结果
|
||||||
|
*/
|
||||||
|
async sendMail({ to, subject, html }) {
|
||||||
|
try {
|
||||||
|
const mailOptions = {
|
||||||
|
from: 'monitor@iscmtech.com',
|
||||||
|
to,
|
||||||
|
subject,
|
||||||
|
html
|
||||||
|
};
|
||||||
|
|
||||||
|
const info = await this.transporter.sendMail(mailOptions);
|
||||||
|
console.log('邮件发送成功:', info.messageId);
|
||||||
|
return { success: true, messageId: info.messageId };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('邮件发送失败:', error);
|
||||||
|
return { success: false, error: error.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new EmailService();
|
||||||
@ -1 +1,4 @@
|
|||||||
[]
|
[
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]
|
||||||
Loading…
Reference in New Issue
Block a user