Skip to content

Commit 902df34

Browse files
committed
Add topbar close hover regression coverage
1 parent f187165 commit 902df34

2 files changed

Lines changed: 110 additions & 0 deletions

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { readFileSync } from "node:fs";
2+
import { resolve } from "node:path";
3+
import { expect, test } from "@playwright/test";
4+
5+
function sanitizeCssModules(css: string): string {
6+
return css.replaceAll(/:global\(([^)]+)\)/g, "$1");
7+
}
8+
9+
const componentsCss = readFileSync(
10+
resolve(process.cwd(), "../packages/web/src/styles/components.css"),
11+
"utf8"
12+
);
13+
const buttonCss = sanitizeCssModules(
14+
readFileSync(
15+
resolve(process.cwd(), "../packages/web/src/components/ui/button/index.module.css"),
16+
"utf8"
17+
)
18+
);
19+
const iconButtonCss = sanitizeCssModules(
20+
readFileSync(
21+
resolve(process.cwd(), "../packages/web/src/components/ui/icon-button/index.module.css"),
22+
"utf8"
23+
)
24+
);
25+
26+
test("topbar close button stays vertically centered while hovered", async ({ page }) => {
27+
await page.setContent(`
28+
<html>
29+
<head>
30+
<style>
31+
:root {
32+
--bg-page: #0f1720;
33+
--bg-surface: #16212c;
34+
--bg-hover: #223140;
35+
--bg-active: #1e2c38;
36+
--border: rgba(123, 152, 180, 0.24);
37+
--border-light: rgba(173, 201, 229, 0.42);
38+
--text-primary: #edf4fb;
39+
--text-secondary: #c8d5e2;
40+
--text-tertiary: #8fa4b8;
41+
--accent-blue: #79b8ff;
42+
--shadow-xl: 0 8px 24px rgba(0, 0, 0, 0.22);
43+
--radius-sm: 5px;
44+
--radius-md: 8px;
45+
--radius-lg: 12px;
46+
--duration-fast: 120ms;
47+
--duration-normal: 180ms;
48+
--ease-out: ease;
49+
--sp-1: 4px;
50+
--sp-2: 8px;
51+
--sp-4: 16px;
52+
--btn-height-md: 32px;
53+
--text-base: 14px;
54+
--text-xs: 12px;
55+
--font-medium: 500;
56+
--font-sans: ui-sans-serif, system-ui, sans-serif;
57+
}
58+
body {
59+
margin: 0;
60+
padding: 24px;
61+
background: #0b1218;
62+
}
63+
${buttonCss}
64+
${iconButtonCss}
65+
${componentsCss}
66+
</style>
67+
</head>
68+
<body>
69+
<div class="topbar-tab-shell active" style="width: 160px;">
70+
<button class="topbar-tab active" type="button">
71+
<span class="topbar-dot active"></span>
72+
<span class="topbar-tab-name">coder-studio</span>
73+
</button>
74+
<button class="root btn btn-ghost btn-sm topbar-close" type="button" aria-label="Close Workspace">
75+
<span class="icon" aria-hidden="true">
76+
<svg width="14" height="14" viewBox="0 0 24 24">
77+
<path
78+
d="M18 6 6 18M6 6l12 12"
79+
stroke="currentColor"
80+
stroke-width="2"
81+
stroke-linecap="round"
82+
/>
83+
</svg>
84+
</span>
85+
</button>
86+
</div>
87+
</body>
88+
</html>
89+
`);
90+
91+
const tabShell = page.locator(".topbar-tab-shell");
92+
await tabShell.hover();
93+
94+
const closeButton = page.locator(".topbar-close");
95+
await expect(closeButton).toBeVisible();
96+
97+
const beforeHoverBox = await closeButton.boundingBox();
98+
expect(beforeHoverBox).not.toBeNull();
99+
100+
await closeButton.hover();
101+
102+
const afterHoverBox = await closeButton.boundingBox();
103+
expect(afterHoverBox).not.toBeNull();
104+
expect(Math.abs((afterHoverBox?.y ?? 0) - (beforeHoverBox?.y ?? 0))).toBeLessThan(0.5);
105+
});

packages/web/src/styles/components.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6684,6 +6684,11 @@ textarea.input {
66846684
z-index: 1;
66856685
}
66866686

6687+
.topbar-close:hover:not(:disabled),
6688+
.topbar-close:active:not(:disabled) {
6689+
transform: translateY(-50%);
6690+
}
6691+
66876692
.topbar-tab-shell.active .topbar-close,
66886693
.topbar-tab-shell:hover .topbar-close,
66896694
.topbar-tab-shell:focus-within .topbar-close {

0 commit comments

Comments
 (0)