speccore 8.3.147 → 8.3.149

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.
Files changed (35) hide show
  1. package/dist/commands/init.d.ts.map +1 -1
  2. package/dist/commands/init.js +9 -1
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/commands/update.d.ts.map +1 -1
  5. package/dist/commands/update.js +4 -1
  6. package/dist/commands/update.js.map +1 -1
  7. package/package.json +3 -2
  8. package/templates/api-design-example.md +338 -0
  9. package/templates/ci/github-actions.yml +44 -0
  10. package/templates/dashboard.html +425 -0
  11. package/templates/database-example.md +223 -0
  12. package/templates/deploy-docker/README.md +284 -0
  13. package/templates/deploy-docker/deploy-remote.sh +79 -0
  14. package/templates/deploy-docker/docker-compose.yml +113 -0
  15. package/templates/deploy-docker/frontend.Dockerfile +43 -0
  16. package/templates/deploy-docker/nginx.conf +30 -0
  17. package/templates/deploy-examples.yaml +436 -0
  18. package/templates/deploy-java/Dockerfile +50 -0
  19. package/templates/deploy-java/README.md +212 -0
  20. package/templates/deploy-java/deploy.sh +120 -0
  21. package/templates/deploy-java/spring-boot.service +35 -0
  22. package/templates/html/speccore-ask-explain.html +10 -0
  23. package/templates/html/speccore-ask-guide.html +10 -0
  24. package/templates/html/speccore-ask-match.html +10 -0
  25. package/templates/html/speccore-ask-pipeline.html +1 -0
  26. package/templates/html/speccore-ask-result.html +10 -0
  27. package/templates/html/speccore-demo.html +449 -0
  28. package/templates/html/speccore-dev.html +202 -0
  29. package/templates/html/speccore-help.html +1 -0
  30. package/templates/html/speccore-knowledge-graph.html +656 -0
  31. package/templates/html/speccore-retro-T-001.html +1 -0
  32. package/templates/html/speccore-setup-guide.html +289 -0
  33. package/templates/html/speccore-welcome.html +1 -0
  34. package/templates/security-example.md +226 -0
  35. package/templates/verify-spec-example.yaml +852 -0
