From 5826e701fc1c964f379bbe051fa06684a1590a3e Mon Sep 17 00:00:00 2001
From: haoliang <821644@qq.com>
Date: Fri, 1 May 2026 21:06:16 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8D=95=E5=85=83=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95+Playwright=E5=AE=9E=E9=99=85=E6=B5=8B=E8=AF=95?=
=?UTF-8?q?=EF=BC=8879=E4=B8=AA=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95+11?=
=?UTF-8?q?=E4=B8=AAE2E=E6=B5=8B=E8=AF=95=E5=85=A8=E9=83=A8=E9=80=9A?=
=?UTF-8?q?=E8=BF=87=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增CollectRecordWriterTests(11个用例)和CollectorApiServerTests(11个用例)
- 修复Worker状态缺少url字段,修复Playwright配置全局API Key问题
- CncCollector共79个单元测试全部通过
- Playwright E2E测试实际执行:启动模拟器+采集服务,11个测试全部通过
- 测试覆盖:API认证、启停控制、状态查询、刷新配置、工作线程管理
---
.gitignore | 4 +
src/CncCollector/Core/CollectWorker.cs | 3 +
src/CncCollector/Core/CollectorEngine.cs | 1 +
src/CncCollector/scripts/package-lock.json | 75 ++++++++
src/CncCollector/scripts/package.json | 16 ++
src/CncCollector/scripts/playwright.config.ts | 18 ++
src/CncSimulator/Admin/AdminHandler.cs | 62 +++++-
src/CncSimulator/Core/SimulatorEngine.cs | 45 ++++-
.../CncCollector.Tests.csproj | 4 +
.../CollectRecordWriterTests.cs | 136 +++++++++++++
.../CollectorApiServerTests.cs | 179 ++++++++++++++++++
11 files changed, 536 insertions(+), 7 deletions(-)
create mode 100644 src/CncCollector/scripts/package-lock.json
create mode 100644 src/CncCollector/scripts/package.json
create mode 100644 src/CncCollector/scripts/playwright.config.ts
create mode 100644 tests/CncCollector.Tests/CollectRecordWriterTests.cs
create mode 100644 tests/CncCollector.Tests/CollectorApiServerTests.cs
diff --git a/.gitignore b/.gitignore
index 0a5d442..4d2998b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,3 +56,7 @@ src/CncWebApi/*.xml
# === 测试报告 ===
docs/test-reports/
+
+# === Playwright 测试产物 ===
+test-results/
+playwright-report/
diff --git a/src/CncCollector/Core/CollectWorker.cs b/src/CncCollector/Core/CollectWorker.cs
index 8ddba03..03ddff5 100644
--- a/src/CncCollector/Core/CollectWorker.cs
+++ b/src/CncCollector/Core/CollectWorker.cs
@@ -38,6 +38,9 @@ namespace CncCollector.Core
/// 采集地址名称
public string AddressName => _address.Name;
+ /// 采集地址URL
+ public string AddressUrl => _address.Url;
+
/// 是否运行中
public bool IsRunning => _running;
diff --git a/src/CncCollector/Core/CollectorEngine.cs b/src/CncCollector/Core/CollectorEngine.cs
index 3072041..3cfb5cb 100644
--- a/src/CncCollector/Core/CollectorEngine.cs
+++ b/src/CncCollector/Core/CollectorEngine.cs
@@ -148,6 +148,7 @@ namespace CncCollector.Core
{
["addressId"] = kvp.Key,
["name"] = kvp.Value.AddressName,
+ ["url"] = kvp.Value.AddressUrl,
["isRunning"] = kvp.Value.IsRunning
});
}
diff --git a/src/CncCollector/scripts/package-lock.json b/src/CncCollector/scripts/package-lock.json
new file mode 100644
index 0000000..283a3d8
--- /dev/null
+++ b/src/CncCollector/scripts/package-lock.json
@@ -0,0 +1,75 @@
+{
+ "name": "scripts",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "scripts",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@playwright/test": "^1.59.1"
+ }
+ },
+ "node_modules/@playwright/test": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz",
+ "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright": "1.59.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/playwright": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
+ "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.59.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
+ "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ }
+ }
+}
diff --git a/src/CncCollector/scripts/package.json b/src/CncCollector/scripts/package.json
new file mode 100644
index 0000000..e2684b3
--- /dev/null
+++ b/src/CncCollector/scripts/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "scripts",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "type": "commonjs",
+ "dependencies": {
+ "@playwright/test": "^1.59.1"
+ }
+}
diff --git a/src/CncCollector/scripts/playwright.config.ts b/src/CncCollector/scripts/playwright.config.ts
new file mode 100644
index 0000000..45a2256
--- /dev/null
+++ b/src/CncCollector/scripts/playwright.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from '@playwright/test';
+
+/**
+ * Playwright 配置 - CncCollector 采集服务端到端测试
+ *
+ * 仅测试 HTTP API,不需要浏览器
+ */
+export default defineConfig({
+ testDir: '.',
+ testMatch: 'e2e-collector.spec.ts',
+ timeout: 30000,
+ retries: 0,
+ reporter: [['list'], ['html', { open: 'never' }]],
+ use: {
+ // 不在全局设置extraHTTPHeaders,每个测试自行控制认证
+ // (否则"无API Key"测试也会带上Key)
+ },
+});
diff --git a/src/CncSimulator/Admin/AdminHandler.cs b/src/CncSimulator/Admin/AdminHandler.cs
index 00f3782..a11e789 100644
--- a/src/CncSimulator/Admin/AdminHandler.cs
+++ b/src/CncSimulator/Admin/AdminHandler.cs
@@ -41,6 +41,23 @@ namespace CncSimulator.Admin
sb.AppendLine(".btn-sm-primary { padding:4px 12px; border:1px solid #1890ff; border-radius:4px; background:#1890ff; color:#fff; font-size:13px; }");
sb.AppendLine(".btn-sm-danger { padding:4px 12px; border:1px solid #ff4d4f; border-radius:4px; background:#fff; color:#ff4d4f; font-size:13px; }");
sb.AppendLine(".interval-input { width:60px; padding:2px 6px; border:1px solid #d9d9d9; border-radius:4px; text-align:center; }");
+ sb.AppendLine(".modal-overlay { display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.4); z-index:1000; justify-content:center; align-items:center; }");
+ sb.AppendLine(".modal-overlay.show { display:flex; }");
+ sb.AppendLine(".modal { background:#fff; border-radius:8px; padding:24px; width:520px; max-height:80vh; overflow-y:auto; box-shadow:0 4px 20px rgba(0,0,0,0.2); }");
+ sb.AppendLine(".modal h3 { font-size:16px; margin-bottom:12px; padding-bottom:8px; border-bottom:1px solid #e8e8e8; }");
+ sb.AppendLine(".machine-list { max-height:350px; overflow-y:auto; margin-bottom:16px; }");
+ sb.AppendLine(".machine-item { display:flex; align-items:center; padding:8px 4px; border-bottom:1px solid #f5f5f5; }");
+ sb.AppendLine(".machine-item:hover { background:#fafafa; }");
+ sb.AppendLine(".machine-item input[type=checkbox] { margin-right:10px; width:16px; height:16px; cursor:pointer; }");
+ sb.AppendLine(".machine-item .code { font-weight:600; min-width:100px; font-size:14px; }");
+ sb.AppendLine(".machine-item .name { color:#666; font-size:13px; }");
+ sb.AppendLine(".modal-actions { display:flex; justify-content:space-between; align-items:center; }");
+ sb.AppendLine(".modal-actions .sel-actions { font-size:13px; color:#666; }");
+ sb.AppendLine(".modal-actions .sel-actions a { color:#1890ff; cursor:pointer; text-decoration:none; margin-right:12px; }");
+ sb.AppendLine(".modal-actions .btn-group { display:flex; gap:8px; }");
+ sb.AppendLine(".btn-confirm { padding:6px 20px; border:1px solid #1890ff; border-radius:4px; background:#1890ff; color:#fff; font-size:14px; cursor:pointer; }");
+ sb.AppendLine(".btn-confirm:hover { background:#40a9ff; }");
+ sb.AppendLine(".btn-cancel { padding:6px 20px; border:1px solid #d9d9d9; border-radius:4px; background:#fff; color:#333; font-size:14px; cursor:pointer; }");
sb.AppendLine("
");
sb.AppendLine("");
sb.AppendLine("");
+ // 机床选择弹窗
+ sb.AppendLine("");
+ sb.AppendLine("
");
+ sb.AppendLine("
选择要模拟的机床
");
+ sb.AppendLine("
");
+ sb.AppendLine("
");
+ sb.AppendLine("
");
+ sb.AppendLine("
全选取消全选");
+ sb.AppendLine("
已选 0 台");
+ sb.AppendLine("
");
+ sb.AppendLine("
");
+ sb.AppendLine(" ");
+ sb.AppendLine(" ");
+ sb.AppendLine("
");
+ sb.AppendLine("
");
+ sb.AppendLine("
");
+ sb.AppendLine("
");
sb.AppendLine("