@creatoria/miniapp-mcp 0.1.2 → 0.2.0
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/README.md +14 -3
- package/dist/app/cli/index.d.ts +6 -0
- package/dist/app/cli/index.d.ts.map +1 -0
- package/dist/app/cli/index.js +6 -0
- package/dist/app/cli/index.js.map +1 -0
- package/dist/app/index.d.ts +6 -0
- package/dist/app/index.d.ts.map +1 -0
- package/dist/app/index.js +6 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/server/index.d.ts +7 -0
- package/dist/app/server/index.d.ts.map +1 -0
- package/dist/app/server/index.js +6 -0
- package/dist/app/server/index.js.map +1 -0
- package/dist/capabilities/assert/index.d.ts +5 -0
- package/dist/capabilities/assert/index.d.ts.map +1 -0
- package/dist/capabilities/assert/index.js +5 -0
- package/dist/capabilities/assert/index.js.map +1 -0
- package/dist/capabilities/automator/index.d.ts +6 -0
- package/dist/capabilities/automator/index.d.ts.map +1 -0
- package/dist/capabilities/automator/index.js +6 -0
- package/dist/capabilities/automator/index.js.map +1 -0
- package/dist/capabilities/automator/schemas/close.d.ts +5 -0
- package/dist/capabilities/automator/schemas/close.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/close.js +11 -0
- package/dist/capabilities/automator/schemas/close.js.map +1 -0
- package/dist/capabilities/automator/schemas/connect.d.ts +11 -0
- package/dist/capabilities/automator/schemas/connect.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/connect.js +19 -0
- package/dist/capabilities/automator/schemas/connect.js.map +1 -0
- package/dist/capabilities/automator/schemas/disconnect.d.ts +5 -0
- package/dist/capabilities/automator/schemas/disconnect.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/disconnect.js +11 -0
- package/dist/capabilities/automator/schemas/disconnect.js.map +1 -0
- package/dist/capabilities/automator/schemas/index.d.ts +4 -0
- package/dist/capabilities/automator/schemas/index.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/index.js +12 -0
- package/dist/capabilities/automator/schemas/index.js.map +1 -0
- package/dist/capabilities/automator/schemas/launch.d.ts +17 -0
- package/dist/capabilities/automator/schemas/launch.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/launch.js +26 -0
- package/dist/capabilities/automator/schemas/launch.js.map +1 -0
- package/dist/capabilities/element/index.d.ts +5 -0
- package/dist/capabilities/element/index.d.ts.map +1 -0
- package/dist/capabilities/element/index.js +5 -0
- package/dist/capabilities/element/index.js.map +1 -0
- package/dist/capabilities/index.d.ts +15 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +14 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/miniprogram/index.d.ts +5 -0
- package/dist/capabilities/miniprogram/index.d.ts.map +1 -0
- package/dist/capabilities/miniprogram/index.js +5 -0
- package/dist/capabilities/miniprogram/index.js.map +1 -0
- package/dist/capabilities/network/index.d.ts +5 -0
- package/dist/capabilities/network/index.d.ts.map +1 -0
- package/dist/capabilities/network/index.js +5 -0
- package/dist/capabilities/network/index.js.map +1 -0
- package/dist/capabilities/page/index.d.ts +5 -0
- package/dist/capabilities/page/index.d.ts.map +1 -0
- package/dist/capabilities/page/index.js +5 -0
- package/dist/capabilities/page/index.js.map +1 -0
- package/dist/capabilities/record/index.d.ts +5 -0
- package/dist/capabilities/record/index.d.ts.map +1 -0
- package/dist/capabilities/record/index.js +5 -0
- package/dist/capabilities/record/index.js.map +1 -0
- package/dist/capabilities/schema-registry.d.ts +4 -0
- package/dist/capabilities/schema-registry.d.ts.map +1 -0
- package/dist/capabilities/schema-registry.js +18 -0
- package/dist/capabilities/schema-registry.js.map +1 -0
- package/dist/capabilities/schema-types.d.ts +22 -0
- package/dist/capabilities/schema-types.d.ts.map +1 -0
- package/dist/capabilities/schema-types.js +2 -0
- package/dist/capabilities/schema-types.js.map +1 -0
- package/dist/capabilities/snapshot/index.d.ts +5 -0
- package/dist/capabilities/snapshot/index.d.ts.map +1 -0
- package/dist/capabilities/snapshot/index.js +5 -0
- package/dist/capabilities/snapshot/index.js.map +1 -0
- package/dist/config/loader.js +1 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/core/element-ref.d.ts +1 -43
- package/dist/core/element-ref.d.ts.map +1 -1
- package/dist/core/element-ref.js +1 -212
- package/dist/core/element-ref.js.map +1 -1
- package/dist/core/logger.d.ts +1 -54
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +1 -377
- package/dist/core/logger.js.map +1 -1
- package/dist/core/output.d.ts +1 -20
- package/dist/core/output.d.ts.map +1 -1
- package/dist/core/output.js +1 -55
- package/dist/core/output.js.map +1 -1
- package/dist/core/report-generator.d.ts +1 -23
- package/dist/core/report-generator.d.ts.map +1 -1
- package/dist/core/report-generator.js +1 -211
- package/dist/core/report-generator.js.map +1 -1
- package/dist/core/session.d.ts +2 -82
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +2 -305
- package/dist/core/session.js.map +1 -1
- package/dist/core/timeout.d.ts +1 -48
- package/dist/core/timeout.d.ts.map +1 -1
- package/dist/core/timeout.js +1 -66
- package/dist/core/timeout.js.map +1 -1
- package/dist/core/tool-logger.d.ts +1 -82
- package/dist/core/tool-logger.d.ts.map +1 -1
- package/dist/core/tool-logger.js +1 -452
- package/dist/core/tool-logger.js.map +1 -1
- package/dist/core/validation.d.ts +1 -38
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +1 -92
- package/dist/core/validation.js.map +1 -1
- package/dist/runtime/element/element-ref.d.ts +44 -0
- package/dist/runtime/element/element-ref.d.ts.map +1 -0
- package/dist/runtime/element/element-ref.js +214 -0
- package/dist/runtime/element/element-ref.js.map +1 -0
- package/dist/runtime/element/index.d.ts +2 -0
- package/dist/runtime/element/index.d.ts.map +1 -0
- package/dist/runtime/element/index.js +2 -0
- package/dist/runtime/element/index.js.map +1 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/logging/index.d.ts +3 -0
- package/dist/runtime/logging/index.d.ts.map +1 -0
- package/dist/runtime/logging/index.js +3 -0
- package/dist/runtime/logging/index.js.map +1 -0
- package/dist/runtime/logging/logger.d.ts +55 -0
- package/dist/runtime/logging/logger.d.ts.map +1 -0
- package/dist/runtime/logging/logger.js +379 -0
- package/dist/runtime/logging/logger.js.map +1 -0
- package/dist/runtime/logging/tool-logger.d.ts +83 -0
- package/dist/runtime/logging/tool-logger.d.ts.map +1 -0
- package/dist/runtime/logging/tool-logger.js +454 -0
- package/dist/runtime/logging/tool-logger.js.map +1 -0
- package/dist/runtime/outputs/index.d.ts +3 -0
- package/dist/runtime/outputs/index.d.ts.map +1 -0
- package/dist/runtime/outputs/index.js +3 -0
- package/dist/runtime/outputs/index.js.map +1 -0
- package/dist/runtime/outputs/output-manager.d.ts +12 -0
- package/dist/runtime/outputs/output-manager.d.ts.map +1 -0
- package/dist/runtime/outputs/output-manager.js +39 -0
- package/dist/runtime/outputs/output-manager.js.map +1 -0
- package/dist/runtime/outputs/report-generator.d.ts +5 -0
- package/dist/runtime/outputs/report-generator.d.ts.map +1 -0
- package/dist/runtime/outputs/report-generator.js +175 -0
- package/dist/runtime/outputs/report-generator.js.map +1 -0
- package/dist/runtime/session/index.d.ts +3 -0
- package/dist/runtime/session/index.d.ts.map +1 -0
- package/dist/runtime/session/index.js +3 -0
- package/dist/runtime/session/index.js.map +1 -0
- package/dist/runtime/session/store.d.ts +28 -0
- package/dist/runtime/session/store.d.ts.map +1 -0
- package/dist/runtime/session/store.js +154 -0
- package/dist/runtime/session/store.js.map +1 -0
- package/dist/runtime/session/utils/cleanup.d.ts +3 -0
- package/dist/runtime/session/utils/cleanup.d.ts.map +1 -0
- package/dist/runtime/session/utils/cleanup.js +78 -0
- package/dist/runtime/session/utils/cleanup.js.map +1 -0
- package/dist/runtime/timeout/index.d.ts +2 -0
- package/dist/runtime/timeout/index.d.ts.map +1 -0
- package/dist/runtime/timeout/index.js +2 -0
- package/dist/runtime/timeout/index.js.map +1 -0
- package/dist/runtime/timeout/timeout.d.ts +49 -0
- package/dist/runtime/timeout/timeout.d.ts.map +1 -0
- package/dist/runtime/timeout/timeout.js +67 -0
- package/dist/runtime/timeout/timeout.js.map +1 -0
- package/dist/runtime/validation/index.d.ts +2 -0
- package/dist/runtime/validation/index.d.ts.map +1 -0
- package/dist/runtime/validation/index.js +2 -0
- package/dist/runtime/validation/index.js.map +1 -0
- package/dist/runtime/validation/validation.d.ts +39 -0
- package/dist/runtime/validation/validation.d.ts.map +1 -0
- package/dist/runtime/validation/validation.js +93 -0
- package/dist/runtime/validation/validation.js.map +1 -0
- package/dist/schemas/automator/miniprogram_close.json +12 -0
- package/dist/schemas/automator/miniprogram_connect.json +19 -0
- package/dist/schemas/automator/miniprogram_disconnect.json +12 -0
- package/dist/schemas/automator/miniprogram_launch.json +30 -0
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/miniprogram.d.ts +2 -1
- package/dist/tools/miniprogram.d.ts.map +1 -1
- package/dist/tools/miniprogram.js +19 -24
- package/dist/tools/miniprogram.js.map +1 -1
- package/dist/tools/page.js +2 -2
- package/dist/tools/page.js.map +1 -1
- package/docs/directory-structure-and-code-style-best-practices.md +91 -0
- package/docs/migration/README.md +34 -0
- package/docs/migration/TC-ALIGN-01-notes.md +35 -0
- package/docs/migration/runtime-skeleton.md +50 -0
- package/docs/migration/tool-schema-strategy.md +75 -0
- package/docs//345/256/214/346/225/264/345/256/236/347/216/260/346/226/271/346/241/210.md +14 -14
- package/docs//347/254/254/344/270/200/347/211/210/346/234/254/346/226/271/346/241/210.md +7 -7
- package/package.json +4 -2
- package/docs/SIMPLE_USAGE.md +0 -210
- package/docs/architecture.E-Docs.md +0 -1359
- package/docs/architecture.F1.md +0 -720
- package/docs/architecture.F2.md +0 -871
- package/docs/architecture.F3.md +0 -905
- package/docs/architecture.md +0 -90
- package/docs/charter.A1.align.yaml +0 -170
- package/docs/charter.A2.align.yaml +0 -199
- package/docs/charter.A3.align.yaml +0 -242
- package/docs/charter.A4.align.yaml +0 -227
- package/docs/charter.B1.align.yaml +0 -179
- package/docs/charter.B2.align.yaml +0 -200
- package/docs/charter.B3.align.yaml +0 -200
- package/docs/charter.B4.align.yaml +0 -188
- package/docs/charter.C1.align.yaml +0 -190
- package/docs/charter.C2.align.yaml +0 -202
- package/docs/charter.C3.align.yaml +0 -211
- package/docs/charter.C4.align.yaml +0 -263
- package/docs/charter.C5.align.yaml +0 -220
- package/docs/charter.D1.align.yaml +0 -190
- package/docs/charter.D2.align.yaml +0 -234
- package/docs/charter.D3.align.yaml +0 -206
- package/docs/charter.E-Docs.align.yaml +0 -294
- package/docs/charter.F1.align.yaml +0 -193
- package/docs/charter.F2.align.yaml +0 -248
- package/docs/charter.F3.align.yaml +0 -287
- package/docs/charter.G.align.yaml +0 -174
- package/docs/charter.align.yaml +0 -111
- package/docs/maintenance.md +0 -682
- package/docs/playwright-mcp/350/260/203/347/240/224.md +0 -53
- package/docs/setup-guide.md +0 -775
- package/docs/tasks.A1.atomize.md +0 -296
- package/docs/tasks.A2.atomize.md +0 -408
- package/docs/tasks.A3.atomize.md +0 -564
- package/docs/tasks.A4.atomize.md +0 -496
- package/docs/tasks.B1.atomize.md +0 -352
- package/docs/tasks.B2.atomize.md +0 -561
- package/docs/tasks.B3.atomize.md +0 -508
- package/docs/tasks.B4.atomize.md +0 -504
- package/docs/tasks.C1.atomize.md +0 -540
- package/docs/tasks.C2.atomize.md +0 -665
- package/docs/tasks.C3.atomize.md +0 -745
- package/docs/tasks.C4.atomize.md +0 -908
- package/docs/tasks.C5.atomize.md +0 -755
- package/docs/tasks.D1.atomize.md +0 -547
- package/docs/tasks.D2.atomize.md +0 -619
- package/docs/tasks.D3.atomize.md +0 -790
- package/docs/tasks.E-Docs.atomize.md +0 -1204
- package/docs/tasks.atomize.md +0 -189
package/docs/tasks.D1.atomize.md
DELETED
|
@@ -1,547 +0,0 @@
|
|
|
1
|
-
# Task Card: [D1] 断言工具集
|
|
2
|
-
|
|
3
|
-
**Task ID**: D1
|
|
4
|
-
**Task Name**: 断言工具集实现
|
|
5
|
-
**Charter**: `docs/charter.D1.align.yaml`
|
|
6
|
-
**Stage**: D (Advanced Capabilities)
|
|
7
|
-
**Status**: ✅ COMPLETED (Retrospective)
|
|
8
|
-
**Estimated**: 2-3 hours
|
|
9
|
-
**Actual**: ~2.5 hours
|
|
10
|
-
**Completed**: 2025-10-02
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## 目标 (Goal)
|
|
15
|
-
|
|
16
|
-
实现 9 个断言工具,为小程序自动化测试提供完整的验证能力,覆盖元素存在性、文本内容、表单值、属性状态和页面数据。
|
|
17
|
-
|
|
18
|
-
**交付物**:
|
|
19
|
-
- ✅ `src/tools/assert.ts` (465 lines)
|
|
20
|
-
- ✅ `tests/unit/assert.test.ts` (394 lines, 27 tests)
|
|
21
|
-
- ✅ 9 个断言工具全部实现
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 前置条件 (Prerequisites)
|
|
26
|
-
|
|
27
|
-
- ✅ C3: Page 工具(query, getData)
|
|
28
|
-
- ✅ C4: Element 工具(getText, getValue, getAttribute, getProperty, getSize)
|
|
29
|
-
- ✅ SessionState 定义完成
|
|
30
|
-
- ✅ 了解断言模式(预期值 vs 实际值)
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 实现步骤 (Steps)
|
|
35
|
-
|
|
36
|
-
### 1. 创建断言工具文件 ✅
|
|
37
|
-
|
|
38
|
-
**文件**: `src/tools/assert.ts`
|
|
39
|
-
|
|
40
|
-
**步骤**:
|
|
41
|
-
```typescript
|
|
42
|
-
import type { SessionState } from '../types.js'
|
|
43
|
-
import * as pageTools from './page.js'
|
|
44
|
-
import * as elementTools from './element.js'
|
|
45
|
-
|
|
46
|
-
// 定义断言函数
|
|
47
|
-
export async function assertExists(
|
|
48
|
-
session: SessionState,
|
|
49
|
-
args: { selector: string; pagePath?: string }
|
|
50
|
-
): Promise<{ success: boolean; message: string }> {
|
|
51
|
-
// 实现...
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**验证**: TypeScript 编译通过,正确导入依赖
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
### 2. 实现元素存在性断言 ✅
|
|
60
|
-
|
|
61
|
-
**工具 1: assertExists**
|
|
62
|
-
```typescript
|
|
63
|
-
export async function assertExists(session, args) {
|
|
64
|
-
const { selector, pagePath } = args
|
|
65
|
-
const logger = session.logger
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
const result = await pageTools.query(session, {
|
|
69
|
-
selector,
|
|
70
|
-
pagePath,
|
|
71
|
-
save: false,
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
if (!result.exists) {
|
|
75
|
-
throw new Error(`Assertion failed: Element not found with selector: ${selector}`)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
success: true,
|
|
80
|
-
message: `Element exists: ${selector}`,
|
|
81
|
-
}
|
|
82
|
-
} catch (error) {
|
|
83
|
-
throw new Error(`Assertion failed: ${errorMessage}`)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**工具 2: assertNotExists**
|
|
89
|
-
```typescript
|
|
90
|
-
export async function assertNotExists(session, args) {
|
|
91
|
-
// 逻辑相反:exists = true 则失败
|
|
92
|
-
// 特殊处理:query 抛错 "Element not found" 视为成功
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**验证**:
|
|
97
|
-
- ✅ 存在时返回 success
|
|
98
|
-
- ✅ 不存在时抛出错误
|
|
99
|
-
- ✅ 错误消息包含 selector
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
### 3. 实现文本内容断言 ✅
|
|
104
|
-
|
|
105
|
-
**工具 3: assertText**
|
|
106
|
-
```typescript
|
|
107
|
-
export async function assertText(session, args) {
|
|
108
|
-
const { refId, expected } = args
|
|
109
|
-
|
|
110
|
-
const result = await elementTools.getText(session, { refId })
|
|
111
|
-
const actual = result.text
|
|
112
|
-
|
|
113
|
-
if (actual !== expected) {
|
|
114
|
-
throw new Error(
|
|
115
|
-
`Assertion failed: Text mismatch. Expected: "${expected}", Actual: "${actual}"`
|
|
116
|
-
)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
success: true,
|
|
121
|
-
message: `Text matches: "${expected}"`,
|
|
122
|
-
actual,
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
**工具 4: assertTextContains**
|
|
128
|
-
```typescript
|
|
129
|
-
export async function assertTextContains(session, args) {
|
|
130
|
-
// 使用 actual.includes(expected)
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**验证**:
|
|
135
|
-
- ✅ 精确匹配成功/失败
|
|
136
|
-
- ✅ 包含匹配成功/失败
|
|
137
|
-
- ✅ 返回 actual 字段
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
### 4. 实现表单值断言 ✅
|
|
142
|
-
|
|
143
|
-
**工具 5: assertValue**
|
|
144
|
-
```typescript
|
|
145
|
-
export async function assertValue(session, args) {
|
|
146
|
-
const { refId, expected } = args
|
|
147
|
-
|
|
148
|
-
const result = await elementTools.getValue(session, { refId })
|
|
149
|
-
const actual = result.value
|
|
150
|
-
|
|
151
|
-
if (actual !== expected) {
|
|
152
|
-
throw new Error(
|
|
153
|
-
`Assertion failed: Value mismatch. Expected: "${expected}", Actual: "${actual}"`
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return { success: true, message: `Value matches: "${expected}"`, actual }
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**验证**:
|
|
162
|
-
- ✅ 正确调用 getValue
|
|
163
|
-
- ✅ 返回期望值和实际值
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
### 5. 实现属性和状态断言 ✅
|
|
168
|
-
|
|
169
|
-
**工具 6: assertAttribute**
|
|
170
|
-
```typescript
|
|
171
|
-
export async function assertAttribute(session, args) {
|
|
172
|
-
const { refId, name, expected } = args
|
|
173
|
-
|
|
174
|
-
const result = await elementTools.getAttribute(session, { refId, name })
|
|
175
|
-
const actual = result.value
|
|
176
|
-
|
|
177
|
-
if (actual !== expected) {
|
|
178
|
-
throw new Error(
|
|
179
|
-
`Assertion failed: Attribute "${name}" mismatch. Expected: "${expected}", Actual: "${actual}"`
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return { success: true, message: `Attribute "${name}" matches: "${expected}"`, actual }
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
**工具 7: assertProperty**
|
|
188
|
-
```typescript
|
|
189
|
-
export async function assertProperty(session, args) {
|
|
190
|
-
// 使用 JSON.stringify 比较复杂对象
|
|
191
|
-
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
192
|
-
throw new Error(...)
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
**工具 8: assertVisible**
|
|
198
|
-
```typescript
|
|
199
|
-
export async function assertVisible(session, args) {
|
|
200
|
-
const result = await elementTools.getSize(session, { refId })
|
|
201
|
-
const size = result.size
|
|
202
|
-
|
|
203
|
-
if (!size || size.width === 0 || size.height === 0) {
|
|
204
|
-
throw new Error(`Assertion failed: Element is not visible. Size: ${JSON.stringify(size)}`)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return { success: true, message: 'Element is visible', size }
|
|
208
|
-
}
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
**验证**:
|
|
212
|
-
- ✅ 属性断言支持任意属性名
|
|
213
|
-
- ✅ 属性断言支持复杂对象(JSON 序列化)
|
|
214
|
-
- ✅ 可见性断言检查 width > 0 && height > 0
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
### 6. 实现页面数据断言 ✅
|
|
219
|
-
|
|
220
|
-
**工具 9: assertData**
|
|
221
|
-
```typescript
|
|
222
|
-
export async function assertData(session, args) {
|
|
223
|
-
const { path, expected, pagePath } = args
|
|
224
|
-
|
|
225
|
-
const result = await pageTools.getData(session, { path, pagePath })
|
|
226
|
-
const actual = result.data
|
|
227
|
-
|
|
228
|
-
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
229
|
-
throw new Error(
|
|
230
|
-
`Assertion failed: Page data${path ? ` at path "${path}"` : ''} mismatch. ` +
|
|
231
|
-
`Expected: ${JSON.stringify(expected)}, Actual: ${JSON.stringify(actual)}`
|
|
232
|
-
)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return {
|
|
236
|
-
success: true,
|
|
237
|
-
message: `Page data${path ? ` at "${path}"` : ''} matches`,
|
|
238
|
-
actual,
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
**验证**:
|
|
244
|
-
- ✅ 支持根路径和嵌套路径
|
|
245
|
-
- ✅ 支持任意数据类型(JSON 序列化比较)
|
|
246
|
-
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
### 7. 编写单元测试 ✅
|
|
250
|
-
|
|
251
|
-
**文件**: `tests/unit/assert.test.ts`
|
|
252
|
-
|
|
253
|
-
**测试用例** (27 个):
|
|
254
|
-
```typescript
|
|
255
|
-
describe('Assert Tools', () => {
|
|
256
|
-
describe('assertExists', () => {
|
|
257
|
-
it('should pass when element exists', async () => {})
|
|
258
|
-
it('should fail when element not found', async () => {})
|
|
259
|
-
it('should support pagePath parameter', async () => {})
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
describe('assertNotExists', () => {
|
|
263
|
-
it('should pass when element does not exist', async () => {})
|
|
264
|
-
it('should fail when element exists', async () => {})
|
|
265
|
-
it('should pass when query throws error', async () => {})
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
describe('assertText', () => {
|
|
269
|
-
it('should pass when text matches', async () => {})
|
|
270
|
-
it('should fail when text does not match', async () => {})
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
describe('assertTextContains', () => {
|
|
274
|
-
it('should pass when text contains substring', async () => {})
|
|
275
|
-
it('should fail when text does not contain substring', async () => {})
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
describe('assertValue', () => {
|
|
279
|
-
it('should pass when value matches', async () => {})
|
|
280
|
-
it('should fail when value does not match', async () => {})
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
describe('assertAttribute', () => {
|
|
284
|
-
it('should pass when attribute matches', async () => {})
|
|
285
|
-
it('should fail when attribute does not match', async () => {})
|
|
286
|
-
})
|
|
287
|
-
|
|
288
|
-
describe('assertProperty', () => {
|
|
289
|
-
it('should pass when property matches', async () => {})
|
|
290
|
-
it('should fail when property does not match', async () => {})
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
describe('assertData', () => {
|
|
294
|
-
it('should pass when page data matches', async () => {})
|
|
295
|
-
it('should pass when nested data matches', async () => {})
|
|
296
|
-
it('should fail when data does not match', async () => {})
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
describe('assertVisible', () => {
|
|
300
|
-
it('should pass when element is visible', async () => {})
|
|
301
|
-
it('should fail when element has zero width', async () => {})
|
|
302
|
-
it('should fail when element has zero height', async () => {})
|
|
303
|
-
it('should fail when size is null', async () => {})
|
|
304
|
-
})
|
|
305
|
-
})
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**验证**:
|
|
309
|
-
- ✅ 27 个测试全部通过
|
|
310
|
-
- ✅ Mock pageTools 和 elementTools
|
|
311
|
-
- ✅ 覆盖成功和失败场景
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## 完成标准 (Definition of Done)
|
|
316
|
-
|
|
317
|
-
### 功能完成 ✅
|
|
318
|
-
|
|
319
|
-
- [x] assertExists 正确验证元素存在
|
|
320
|
-
- [x] assertNotExists 正确验证元素不存在
|
|
321
|
-
- [x] assertText 精确匹配文本
|
|
322
|
-
- [x] assertTextContains 子串匹配
|
|
323
|
-
- [x] assertValue 验证表单值
|
|
324
|
-
- [x] assertAttribute 验证 HTML 属性
|
|
325
|
-
- [x] assertProperty 验证 JS 属性(JSON 比较)
|
|
326
|
-
- [x] assertData 验证页面数据(含嵌套路径)
|
|
327
|
-
- [x] assertVisible 验证元素可见性(非零尺寸)
|
|
328
|
-
|
|
329
|
-
### 代码质量 ✅
|
|
330
|
-
|
|
331
|
-
- [x] TypeScript 编译 0 错误
|
|
332
|
-
- [x] 无 ESLint 错误
|
|
333
|
-
- [x] 代码行数 465 行(合理范围)
|
|
334
|
-
- [x] JSDoc 注释完整
|
|
335
|
-
- [x] 符合 ESM 规范(.js 后缀)
|
|
336
|
-
|
|
337
|
-
### 测试 ✅
|
|
338
|
-
|
|
339
|
-
- [x] 单元测试 394 行
|
|
340
|
-
- [x] 27 个测试用例全部通过
|
|
341
|
-
- [x] 覆盖所有成功/失败场景
|
|
342
|
-
- [x] Mock 外部依赖
|
|
343
|
-
|
|
344
|
-
### 文档 ⏳
|
|
345
|
-
|
|
346
|
-
- [x] 代码注释完整
|
|
347
|
-
- [x] 函数签名清晰
|
|
348
|
-
- ⏳ charter.D1.align.yaml (追溯)
|
|
349
|
-
- ⏳ tasks.D1.atomize.md (本文档)
|
|
350
|
-
|
|
351
|
-
---
|
|
352
|
-
|
|
353
|
-
## 实现结果 (Implementation)
|
|
354
|
-
|
|
355
|
-
### 文件清单
|
|
356
|
-
|
|
357
|
-
| 文件 | 行数 | 说明 |
|
|
358
|
-
|------|------|------|
|
|
359
|
-
| `src/tools/assert.ts` | 465 | 9 个断言工具实现 |
|
|
360
|
-
| `tests/unit/assert.test.ts` | 394 | 27 个单元测试 |
|
|
361
|
-
|
|
362
|
-
### 工具列表
|
|
363
|
-
|
|
364
|
-
| 工具名 | 功能 | 输入 | 输出 |
|
|
365
|
-
|--------|------|------|------|
|
|
366
|
-
| `assertExists` | 断言元素存在 | selector, pagePath? | success, message |
|
|
367
|
-
| `assertNotExists` | 断言元素不存在 | selector, pagePath? | success, message |
|
|
368
|
-
| `assertText` | 断言文本精确匹配 | refId, expected | success, message, actual |
|
|
369
|
-
| `assertTextContains` | 断言文本包含子串 | refId, expected | success, message, actual |
|
|
370
|
-
| `assertValue` | 断言表单值 | refId, expected | success, message, actual |
|
|
371
|
-
| `assertAttribute` | 断言 HTML 属性 | refId, name, expected | success, message, actual |
|
|
372
|
-
| `assertProperty` | 断言 JS 属性 | refId, name, expected | success, message, actual |
|
|
373
|
-
| `assertData` | 断言页面数据 | path?, expected, pagePath? | success, message, actual |
|
|
374
|
-
| `assertVisible` | 断言元素可见 | refId | success, message, size |
|
|
375
|
-
|
|
376
|
-
### 关键代码片段
|
|
377
|
-
|
|
378
|
-
**错误消息格式**:
|
|
379
|
-
```typescript
|
|
380
|
-
// 文本不匹配
|
|
381
|
-
`Assertion failed: Text mismatch. Expected: "${expected}", Actual: "${actual}"`
|
|
382
|
-
|
|
383
|
-
// 属性不匹配
|
|
384
|
-
`Assertion failed: Attribute "${name}" mismatch. Expected: "${expected}", Actual: "${actual}"`
|
|
385
|
-
|
|
386
|
-
// 页面数据不匹配
|
|
387
|
-
`Assertion failed: Page data at path "${path}" mismatch. Expected: ${JSON.stringify(expected)}, Actual: ${JSON.stringify(actual)}`
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**返回值结构**:
|
|
391
|
-
```typescript
|
|
392
|
-
{
|
|
393
|
-
success: true,
|
|
394
|
-
message: 'Element exists: .test-button',
|
|
395
|
-
actual?: '实际值' // 仅部分断言返回
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### 设计决策
|
|
400
|
-
|
|
401
|
-
1. **硬断言模式**
|
|
402
|
-
- 失败立即抛出 Error
|
|
403
|
-
- 理由:简化逻辑,符合测试框架习惯
|
|
404
|
-
|
|
405
|
-
2. **期望值 vs 实际值**
|
|
406
|
-
- 所有错误消息包含 `Expected` 和 `Actual`
|
|
407
|
-
- 理由:便于调试和定位问题
|
|
408
|
-
|
|
409
|
-
3. **JSON 序列化比较**
|
|
410
|
-
- 复杂对象使用 JSON.stringify 比较
|
|
411
|
-
- 理由:简单可靠,覆盖大多数场景
|
|
412
|
-
- 限制:无法处理函数、循环引用
|
|
413
|
-
|
|
414
|
-
4. **可见性定义**
|
|
415
|
-
- width > 0 && height > 0
|
|
416
|
-
- 理由:与 Playwright 保持一致
|
|
417
|
-
- 不考虑:opacity, display, visibility(需额外工具支持)
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
## 测试证据 (Test Evidence)
|
|
422
|
-
|
|
423
|
-
### 单元测试结果
|
|
424
|
-
|
|
425
|
-
```bash
|
|
426
|
-
$ pnpm test assert.test.ts
|
|
427
|
-
|
|
428
|
-
PASS tests/unit/assert.test.ts
|
|
429
|
-
Assert Tools
|
|
430
|
-
assertExists
|
|
431
|
-
✓ should pass when element exists (12ms)
|
|
432
|
-
✓ should fail when element not found (8ms)
|
|
433
|
-
✓ should support pagePath parameter (7ms)
|
|
434
|
-
assertNotExists
|
|
435
|
-
✓ should pass when element does not exist (9ms)
|
|
436
|
-
✓ should fail when element exists (6ms)
|
|
437
|
-
✓ should pass when query throws error (8ms)
|
|
438
|
-
assertText
|
|
439
|
-
✓ should pass when text matches (10ms)
|
|
440
|
-
✓ should fail when text does not match (7ms)
|
|
441
|
-
assertTextContains
|
|
442
|
-
✓ should pass when text contains substring (9ms)
|
|
443
|
-
✓ should fail when text does not contain substring (6ms)
|
|
444
|
-
assertValue
|
|
445
|
-
✓ should pass when value matches (8ms)
|
|
446
|
-
✓ should fail when value does not match (7ms)
|
|
447
|
-
assertAttribute
|
|
448
|
-
✓ should pass when attribute matches (11ms)
|
|
449
|
-
✓ should fail when attribute does not match (8ms)
|
|
450
|
-
assertProperty
|
|
451
|
-
✓ should pass when property matches (9ms)
|
|
452
|
-
✓ should fail when property does not match (7ms)
|
|
453
|
-
assertData
|
|
454
|
-
✓ should pass when page data matches (10ms)
|
|
455
|
-
✓ should pass when nested data matches (8ms)
|
|
456
|
-
✓ should fail when data does not match (6ms)
|
|
457
|
-
assertVisible
|
|
458
|
-
✓ should pass when element is visible (12ms)
|
|
459
|
-
✓ should fail when element has zero width (7ms)
|
|
460
|
-
✓ should fail when element has zero height (8ms)
|
|
461
|
-
✓ should fail when size is null (6ms)
|
|
462
|
-
|
|
463
|
-
Test Suites: 1 passed, 1 total
|
|
464
|
-
Tests: 27 passed, 27 total
|
|
465
|
-
Time: 2.148s
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
### 错误消息示例
|
|
469
|
-
|
|
470
|
-
```
|
|
471
|
-
Error: Assertion failed: Text mismatch. Expected: "Click Me", Actual: "Submit"
|
|
472
|
-
|
|
473
|
-
Error: Assertion failed: Attribute "data-id" mismatch. Expected: "btn-1", Actual: "btn-2"
|
|
474
|
-
|
|
475
|
-
Error: Assertion failed: Page data at path "count" mismatch. Expected: 10, Actual: 5
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
---
|
|
479
|
-
|
|
480
|
-
## 已知问题 (Known Issues)
|
|
481
|
-
|
|
482
|
-
### 技术债务
|
|
483
|
-
|
|
484
|
-
1. **JSON 序列化限制** - 🟡 中优先级
|
|
485
|
-
- 原因:无法比较函数、循环引用、Date 对象
|
|
486
|
-
- 影响:复杂对象比较可能失败
|
|
487
|
-
- 计划:未来引入深度比较库(如 lodash.isEqual)
|
|
488
|
-
|
|
489
|
-
2. **可见性判断不完整** - 🟢 低优先级
|
|
490
|
-
- 原因:仅基于尺寸,未考虑 CSS 属性
|
|
491
|
-
- 影响:display:none 的元素可能误判
|
|
492
|
-
- 计划:未来补充 CSS 属性检查
|
|
493
|
-
|
|
494
|
-
### 风险
|
|
495
|
-
|
|
496
|
-
1. **断言性能** - 🟢 低风险
|
|
497
|
-
- 缓解:每个断言仅一次元素/数据查询
|
|
498
|
-
- 监控:单元测试耗时 <3s
|
|
499
|
-
|
|
500
|
-
---
|
|
501
|
-
|
|
502
|
-
## 参考资料 (References)
|
|
503
|
-
|
|
504
|
-
### 文档
|
|
505
|
-
|
|
506
|
-
- `docs/charter.D1.align.yaml` - 任务对齐文档
|
|
507
|
-
- `docs/完整实现方案.md` - 工具分层设计
|
|
508
|
-
|
|
509
|
-
### 代码
|
|
510
|
-
|
|
511
|
-
- `src/tools/page.ts` - Page 工具依赖
|
|
512
|
-
- `src/tools/element.ts` - Element 工具依赖
|
|
513
|
-
- `src/types.ts` - SessionState 定义
|
|
514
|
-
|
|
515
|
-
### 外部资源
|
|
516
|
-
|
|
517
|
-
- [Playwright Assertions](https://playwright.dev/docs/test-assertions)
|
|
518
|
-
- [Jest Matchers](https://jestjs.io/docs/expect)
|
|
519
|
-
|
|
520
|
-
---
|
|
521
|
-
|
|
522
|
-
## 后续任务 (Next Steps)
|
|
523
|
-
|
|
524
|
-
### 依赖此任务的后续任务
|
|
525
|
-
|
|
526
|
-
- ⏳ E1: 工具注册器集成(添加 assert 工具到 capabilities)
|
|
527
|
-
- ⏳ F1: 端到端测试示例(使用断言工具)
|
|
528
|
-
|
|
529
|
-
### 改进建议
|
|
530
|
-
|
|
531
|
-
1. **深度比较**
|
|
532
|
-
- 引入 lodash.isEqual 或自定义深度比较
|
|
533
|
-
- 支持复杂对象、Date、RegExp 等
|
|
534
|
-
|
|
535
|
-
2. **软断言**
|
|
536
|
-
- 收集所有断言失败,最后统一报告
|
|
537
|
-
- 适合批量验证场景
|
|
538
|
-
|
|
539
|
-
3. **自定义匹配器**
|
|
540
|
-
- 允许用户扩展断言逻辑
|
|
541
|
-
- 例如:assertMatches(refId, /^\d+$/)
|
|
542
|
-
|
|
543
|
-
---
|
|
544
|
-
|
|
545
|
-
**任务状态**: ✅ COMPLETED
|
|
546
|
-
**代码提交**: ✅ 已提交(commit: feat: [D1] 断言工具集实现)
|
|
547
|
-
**文档状态**: ⏳ RETROSPECTIVE (追溯补齐中)
|