@@ -0,0 +1,852 @@
1
+ # VERIFY_SPEC.yaml — 企业级 UI 冒烟测试规格(完整示例)
2
+ # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3
+ # 格式类型: VERIFY_SPEC 格式(scenarios + actions + assertions 结构)
4
+ # 适用场景: 精细 UI 交互测试(填写表单、点击按钮、断言元素状态)
5
+ # 对应命令:
6
+ # • speccore verify --ui --spec ./tests/smoke.yaml ← 推荐,原生支持完整交互逻辑
7
+ # • speccore verify --ui --config ./tests/smoke.yaml ← 兼容,自动转换为批量页面测试
8
+ # 按模块过滤: speccore verify --ui --spec ./tests/smoke.yaml --module=auth
9
+ #
10
+ # ⚠️ 格式说明:
11
+ # VERIFY_SPEC 格式 = scenarios + actions + assertions(本文件,支持完整交互)
12
+ # TestConfig 格式 = tests + routes + type(用于批量页面/API测试,见 pr.yaml/release.yaml)
13
+ # 两种格式 speccore verify --config 均可自动识别。
14
+ #
15
+ # 本示例覆盖:
16
+ # • 全部 ActionType: fill, click, select, check, uncheck, hover, focus, blur, press,
17
+ # wait, navigate, screenshot, cookie, localStorage, script, scroll, upload, iframe,
18
+ # waitForRequest, waitForResponse, drag
19
+ # • 全部 AssertionType: visible, hidden, text, value, url, count, attribute, style, visual
20
+ # • 业务模块: 登录认证 / 用户中心 / 商品 / 购物车 / 订单 / 消息通知 / 后台管理
21
+ #
22
+ # v8.3.95+ 支持: cookie / localStorage / script / scroll / upload / iframe / waitForRequest / waitForResponse / drag
23
+
24
+ name: 示例项目冒烟测试(完整版)
25
+ platform: h5-mobile
26
+ url: /
27
+
28
+ # ─────────────────────────────────────────────────────────────────────────────
29
+ # 一、登录认证模块 (auth)
30
+ # ─────────────────────────────────────────────────────────────────────────────
31
+ scenarios:
32
+ # ── 场景1: 账号密码登录 ──
33
+ - name: 登录-账号密码登录
34
+ description: 模块:auth 页面:/login
35
+ actions:
36
+ - type: navigate
37
+ value: /login
38
+ - type: fill
39
+ selector: 'input[name="username"]'
40
+ value: test_user
41
+ - type: fill
42
+ selector: 'input[name="password"]'
43
+ value: test_password
44
+ - type: click
45
+ selector: 'button[type="submit"]'
46
+ waitFor: '.dashboard-container'
47
+ assertions:
48
+ - type: url
49
+ contains: /dashboard
50
+ - type: visible
51
+ selector: '.dashboard-container'
52
+ - type: text
53
+ selector: '.user-name'
54
+ contains: test_user
55
+
56
+ # ── 场景2: 手机号+验证码登录 ──
57
+ - name: 登录-手机号验证码
58
+ description: 模块:auth 页面:/login/phone
59
+ actions:
60
+ - type: navigate
61
+ value: /login/phone
62
+ - type: fill
63
+ selector: 'input[name="phone"]'
64
+ value: '13800138000'
65
+ - type: click
66
+ selector: '.send-code-btn'
67
+ - type: wait
68
+ delay: 2000
69
+ - type: fill
70
+ selector: 'input[name="verifyCode"]'
71
+ value: '123456'
72
+ - type: click
73
+ selector: 'button[type="submit"]'
74
+ waitFor: '.dashboard-container'
75
+ assertions:
76
+ - type: url
77
+ contains: /dashboard
78
+ - type: visible
79
+ selector: '.dashboard-container'
80
+
81
+ # ── 场景3: 微信 OAuth 登录 ──
82
+ - name: 登录-微信OAuth
83
+ description: 模块:auth 页面:/login 第三方登录
84
+ actions:
85
+ - type: navigate
86
+ value: /login
87
+ - type: click
88
+ selector: '.wechat-login-btn'
89
+ - type: waitForRequest
90
+ selector: 'https://open.weixin.qq.com/connect/oauth2/authorize'
91
+ timeout: 5000
92
+ - type: wait
93
+ delay: 3000
94
+ assertions:
95
+ - type: url
96
+ contains: wechat
97
+
98
+ # ── 场景4: 企业微信 SSO 登录 ──
99
+ - name: 登录-企业微信SSO
100
+ description: 模块:auth 页面:/login/sso
101
+ actions:
102
+ - type: navigate
103
+ value: /login/sso
104
+ - type: iframe
105
+ selector: '#sso-frame'
106
+ - type: fill
107
+ selector: 'input[name="corpId"]'
108
+ value: 'ww1234567890abcdef'
109
+ - type: click
110
+ selector: '.sso-submit-btn'
111
+ waitFor: '.dashboard-container'
112
+ assertions:
113
+ - type: url
114
+ contains: /dashboard
115
+ - type: visible
116
+ selector: '.dashboard-container'
117
+
118
+ # ── 场景5: 扫码登录 ──
119
+ - name: 登录-扫码登录
120
+ description: 模块:auth 页面:/login/qrcode
121
+ actions:
122
+ - type: navigate
123
+ value: /login/qrcode
124
+ - type: visible
125
+ selector: '.qrcode-img'
126
+ - type: wait
127
+ delay: 5000
128
+ assertions:
129
+ - type: visible
130
+ selector: '.qrcode-img'
131
+ - type: attribute
132
+ selector: '.qrcode-img'
133
+ attribute: src
134
+ contains: data:image
135
+
136
+ # ── 场景6: 登录失败-密码错误 ──
137
+ - name: 登录-密码错误提示
138
+ description: 模块:auth 页面:/login 异常场景
139
+ actions:
140
+ - type: navigate
141
+ value: /login
142
+ - type: fill
143
+ selector: 'input[name="username"]'
144
+ value: test_user
145
+ - type: fill
146
+ selector: 'input[name="password"]'
147
+ value: wrong_password
148
+ - type: click
149
+ selector: 'button[type="submit"]'
150
+ - type: wait
151
+ delay: 1000
152
+ assertions:
153
+ - type: visible
154
+ selector: '.error-message'
155
+ - type: text
156
+ selector: '.error-message'
157
+ contains: 密码错误
158
+
159
+ # ── 场景7: 登录失败-账号锁定 ──
160
+ - name: 登录-账号锁定提示
161
+ description: 模块:auth 页面:/login 异常场景
162
+ actions:
163
+ - type: navigate
164
+ value: /login
165
+ - type: fill
166
+ selector: 'input[name="username"]'
167
+ value: locked_user
168
+ - type: fill
169
+ selector: 'input[name="password"]'
170
+ value: any_password
171
+ - type: click
172
+ selector: 'button[type="submit"]'
173
+ - type: wait
174
+ delay: 1000
175
+ assertions:
176
+ - type: visible
177
+ selector: '.error-message'
178
+ - type: text
179
+ selector: '.error-message'
180
+ contains: 账号已被锁定
181
+
182
+ # ── 场景8: 记住密码功能 ──
183
+ - name: 登录-记住密码
184
+ description: 模块:auth 页面:/login 记住密码勾选
185
+ actions:
186
+ - type: navigate
187
+ value: /login
188
+ - type: check
189
+ selector: 'input[name="rememberMe"]'
190
+ - type: fill
191
+ selector: 'input[name="username"]'
192
+ value: test_user
193
+ - type: fill
194
+ selector: 'input[name="password"]'
195
+ value: test_password
196
+ - type: click
197
+ selector: 'button[type="submit"]'
198
+ waitFor: '.dashboard-container'
199
+ assertions:
200
+ - type: cookie
201
+ selector: remember_me
202
+ contains: 'true'
203
+
204
+ # ── 场景9: 退出登录 ──
205
+ - name: 登录-退出登录
206
+ description: 模块:auth 页面:/dashboard
207
+ actions:
208
+ - type: navigate
209
+ value: /dashboard
210
+ - type: click
211
+ selector: '.user-avatar'
212
+ - type: click
213
+ selector: '.logout-btn'
214
+ - type: wait
215
+ delay: 1000
216
+ assertions:
217
+ - type: url
218
+ contains: /login
219
+ - type: visible
220
+ selector: '.login-form'
221
+
222
+ # ─────────────────────────────────────────────────────────────────────────────
223
+ # 二、用户中心模块 (user)
224
+ # ─────────────────────────────────────────────────────────────────────────────
225
+
226
+ # ── 场景10: 个人资料修改 ──
227
+ - name: 用户-修改个人资料
228
+ description: 模块:user 页面:/profile/edit
229
+ actions:
230
+ - type: navigate
231
+ value: /profile/edit
232
+ - type: fill
233
+ selector: 'input[name="nickname"]'
234
+ value: 新昵称测试
235
+ - type: select
236
+ selector: 'select[name="gender"]'
237
+ value: female
238
+ - type: fill
239
+ selector: 'input[name="email"]'
240
+ value: 'newemail@example.com'
241
+ - type: click
242
+ selector: '.save-profile-btn'
243
+ - type: wait
244
+ delay: 1500
245
+ assertions:
246
+ - type: visible
247
+ selector: '.toast-success'
248
+ - type: text
249
+ selector: '.toast-success'
250
+ contains: 保存成功
251
+
252
+ # ── 场景11: 头像上传 ──
253
+ - name: 用户-上传头像
254
+ description: 模块:user 页面:/profile/edit 头像上传
255
+ actions:
256
+ - type: navigate
257
+ value: /profile/edit
258
+ - type: upload
259
+ selector: 'input[type="file"].avatar-upload'
260
+ value: ./fixtures/test-avatar.png
261
+ - type: wait
262
+ delay: 2000
263
+ assertions:
264
+ - type: visible
265
+ selector: '.avatar-preview img'
266
+ - type: attribute
267
+ selector: '.avatar-preview img'
268
+ attribute: src
269
+ contains: avatar
270
+
271
+ # ── 场景12: 修改密码 ──
272
+ - name: 用户-修改密码
273
+ description: 模块:user 页面:/profile/security
274
+ actions:
275
+ - type: navigate
276
+ value: /profile/security
277
+ - type: fill
278
+ selector: 'input[name="oldPassword"]'
279
+ value: old_pass_123
280
+ - type: fill
281
+ selector: 'input[name="newPassword"]'
282
+ value: new_pass_456
283
+ - type: fill
284
+ selector: 'input[name="confirmPassword"]'
285
+ value: new_pass_456
286
+ - type: click
287
+ selector: '.change-password-btn'
288
+ - type: wait
289
+ delay: 1500
290
+ assertions:
291
+ - type: visible
292
+ selector: '.toast-success'
293
+ - type: text
294
+ selector: '.toast-success'
295
+ contains: 密码修改成功
296
+
297
+ # ── 场景13: Token 注入免登录(localStorage) ──
298
+ - name: 用户-Token注入免登录
299
+ description: 模块:user 页面:/profile Token注入方式
300
+ actions:
301
+ - type: localStorage
302
+ selector: accessToken
303
+ value: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
304
+ - type: localStorage
305
+ selector: refreshToken
306
+ value: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
307
+ - type: navigate
308
+ value: /profile
309
+ - type: wait
310
+ delay: 800
311
+ assertions:
312
+ - type: visible
313
+ selector: '.profile-header'
314
+ - type: text
315
+ selector: '.username'
316
+ contains: test_user
317
+
318
+ # ─────────────────────────────────────────────────────────────────────────────
319
+ # 三、商品模块 (product)
320
+ # ─────────────────────────────────────────────────────────────────────────────
321
+
322
+ # ── 场景14: 商品列表浏览 ──
323
+ - name: 商品-列表浏览
324
+ description: 模块:product 页面:/products
325
+ actions:
326
+ - type: navigate
327
+ value: /products
328
+ - type: scroll
329
+ selector: bottom
330
+ - type: wait
331
+ delay: 1000
332
+ assertions:
333
+ - type: visible
334
+ selector: '.product-list'
335
+ - type: count
336
+ selector: '.product-item'
337
+ count: 10
338
+
339
+ # ── 场景15: 商品搜索 ──
340
+ - name: 商品-搜索
341
+ description: 模块:product 页面:/products 搜索功能
342
+ actions:
343
+ - type: navigate
344
+ value: /products
345
+ - type: fill
346
+ selector: 'input[name="keyword"]'
347
+ value: iPhone
348
+ - type: press
349
+ key: Enter
350
+ - type: wait
351
+ delay: 1500
352
+ assertions:
353
+ - type: visible
354
+ selector: '.search-result-list'
355
+ - type: count
356
+ selector: '.product-item'
357
+ count: 3
358
+
359
+ # ── 场景16: 商品详情 ──
360
+ - name: 商品-详情页
361
+ description: 模块:product 页面:/products/:id
362
+ actions:
363
+ - type: navigate
364
+ value: /products
365
+ - type: click
366
+ selector: '.product-item:first-child .product-title'
367
+ - type: wait
368
+ delay: 1000
369
+ assertions:
370
+ - type: visible
371
+ selector: '.product-detail'
372
+ - type: text
373
+ selector: '.product-name'
374
+ contains: iPhone
375
+ - type: visible
376
+ selector: '.product-price'
377
+
378
+ # ── 场景17: 商品筛选 ──
379
+ - name: 商品-多条件筛选
380
+ description: 模块:product 页面:/products 筛选功能
381
+ actions:
382
+ - type: navigate
383
+ value: /products
384
+ - type: select
385
+ selector: 'select[name="category"]'
386
+ value: electronics
387
+ - type: check
388
+ selector: 'input[value="inStock"]'
389
+ - type: click
390
+ selector: '.filter-submit-btn'
391
+ - type: wait
392
+ delay: 1200
393
+ assertions:
394
+ - type: visible
395
+ selector: '.product-list'
396
+ - type: count
397
+ selector: '.product-item'
398
+ count: 5
399
+
400
+ # ── 场景18: 商品收藏 ──
401
+ - name: 商品-收藏/取消收藏
402
+ description: 模块:product 页面:/products/:id 收藏功能
403
+ actions:
404
+ - type: navigate
405
+ value: /products/123
406
+ - type: click
407
+ selector: '.favorite-btn'
408
+ - type: wait
409
+ delay: 500
410
+ assertions:
411
+ - type: style
412
+ selector: '.favorite-btn'
413
+ style: color
414
+ value: rgb(255, 77, 79)
415
+
416
+ # ─────────────────────────────────────────────────────────────────────────────
417
+ # 四、购物车模块 (cart)
418
+ # ─────────────────────────────────────────────────────────────────────────────
419
+
420
+ # ── 场景19: 添加商品到购物车 ──
421
+ - name: 购物车-添加商品
422
+ description: 模块:cart 页面:/products/:id
423
+ actions:
424
+ - type: navigate
425
+ value: /products/123
426
+ - type: click
427
+ selector: '.add-to-cart-btn'
428
+ - type: wait
429
+ delay: 800
430
+ assertions:
431
+ - type: visible
432
+ selector: '.cart-badge'
433
+ - type: text
434
+ selector: '.cart-badge'
435
+ contains: '1'
436
+
437
+ # ── 场景20: 购物车数量修改 ──
438
+ - name: 购物车-修改数量
439
+ description: 模块:cart 页面:/cart
440
+ actions:
441
+ - type: navigate
442
+ value: /cart
443
+ - type: fill
444
+ selector: '.cart-item:first-child .quantity-input'
445
+ value: '3'
446
+ - type: blur
447
+ selector: '.cart-item:first-child .quantity-input'
448
+ - type: wait
449
+ delay: 800
450
+ assertions:
451
+ - type: text
452
+ selector: '.cart-item:first-child .subtotal'
453
+ contains: '¥'
454
+
455
+ # ── 场景21: 购物车结算 ──
456
+ - name: 购物车-去结算
457
+ description: 模块:cart 页面:/cart
458
+ actions:
459
+ - type: navigate
460
+ value: /cart
461
+ - type: check
462
+ selector: '.cart-item:first-child .item-checkbox'
463
+ - type: click
464
+ selector: '.checkout-btn'
465
+ - type: wait
466
+ delay: 1500
467
+ assertions:
468
+ - type: url
469
+ contains: /checkout
470
+ - type: visible
471
+ selector: '.checkout-form'
472
+
473
+ # ── 场景22: 购物车删除商品 ──
474
+ - name: 购物车-删除商品
475
+ description: 模块:cart 页面:/cart
476
+ actions:
477
+ - type: navigate
478
+ value: /cart
479
+ - type: click
480
+ selector: '.cart-item:first-child .delete-btn'
481
+ - type: wait
482
+ delay: 800
483
+ assertions:
484
+ - type: count
485
+ selector: '.cart-item'
486
+ count: 0
487
+
488
+ # ─────────────────────────────────────────────────────────────────────────────
489
+ # 五、订单模块 (order)
490
+ # ─────────────────────────────────────────────────────────────────────────────
491
+
492
+ # ── 场景23: 订单创建 ──
493
+ - name: 订单-创建订单
494
+ description: 模块:order 页面:/checkout
495
+ actions:
496
+ - type: navigate
497
+ value: /checkout
498
+ - type: fill
499
+ selector: 'input[name="receiverName"]'
500
+ value: 张三
501
+ - type: fill
502
+ selector: 'input[name="phone"]'
503
+ value: '13800138000'
504
+ - type: fill
505
+ selector: 'input[name="address"]'
506
+ value: 北京市朝阳区测试街道123号
507
+ - type: click
508
+ selector: '.submit-order-btn'
509
+ - type: wait
510
+ delay: 2000
511
+ assertions:
512
+ - type: url
513
+ contains: /order/success
514
+ - type: visible
515
+ selector: '.order-success'
516
+ - type: text
517
+ selector: '.order-success'
518
+ contains: 订单提交成功
519
+
520
+ # ── 场景24: 订单支付 ──
521
+ - name: 订单-支付订单
522
+ description: 模块:order 页面:/pay/:orderId
523
+ actions:
524
+ - type: navigate
525
+ value: /pay/ORD202409110001
526
+ - type: click
527
+ selector: '.pay-method-wechat'
528
+ - type: click
529
+ selector: '.confirm-pay-btn'
530
+ - type: waitForResponse
531
+ selector: '/api/pay/create'
532
+ timeout: 10000
533
+ - type: wait
534
+ delay: 2000
535
+ assertions:
536
+ - type: url
537
+ contains: /pay/success
538
+ - type: visible
539
+ selector: '.pay-success'
540
+
541
+ # ── 场景25: 订单列表 ──
542
+ - name: 订单-列表查询
543
+ description: 模块:order 页面:/orders
544
+ actions:
545
+ - type: navigate
546
+ value: /orders
547
+ - type: wait
548
+ delay: 1000
549
+ assertions:
550
+ - type: visible
551
+ selector: '.order-list'
552
+ - type: count
553
+ selector: '.order-item'
554
+ count: 5
555
+
556
+ # ── 场景26: 订单详情 ──
557
+ - name: 订单-详情查看
558
+ description: 模块:order 页面:/orders/:id
559
+ actions:
560
+ - type: navigate
561
+ value: /orders
562
+ - type: click
563
+ selector: '.order-item:first-child .view-detail-btn'
564
+ - type: wait
565
+ delay: 800
566
+ assertions:
567
+ - type: visible
568
+ selector: '.order-detail'
569
+ - type: text
570
+ selector: '.order-status'
571
+ contains: 待付款
572
+
573
+ # ── 场景27: 订单取消 ──
574
+ - name: 订单-取消订单
575
+ description: 模块:order 页面:/orders/:id
576
+ actions:
577
+ - type: navigate
578
+ value: /orders/ORD202409110001
579
+ - type: click
580
+ selector: '.cancel-order-btn'
581
+ - type: wait
582
+ delay: 500
583
+ - type: click
584
+ selector: '.confirm-cancel-btn'
585
+ - type: wait
586
+ delay: 1500
587
+ assertions:
588
+ - type: text
589
+ selector: '.order-status'
590
+ contains: 已取消
591
+
592
+ # ─────────────────────────────────────────────────────────────────────────────
593
+ # 六、消息通知模块 (notification)
594
+ # ─────────────────────────────────────────────────────────────────────────────
595
+
596
+ # ── 场景28: 消息列表 ──
597
+ - name: 消息-列表查看
598
+ description: 模块:notification 页面:/notifications
599
+ actions:
600
+ - type: navigate
601
+ value: /notifications
602
+ - type: wait
603
+ delay: 1000
604
+ assertions:
605
+ - type: visible
606
+ selector: '.notification-list'
607
+ - type: count
608
+ selector: '.notification-item'
609
+ count: 3
610
+
611
+ # ── 场景29: 消息标记已读 ──
612
+ - name: 消息-标记已读
613
+ description: 模块:notification 页面:/notifications
614
+ actions:
615
+ - type: navigate
616
+ value: /notifications
617
+ - type: click
618
+ selector: '.notification-item:first-child'
619
+ - type: wait
620
+ delay: 500
621
+ assertions:
622
+ - type: style
623
+ selector: '.notification-item:first-child'
624
+ style: font-weight
625
+ value: '400'
626
+
627
+ # ─────────────────────────────────────────────────────────────────────────────
628
+ # 七、后台管理模块 (admin)
629
+ # ─────────────────────────────────────────────────────────────────────────────
630
+
631
+ # ── 场景30: 用户管理列表 ──
632
+ - name: 后台-用户管理
633
+ description: 模块:admin 页面:/admin/users
634
+ actions:
635
+ - type: navigate
636
+ value: /admin/users
637
+ - type: wait
638
+ delay: 1500
639
+ assertions:
640
+ - type: visible
641
+ selector: '.user-table'
642
+ - type: count
643
+ selector: '.user-table tbody tr'
644
+ count: 10
645
+
646
+ # ── 场景31: 数据报表(iframe 嵌入) ──
647
+ - name: 后台-数据报表iframe
648
+ description: 模块:admin 页面:/admin/reports iframe嵌入
649
+ actions:
650
+ - type: navigate
651
+ value: /admin/reports
652
+ - type: iframe
653
+ selector: '#report-frame'
654
+ - type: wait
655
+ delay: 2000
656
+ assertions:
657
+ - type: visible
658
+ selector: '.chart-container'
659
+ - type: count
660
+ selector: '.chart-item'
661
+ count: 4
662
+
663
+ # ── 场景32: 拖拽排序 ──
664
+ - name: 后台-拖拽排序
665
+ description: 模块:admin 页面:/admin/categories 拖拽排序
666
+ actions:
667
+ - type: navigate
668
+ value: /admin/categories
669
+ - type: drag
670
+ selector: '.category-item:first-child'
671
+ toSelector: '.category-item:last-child'
672
+ - type: wait
673
+ delay: 1000
674
+ assertions:
675
+ - type: text
676
+ selector: '.category-item:last-child .category-name'
677
+ contains: 原第一个分类
678
+
679
+ # ─────────────────────────────────────────────────────────────────────────────
680
+ # 八、通用能力与高级特性
681
+ # ─────────────────────────────────────────────────────────────────────────────
682
+
683
+ # ── 场景33: Cookie 注入免登录 ──
684
+ - name: 通用-Cookie注入免登录
685
+ description: 模块:common Cookie注入跳过登录
686
+ actions:
687
+ - type: cookie
688
+ selector: session_token
689
+ value: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
690
+ domain: example.com
691
+ path: /
692
+ secure: true
693
+ httpOnly: true
694
+ - type: cookie
695
+ selector: user_id
696
+ value: '10086'
697
+ domain: example.com
698
+ path: /
699
+ - type: navigate
700
+ value: /dashboard
701
+ - type: wait
702
+ delay: 1000
703
+ assertions:
704
+ - type: visible
705
+ selector: '.dashboard-container'
706
+ - type: text
707
+ selector: '.user-name'
708
+ contains: test_user
709
+
710
+ # ── 场景34: 首页滚动加载 ──
711
+ - name: 通用-首页滚动加载
712
+ description: 模块:home 页面:/
713
+ actions:
714
+ - type: navigate
715
+ value: /
716
+ - type: scroll
717
+ selector: bottom
718
+ - type: wait
719
+ delay: 1500
720
+ - type: scroll
721
+ selector: bottom
722
+ - type: wait
723
+ delay: 1500
724
+ assertions:
725
+ - type: visible
726
+ selector: '.load-more-btn'
727
+ - type: count
728
+ selector: '.product-card'
729
+ count: 20
730
+
731
+ # ── 场景35: 样式断言 ──
732
+ - name: 通用-按钮样式检查
733
+ description: 模块:ui 页面:/
734
+ actions:
735
+ - type: navigate
736
+ value: /
737
+ assertions:
738
+ - type: style
739
+ selector: '.primary-btn'
740
+ style: background-color
741
+ value: rgb(24, 144, 255)
742
+ - type: style
743
+ selector: '.primary-btn'
744
+ style: border-radius
745
+ value: 4px
746
+
747
+ # ── 场景36: 视觉对比测试 ──
748
+ - name: 通用-视觉对比测试
749
+ description: 模块:ui 页面:/ 视觉回归
750
+ actions:
751
+ - type: navigate
752
+ value: /
753
+ - type: screenshot
754
+ assertions:
755
+ - type: visual
756
+ selector: 'body'
757
+ threshold: normal
758
+
759
+ # ── 场景37: 键盘操作 ──
760
+ - name: 通用-键盘操作
761
+ description: 模块:common 页面:/products 键盘导航
762
+ actions:
763
+ - type: navigate
764
+ value: /products
765
+ - type: focus
766
+ selector: 'input[name="keyword"]'
767
+ - type: fill
768
+ selector: 'input[name="keyword"]'
769
+ value: MacBook
770
+ - type: press
771
+ key: Enter
772
+ - type: wait
773
+ delay: 1500
774
+ assertions:
775
+ - type: visible
776
+ selector: '.search-result-list'
777
+ - type: count
778
+ selector: '.product-item'
779
+ count: 2
780
+
781
+ # ── 场景38: hover 效果 ──
782
+ - name: 通用-hover效果
783
+ description: 模块:ui 页面:/products hover交互
784
+ actions:
785
+ - type: navigate
786
+ value: /products
787
+ - type: hover
788
+ selector: '.product-item:first-child'
789
+ - type: wait
790
+ delay: 500
791
+ assertions:
792
+ - type: style
793
+ selector: '.product-item:first-child'
794
+ style: box-shadow
795
+ contains: rgba
796
+
797
+ # ── 场景39: 元素隐藏检查 ──
798
+ - name: 通用-元素隐藏
799
+ description: 模块:ui 页面:/login 未登录状态
800
+ actions:
801
+ - type: navigate
802
+ value: /login
803
+ assertions:
804
+ - type: hidden
805
+ selector: '.user-menu'
806
+ - type: hidden
807
+ selector: '.logout-btn'
808
+
809
+ # ── 场景40: 表单值断言 ──
810
+ - name: 通用-表单值检查
811
+ description: 模块:user 页面:/profile/edit 表单默认值
812
+ actions:
813
+ - type: navigate
814
+ value: /profile/edit
815
+ assertions:
816
+ - type: value
817
+ selector: 'input[name="username"]'
818
+ equals: test_user
819
+ - type: value
820
+ selector: 'input[name="email"]'
821
+ contains: '@'
822
+
823
+ # ── 场景41: JavaScript 注入执行 ──
824
+ - name: 通用-JS脚本注入
825
+ description: 模块:common 页面:/ JS注入测试
826
+ actions:
827
+ - type: navigate
828
+ value: /
829
+ - type: script
830
+ value: 'window.testFlag = "injected";'
831
+ - type: wait
832
+ delay: 500
833
+ - type: script
834
+ value: 'return window.testFlag;'
835
+ assertions:
836
+ - type: text
837
+ selector: 'body'
838
+ contains: injected
839
+
840
+ # ── 场景42: 响应式断点测试 ──
841
+ - name: 通用-响应式布局
842
+ description: 模块:ui 页面:/ 移动端适配
843
+ actions:
844
+ - type: navigate
845
+ value: /
846
+ - type: wait
847
+ delay: 800
848
+ assertions:
849
+ - type: visible
850
+ selector: '.mobile-nav'
851
+ - type: hidden
852
+ selector: '.desktop-sidebar'