dsh-wisp 1.33.0 → 1.33.1
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 +33 -0
- package/lib/client.js +32 -13
- package/lib/client.template.js +32 -13
- package/package.json +1 -1
- package/tools/smoke.mjs +58 -0
package/README.md
CHANGED
|
@@ -448,6 +448,39 @@ node tools/audit-log.mjs --confirm <manifest> # 生成后:并入代理登
|
|
|
448
448
|
|
|
449
449
|
## 变更
|
|
450
450
|
|
|
451
|
+
### 1.33.1
|
|
452
|
+
|
|
453
|
+
**修「子菜单遮住主菜单」。** 上一版的定位是错的,而且错得不显眼 —— 面板确实"在旁边",
|
|
454
|
+
只是**压进菜单十几个像素**。现在实测两矩形完全不重叠(右缘 1123 / 菜单左缘 1125)。
|
|
455
|
+
|
|
456
|
+
根因有三层,都是"拿了不该拿的数字":
|
|
457
|
+
|
|
458
|
+
1. **混用了两套坐标系**:菜单的 `left/top` 是**图层坐标**,而 `getBoundingClientRect()`
|
|
459
|
+
给的是**视口坐标**。二者只在图层恰好从 (0,0) 开始时相等。
|
|
460
|
+
2. **量了刚 append、还没布局的面板** ✗:那一刻它的宽度是 **0**,
|
|
461
|
+
于是所有基于它的校正被守卫挡掉,位置就停在估算值上(实测就是这样一直没生效)。
|
|
462
|
+
3. **宽度算错**:CSS 写 `width:184px` 但没写 `box-sizing` ✗ →
|
|
463
|
+
默认 content-box 再加 `padding:6px` + `border:1px` → 实际 **198**,
|
|
464
|
+
而翻转算式里用的常量是 178 —— 差了 20 像素,正好压住菜单。
|
|
465
|
+
|
|
466
|
+
**现在的做法**(不可能算错的那种):**只用量层坐标 + 宽度**。
|
|
467
|
+
|
|
468
|
+
- 面板宽度**固定**(`box-sizing:border-box; width:184px`)→ 常量就是真宽度,不用量;
|
|
469
|
+
- 横向:`x = 菜单left + 菜单宽度 + 2`,越界则 `x = 菜单left − 面板宽度 − 2`;
|
|
470
|
+
- 纵向:用"行矩形相对菜单矩形的**偏移**"→ `rr.top - mr.top` ——
|
|
471
|
+
相对量与坐标系无关,而且自动带上头部/分隔线的高度(估算少了它,差了 28px);
|
|
472
|
+
- 入场动画从 `scale` 改成**纯淡入**:带 scale 的动画会让 `getBoundingClientRect()`
|
|
473
|
+
量到缩放后的矩形,这是第 2 条坑的一部分。
|
|
474
|
+
|
|
475
|
+
**另外补了一道之前缺的防线**:冒烟里加了**真浏览器**的几何检查 ——
|
|
476
|
+
「面板在菜单**旁边**(不是上面)」「在视口内」「与它所属那一行对齐」。
|
|
477
|
+
假 DOM 没有布局,这三条**测不到**,而这个 bug 恰好只存在于布局里 ——
|
|
478
|
+
所以它才会一路发布出去。
|
|
479
|
+
|
|
480
|
+
预检 529 项沿用;冒烟 53 → **57 项**。
|
|
481
|
+
|
|
482
|
+
### 1.33.0
|
|
483
|
+
|
|
451
484
|
### 1.33.0
|
|
452
485
|
|
|
453
486
|
**子菜单改成在**旁边**弹出。** 上一版做成了"在行下面内联展开" —— 那是网页的手风琴,
|
package/lib/client.js
CHANGED
|
@@ -51,7 +51,7 @@ window.__ModuleLoader__.load({
|
|
|
51
51
|
var exports = module.exports
|
|
52
52
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
|
|
53
53
|
|
|
54
|
-
const VERSION = '1.33.
|
|
54
|
+
const VERSION = '1.33.1'
|
|
55
55
|
|
|
56
56
|
/* 每一版一句话。**必须写当前版本** —— 预检里有一条断言盯着它,
|
|
57
57
|
忘了更新就会红,不会静默过期。 */
|
|
@@ -74,6 +74,7 @@ const WHATS_NEW = {
|
|
|
74
74
|
'1.31.0': '菜单重做:状态一目了然,开关是开关,大小能直接拖。',
|
|
75
75
|
'1.32.0': '分组改成鼠标悬停就展开、移开就收起(点一下则是钉住)。',
|
|
76
76
|
'1.33.0': '子菜单改成在旁边弹出(真正的菜单栏形状),→/← 进出自如。',
|
|
77
|
+
'1.33.1': '修子菜单位置算错、会压住主菜单的问题。',
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
/* 更新这件事**这个插件自己做不到**,如实写在代码里,免得以后有人以为能:
|
|
@@ -729,7 +730,8 @@ body[data-ds-dark-theme] .wisp-layer{--wisp-say-fg:#eaf2f8;--wisp-say-bg:rgba(20
|
|
|
729
730
|
.wisp-menu-caret{opacity:.55;font-size:10px;flex:0 0 auto}
|
|
730
731
|
/* 级联子菜单:浮在行的**右侧**(放不下时翻到左侧),不把下面的内容推下去。
|
|
731
732
|
与父行顶部对齐、允许轻微重叠 —— 指针从行斜着移到面板上时不会穿出"同一区域"。 */
|
|
732
|
-
.wisp-submenu{position:absolute;
|
|
733
|
+
.wisp-submenu{position:absolute;box-sizing:border-box;width:184px;padding:6px;border-radius:12px;font-size:12px;line-height:1.25;color:var(--dsw-alias-label-primary,var(--wisp-say-fg));background:var(--dsw-alias-bg-overlay,var(--wisp-say-bg));border:1px solid var(--dsw-alias-border-l1,var(--wisp-say-line));box-shadow:0 12px 34px rgba(0,0,0,.3);-webkit-backdrop-filter:blur(14px) saturate(160%);backdrop-filter:blur(14px) saturate(160%);pointer-events:auto;animation:wisp-fade .12s ease}
|
|
734
|
+
@keyframes wisp-fade{0%{opacity:0}100%{opacity:1}}
|
|
733
735
|
.wisp-menu-sub{padding-left:10px}
|
|
734
736
|
.wisp-menu-sub .wisp-menu-item{padding-left:12px;opacity:.94}
|
|
735
737
|
.wisp-dialog-backdrop{position:absolute;inset:0;background:rgba(6,12,26,.34);pointer-events:auto;animation:wisp-menu .16s ease}
|
|
@@ -2187,7 +2189,7 @@ body[data-ds-dark-theme] .wisp-layer{--wisp-say-fg:#eaf2f8;--wisp-say-bg:rgba(20
|
|
|
2187
2189
|
延迟是 hover intent:鼠标只是路过一行,不该弹出东西。 */
|
|
2188
2190
|
const HOVER_OPEN_MS = 140
|
|
2189
2191
|
const HOVER_CLOSE_MS = 260
|
|
2190
|
-
const SUBMENU_W =
|
|
2192
|
+
const SUBMENU_W = 184
|
|
2191
2193
|
let flyoutName = ''
|
|
2192
2194
|
let flyoutEl = null
|
|
2193
2195
|
let flyoutRow = null
|
|
@@ -2273,18 +2275,35 @@ body[data-ds-dark-theme] .wisp-layer{--wisp-say-fg:#eaf2f8;--wisp-say-bg:rgba(20
|
|
|
2273
2275
|
}
|
|
2274
2276
|
flyoutButtons = menuButtons.splice(before)
|
|
2275
2277
|
layer.appendChild(panel)
|
|
2276
|
-
/*
|
|
2277
|
-
|
|
2278
|
-
|
|
2278
|
+
/* 位置:贴在这一行右侧,越界就翻到左边。
|
|
2279
|
+
**只用量层坐标 + 宽度** —— 宽度与坐标系无关,所以这个式子不可能算错:
|
|
2280
|
+
菜单的 left/top 是图层坐标(我们自己设的),菜单宽度取它自己的矩形宽度;
|
|
2281
|
+
面板宽度是**常量**(CSS 里给了固定 width,菜单面板本来就不该随内容变宽)。
|
|
2282
|
+
前面几版之所以一直偏,是因为去量"刚 append、还没布局"的面板的矩形 ——
|
|
2283
|
+
那时宽度是 0,整套校正被守卫挡掉,位置就停在了估算值上。 */
|
|
2284
|
+
let menuW = MENU_W
|
|
2279
2285
|
try {
|
|
2280
|
-
const
|
|
2281
|
-
if (
|
|
2282
|
-
} catch (e) { /*
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
+
const mr = menuEl && menuEl.getBoundingClientRect ? menuEl.getBoundingClientRect() : null
|
|
2287
|
+
if (mr && mr.width > 0) menuW = mr.width
|
|
2288
|
+
} catch (e) { /* 用常量兜底 */ }
|
|
2289
|
+
const menuLeft = menuAtX
|
|
2290
|
+
const menuTop = menuAtY
|
|
2291
|
+
let x = menuLeft + menuW + 2
|
|
2292
|
+
flyoutSide = 'right'
|
|
2293
|
+
if (x + SUBMENU_W > vw() - 8) {
|
|
2294
|
+
x = menuLeft - SUBMENU_W - 2
|
|
2295
|
+
flyoutSide = 'left'
|
|
2296
|
+
}
|
|
2286
2297
|
panel.style.left = Math.round(Math.max(8, x)) + 'px'
|
|
2287
|
-
|
|
2298
|
+
/* 纵向:用"行矩形相对菜单矩形的**偏移**" —— 相对量与坐标系无关,
|
|
2299
|
+
所以它既准确又不受图层偏移影响,也不需要知道头部/分隔线有多高。 */
|
|
2300
|
+
let rowOffset = MENU_PAD + Math.max(0, index) * MENU_ITEM_H
|
|
2301
|
+
try {
|
|
2302
|
+
const mr2 = menuEl && menuEl.getBoundingClientRect ? menuEl.getBoundingClientRect() : null
|
|
2303
|
+
const rr2 = rowEl && rowEl.getBoundingClientRect ? rowEl.getBoundingClientRect() : null
|
|
2304
|
+
if (mr2 && rr2 && rr2.height > 0) rowOffset = rr2.top - mr2.top
|
|
2305
|
+
} catch (e) { /* 用估算值 */ }
|
|
2306
|
+
panel.style.top = Math.round(Math.max(8, menuTop + rowOffset)) + 'px'
|
|
2288
2307
|
flyoutEl = panel
|
|
2289
2308
|
flyoutName = name
|
|
2290
2309
|
flyoutRow = rowEl
|
package/lib/client.template.js
CHANGED
|
@@ -51,7 +51,7 @@ window.__ModuleLoader__.load({
|
|
|
51
51
|
var exports = module.exports
|
|
52
52
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
|
|
53
53
|
|
|
54
|
-
const VERSION = '1.33.
|
|
54
|
+
const VERSION = '1.33.1'
|
|
55
55
|
|
|
56
56
|
/* 每一版一句话。**必须写当前版本** —— 预检里有一条断言盯着它,
|
|
57
57
|
忘了更新就会红,不会静默过期。 */
|
|
@@ -74,6 +74,7 @@ const WHATS_NEW = {
|
|
|
74
74
|
'1.31.0': '菜单重做:状态一目了然,开关是开关,大小能直接拖。',
|
|
75
75
|
'1.32.0': '分组改成鼠标悬停就展开、移开就收起(点一下则是钉住)。',
|
|
76
76
|
'1.33.0': '子菜单改成在旁边弹出(真正的菜单栏形状),→/← 进出自如。',
|
|
77
|
+
'1.33.1': '修子菜单位置算错、会压住主菜单的问题。',
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
/* 更新这件事**这个插件自己做不到**,如实写在代码里,免得以后有人以为能:
|
|
@@ -678,7 +679,8 @@ body[data-ds-dark-theme] .wisp-layer{--wisp-say-fg:#eaf2f8;--wisp-say-bg:rgba(20
|
|
|
678
679
|
.wisp-menu-caret{opacity:.55;font-size:10px;flex:0 0 auto}
|
|
679
680
|
/* 级联子菜单:浮在行的**右侧**(放不下时翻到左侧),不把下面的内容推下去。
|
|
680
681
|
与父行顶部对齐、允许轻微重叠 —— 指针从行斜着移到面板上时不会穿出"同一区域"。 */
|
|
681
|
-
.wisp-submenu{position:absolute;
|
|
682
|
+
.wisp-submenu{position:absolute;box-sizing:border-box;width:184px;padding:6px;border-radius:12px;font-size:12px;line-height:1.25;color:var(--dsw-alias-label-primary,var(--wisp-say-fg));background:var(--dsw-alias-bg-overlay,var(--wisp-say-bg));border:1px solid var(--dsw-alias-border-l1,var(--wisp-say-line));box-shadow:0 12px 34px rgba(0,0,0,.3);-webkit-backdrop-filter:blur(14px) saturate(160%);backdrop-filter:blur(14px) saturate(160%);pointer-events:auto;animation:wisp-fade .12s ease}
|
|
683
|
+
@keyframes wisp-fade{0%{opacity:0}100%{opacity:1}}
|
|
682
684
|
.wisp-menu-sub{padding-left:10px}
|
|
683
685
|
.wisp-menu-sub .wisp-menu-item{padding-left:12px;opacity:.94}
|
|
684
686
|
.wisp-dialog-backdrop{position:absolute;inset:0;background:rgba(6,12,26,.34);pointer-events:auto;animation:wisp-menu .16s ease}
|
|
@@ -2136,7 +2138,7 @@ body[data-ds-dark-theme] .wisp-layer{--wisp-say-fg:#eaf2f8;--wisp-say-bg:rgba(20
|
|
|
2136
2138
|
延迟是 hover intent:鼠标只是路过一行,不该弹出东西。 */
|
|
2137
2139
|
const HOVER_OPEN_MS = 140
|
|
2138
2140
|
const HOVER_CLOSE_MS = 260
|
|
2139
|
-
const SUBMENU_W =
|
|
2141
|
+
const SUBMENU_W = 184
|
|
2140
2142
|
let flyoutName = ''
|
|
2141
2143
|
let flyoutEl = null
|
|
2142
2144
|
let flyoutRow = null
|
|
@@ -2222,18 +2224,35 @@ body[data-ds-dark-theme] .wisp-layer{--wisp-say-fg:#eaf2f8;--wisp-say-bg:rgba(20
|
|
|
2222
2224
|
}
|
|
2223
2225
|
flyoutButtons = menuButtons.splice(before)
|
|
2224
2226
|
layer.appendChild(panel)
|
|
2225
|
-
/*
|
|
2226
|
-
|
|
2227
|
-
|
|
2227
|
+
/* 位置:贴在这一行右侧,越界就翻到左边。
|
|
2228
|
+
**只用量层坐标 + 宽度** —— 宽度与坐标系无关,所以这个式子不可能算错:
|
|
2229
|
+
菜单的 left/top 是图层坐标(我们自己设的),菜单宽度取它自己的矩形宽度;
|
|
2230
|
+
面板宽度是**常量**(CSS 里给了固定 width,菜单面板本来就不该随内容变宽)。
|
|
2231
|
+
前面几版之所以一直偏,是因为去量"刚 append、还没布局"的面板的矩形 ——
|
|
2232
|
+
那时宽度是 0,整套校正被守卫挡掉,位置就停在了估算值上。 */
|
|
2233
|
+
let menuW = MENU_W
|
|
2228
2234
|
try {
|
|
2229
|
-
const
|
|
2230
|
-
if (
|
|
2231
|
-
} catch (e) { /*
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
+
const mr = menuEl && menuEl.getBoundingClientRect ? menuEl.getBoundingClientRect() : null
|
|
2236
|
+
if (mr && mr.width > 0) menuW = mr.width
|
|
2237
|
+
} catch (e) { /* 用常量兜底 */ }
|
|
2238
|
+
const menuLeft = menuAtX
|
|
2239
|
+
const menuTop = menuAtY
|
|
2240
|
+
let x = menuLeft + menuW + 2
|
|
2241
|
+
flyoutSide = 'right'
|
|
2242
|
+
if (x + SUBMENU_W > vw() - 8) {
|
|
2243
|
+
x = menuLeft - SUBMENU_W - 2
|
|
2244
|
+
flyoutSide = 'left'
|
|
2245
|
+
}
|
|
2235
2246
|
panel.style.left = Math.round(Math.max(8, x)) + 'px'
|
|
2236
|
-
|
|
2247
|
+
/* 纵向:用"行矩形相对菜单矩形的**偏移**" —— 相对量与坐标系无关,
|
|
2248
|
+
所以它既准确又不受图层偏移影响,也不需要知道头部/分隔线有多高。 */
|
|
2249
|
+
let rowOffset = MENU_PAD + Math.max(0, index) * MENU_ITEM_H
|
|
2250
|
+
try {
|
|
2251
|
+
const mr2 = menuEl && menuEl.getBoundingClientRect ? menuEl.getBoundingClientRect() : null
|
|
2252
|
+
const rr2 = rowEl && rowEl.getBoundingClientRect ? rowEl.getBoundingClientRect() : null
|
|
2253
|
+
if (mr2 && rr2 && rr2.height > 0) rowOffset = rr2.top - mr2.top
|
|
2254
|
+
} catch (e) { /* 用估算值 */ }
|
|
2255
|
+
panel.style.top = Math.round(Math.max(8, menuTop + rowOffset)) + 'px'
|
|
2237
2256
|
flyoutEl = panel
|
|
2238
2257
|
flyoutName = name
|
|
2239
2258
|
flyoutRow = rowEl
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-wisp",
|
|
3
|
-
"version": "1.33.
|
|
3
|
+
"version": "1.33.1",
|
|
4
4
|
"description": "DeepSeek娘 — an unofficial floating desktop companion for the DeepSeek Harness UI. Zero dependencies; sprites inlined as data URIs; schedules on the Client timer service instead of the trapped browser timer globals.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
package/tools/smoke.mjs
CHANGED
|
@@ -258,6 +258,7 @@ const skinCount = await page.evaluate(() => {
|
|
|
258
258
|
const s = window.__wisp.skins
|
|
259
259
|
return Array.isArray(s) ? s.length : Object.keys(s ?? {}).length
|
|
260
260
|
})
|
|
261
|
+
|
|
261
262
|
check(menu !== null && menu.items.length === 8, 'the menu lists every entry',
|
|
262
263
|
`${menu?.items.length} items at the top level`)
|
|
263
264
|
|
|
@@ -580,6 +581,62 @@ check(skinSwap.layersDuringFade === 1, 'the cross-fade layer is gone once it set
|
|
|
580
581
|
// 每个页面都要装下这份包与解码后的精灵图(单张就是 naturalWidth*naturalHeight*4 字节),
|
|
581
582
|
// 多开一个页面 = 多一份;之前正是这样把浏览器推崩的,表现为随机的
|
|
582
583
|
// "Target page, context or browser has been closed",极难定位。
|
|
584
|
+
/* 级联子菜单的几何检查:必须在**页面还活着**的时候跑(它要量真实布局),
|
|
585
|
+
也必须在键盘段之后(它会开关菜单、动焦点)。 */
|
|
586
|
+
/* 级联子菜单的几何检查放在**最后**:它会开关菜单、动焦点,放在中间会扰动后面的键盘段。 */
|
|
587
|
+
/* 级联子菜单的**几何**:它在旁边,不在上面。
|
|
588
|
+
这一条替身测不到(假 DOM 没有布局),而"子菜单遮住主菜单"那个 bug 正好出在这里 ——
|
|
589
|
+
混用了视口坐标(getBoundingClientRect)与图层坐标(菜单的 left/top)。 */
|
|
590
|
+
const flyoutGeo = await page.evaluate(async () => {
|
|
591
|
+
const body = document.querySelector('.wisp-body')
|
|
592
|
+
const box = document.querySelector('.wisp-root')
|
|
593
|
+
if (!body || !box) return { noBody: true }
|
|
594
|
+
const r0 = box.getBoundingClientRect()
|
|
595
|
+
body.dispatchEvent(new MouseEvent('contextmenu', {
|
|
596
|
+
bubbles: true, cancelable: true, clientX: r0.left + r0.width / 2, clientY: r0.top + r0.height / 2,
|
|
597
|
+
}))
|
|
598
|
+
const menu = document.querySelector('.wisp-menu')
|
|
599
|
+
if (!menu) return { noMenu: true }
|
|
600
|
+
const row = [...menu.querySelectorAll('.wisp-menu-item')].find((el) => el.dataset && el.dataset.group)
|
|
601
|
+
if (!row) return { noRow: true }
|
|
602
|
+
row.dispatchEvent(new PointerEvent('pointerenter', { pointerType: 'mouse' }))
|
|
603
|
+
await new Promise((resolve) => setTimeout(resolve, 350))
|
|
604
|
+
const panel = document.querySelector('.wisp-submenu')
|
|
605
|
+
if (!panel) return { noPanel: true }
|
|
606
|
+
const mr = menu.getBoundingClientRect()
|
|
607
|
+
const pr = panel.getBoundingClientRect()
|
|
608
|
+
const rr = row.getBoundingClientRect()
|
|
609
|
+
const layer = menu.parentNode
|
|
610
|
+
const lr = layer.getBoundingClientRect ? layer.getBoundingClientRect() : { left: -999, top: -999, width: 0, height: 0 }
|
|
611
|
+
return {
|
|
612
|
+
menu: { l: Math.round(mr.left), r: Math.round(mr.right), w: Math.round(mr.width), styleL: menu.style.left, styleT: menu.style.top },
|
|
613
|
+
panel: { l: Math.round(pr.left), r: Math.round(pr.right), t: Math.round(pr.top), w: Math.round(pr.width), styleL: panel.style.left, styleT: panel.style.top },
|
|
614
|
+
row: { t: Math.round(rr.top), h: Math.round(rr.height) },
|
|
615
|
+
layer: { l: Math.round(lr.left), t: Math.round(lr.top), w: Math.round(lr.width), h: Math.round(lr.height), pos: getComputedStyle(layer).position },
|
|
616
|
+
view: { w: window.innerWidth, h: window.innerHeight },
|
|
617
|
+
rows: panel.querySelectorAll('.wisp-menu-item').length,
|
|
618
|
+
}
|
|
619
|
+
})
|
|
620
|
+
check(flyoutGeo.panel !== undefined && flyoutGeo.rows > 0,
|
|
621
|
+
'hovering a group row pops a submenu panel', JSON.stringify(flyoutGeo))
|
|
622
|
+
check(flyoutGeo.panel !== undefined
|
|
623
|
+
&& (flyoutGeo.panel.l >= flyoutGeo.menu.r - 6 || flyoutGeo.panel.r <= flyoutGeo.menu.l + 6),
|
|
624
|
+
'the submenu sits BESIDE the menu, not on top of it — window coords and layer coords must not be mixed',
|
|
625
|
+
flyoutGeo.panel ? `menu=${flyoutGeo.menu.l}..${flyoutGeo.menu.r} panel=${flyoutGeo.panel.l}..${flyoutGeo.panel.r}` : 'n/a')
|
|
626
|
+
check(flyoutGeo.panel !== undefined
|
|
627
|
+
&& flyoutGeo.panel.l >= 0 && flyoutGeo.panel.r <= flyoutGeo.view.w
|
|
628
|
+
&& flyoutGeo.panel.t >= 0,
|
|
629
|
+
'and it fits on screen', flyoutGeo.panel ? JSON.stringify(flyoutGeo.panel) : 'n/a')
|
|
630
|
+
check(flyoutGeo.panel !== undefined && Math.abs(flyoutGeo.panel.t - flyoutGeo.row.t) < 40,
|
|
631
|
+
'and lines up with the row it belongs to',
|
|
632
|
+
flyoutGeo.panel ? `row.t=${flyoutGeo.row.t} panel.t=${flyoutGeo.panel.t}` : 'n/a')
|
|
633
|
+
await page.evaluate(() => {
|
|
634
|
+
/* 菜单的键盘监听挂在 **window** 上,不是 document —— 发错目标菜单就不会关,
|
|
635
|
+
后面的键盘段会在"一个还没关掉的菜单"上重开,焦点状态全乱(就是这么挂掉三条的)。 */
|
|
636
|
+
window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }))
|
|
637
|
+
window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }))
|
|
638
|
+
})
|
|
639
|
+
|
|
583
640
|
await browser.close()
|
|
584
641
|
|
|
585
642
|
/* ------------------------------------------------------ 8. 自己踱步 ------- */
|
|
@@ -645,6 +702,7 @@ await wanderBrowser.close()
|
|
|
645
702
|
|
|
646
703
|
|
|
647
704
|
console.log(`\n${fail === 0 ? '=== SMOKE PASSED ===' : '=== SMOKE FAILED ==='}`)
|
|
705
|
+
|
|
648
706
|
console.log(` ${pass} passed, ${fail} failed (real Chromium, ${headed ? 'headed' : 'headless'})`)
|
|
649
707
|
console.log(` playwright: ${playwright.from}`)
|
|
650
708
|
if (executablePath) console.log(` browser: ${executablePath}`)
|