mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-07 16:17:25 +03:00
fix(gui-plugins): correct WSL radio alignment (#53676)
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,91 @@
|
||||
import { base64Encode } from "@opencode/util/encode"
|
||||
import { expect, test } from "@playwright/test"
|
||||
import { expect, test, type Locator } from "@playwright/test"
|
||||
import { NO_PROVIDER, REMOTE_SERVER, SERVER, holdRoute, project, provider, session } from "../utils/app"
|
||||
import { mockOpenCodeServer, mockServers } from "../utils/mock-server"
|
||||
import { expectSessionTitle } from "../utils/waits"
|
||||
|
||||
test.use({ viewport: { width: 1280, height: 900 } })
|
||||
|
||||
test("WSL distribution radios stay inset and aligned in both add-server lists", async ({ page }) => {
|
||||
await mockOpenCodeServer(page, {
|
||||
directory: "/repo",
|
||||
project: project({ id: "proj_wsl_alignment", directory: "/repo", name: "WSL project" }),
|
||||
provider: NO_PROVIDER,
|
||||
sessions: [],
|
||||
pageMessages: () => ({ items: [] }),
|
||||
})
|
||||
await page.goto(
|
||||
`/e2e/utils/settings-wsl.html?${new URLSearchParams({
|
||||
server: SERVER,
|
||||
mode: "ready",
|
||||
distros: "Ubuntu-24.04,AlmaLinux-9,Debian-WSL1",
|
||||
})}`,
|
||||
)
|
||||
const settings = page.getByTestId("settings-screen")
|
||||
await settings.getByRole("tab", { name: "Servers", exact: true }).click()
|
||||
await expect(settings.getByRole("region", { name: "Ubuntu", exact: true })).toHaveCount(1)
|
||||
await settings.getByRole("button", { name: "Add server", exact: true }).press("Enter")
|
||||
await page.getByRole("menuitem", { name: "Add WSL server", exact: true }).click()
|
||||
const dialog = page.getByRole("dialog")
|
||||
const ubuntu = dialog.getByRole("radio", { name: "Ubuntu-24.04 OpenCode not installed", exact: true })
|
||||
const alma = dialog.getByRole("radio", { name: "AlmaLinux-9 OpenCode not installed", exact: true })
|
||||
await expect(ubuntu).toBeEnabled()
|
||||
await expect(dialog.getByText("OpenCode not installed", { exact: true })).toHaveCount(2)
|
||||
await expect(dialog.getByRole("radio", { name: "Debian-WSL1 Unsupported · Use WSL 2", exact: true })).toBeDisabled()
|
||||
await expectDistroLayout(dialog)
|
||||
await dialog
|
||||
.locator('[data-slot="radio-v2-item-label"]')
|
||||
.filter({ has: page.getByText("AlmaLinux-9", { exact: true }) })
|
||||
.click()
|
||||
await expect(alma).toBeChecked()
|
||||
await alma.press("ArrowUp")
|
||||
await expect(ubuntu).toBeChecked()
|
||||
await expect(ubuntu).toBeFocused()
|
||||
await expectDistroLayout(dialog)
|
||||
|
||||
await dialog.getByRole("button", { name: /Need another distro/ }).click()
|
||||
await expect(dialog.getByRole("heading", { name: "Install distro", exact: true })).toBeVisible()
|
||||
await expect(dialog.getByRole("radio", { name: "Debian", exact: true })).toBeChecked()
|
||||
await expectDistroLayout(dialog)
|
||||
await dialog
|
||||
.locator('[data-slot="radio-v2-item-label"]')
|
||||
.filter({ has: page.getByText("FedoraLinux-43", { exact: true }) })
|
||||
.click()
|
||||
await expect(dialog.getByRole("radio", { name: "FedoraLinux-43", exact: true })).toBeChecked()
|
||||
await expectDistroLayout(dialog)
|
||||
})
|
||||
|
||||
async function expectDistroLayout(dialog: Locator) {
|
||||
// Keep the visible control inside its row and aligned with its label, including disabled rows,
|
||||
// and keep rows flush so every divider sits the same distance from the content below it.
|
||||
await expect
|
||||
.poll(() =>
|
||||
dialog.locator(".settings-wsl-distro-row").evaluateAll((rows) =>
|
||||
rows.every((row, index) => {
|
||||
const previous = rows[index - 1]?.getBoundingClientRect()
|
||||
|
||||
if (previous && Math.abs(row.getBoundingClientRect().top - previous.bottom) > 1) return false
|
||||
const control = row.querySelector('[data-slot="radio-v2-item-control"]')
|
||||
const label = row.querySelector('[data-slot="radio-v2-item-label-text"]')
|
||||
|
||||
if (!control || !label) return false
|
||||
const bounds = row.getBoundingClientRect()
|
||||
const circle = control.getBoundingClientRect()
|
||||
const text = label.getBoundingClientRect()
|
||||
|
||||
return (
|
||||
circle.left - bounds.left >= 8 &&
|
||||
circle.top - bounds.top >= 8 &&
|
||||
circle.bottom < bounds.bottom &&
|
||||
circle.right < text.left &&
|
||||
Math.abs(circle.top + circle.height / 2 - (text.top + text.height / 2)) <= 4
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.toBe(true)
|
||||
}
|
||||
|
||||
for (const mode of ["failed", "stopped", "ready"] as const) {
|
||||
test(`manages a ${mode} configured WSL server from the Servers page`, async ({ page }) => {
|
||||
await mockOpenCodeServer(page, {
|
||||
|
||||
@@ -29,6 +29,10 @@ export function mount(input: {
|
||||
ssh?: string | null
|
||||
storage?: string | null
|
||||
hold?: string | null
|
||||
/** Comma-separated installed distributions for the add-server dialog. */
|
||||
distros?: string | null
|
||||
/** Holds the distribution refresh job while inspecting disabled dialog controls. */
|
||||
busy?: string | null
|
||||
/** Enables the updater Ipc; check and install reject with this message, which may be empty. */
|
||||
updater?: string | null
|
||||
}) {
|
||||
@@ -40,6 +44,7 @@ export function mount(input: {
|
||||
const endpoint = { url: input.wsl ?? input.server }
|
||||
const ready = () => ({ kind: "ready" as const, url: endpoint.url, password: null })
|
||||
const held = Promise.withResolvers<void>()
|
||||
const distros = input.distros?.split(",").filter(Boolean) ?? []
|
||||
|
||||
const storage = (name?: string) => {
|
||||
const item = (key: string) => (name ? `${name}:${key}` : key)
|
||||
@@ -82,11 +87,18 @@ export function mount(input: {
|
||||
},
|
||||
state: {
|
||||
runtime: { available: true, version: "2", error: null },
|
||||
installed: [],
|
||||
online: [],
|
||||
distroProbes: {},
|
||||
installed: distros.map((name) => ({ name, version: name === "Debian-WSL1" ? 1 : 2, isDefault: false })),
|
||||
online: distros.length
|
||||
? ["Debian", "FedoraLinux-43", "openSUSE-Tumbleweed", "OracleLinux_9_1", "kali-linux"].map((name) => ({
|
||||
name,
|
||||
label: name,
|
||||
}))
|
||||
: [],
|
||||
distroProbes: Object.fromEntries(
|
||||
distros.map((name) => [name, { name, canExecute: true, hasBash: true, hasCurl: true, error: null }]),
|
||||
),
|
||||
pendingRestart: false,
|
||||
hostJob: "idle",
|
||||
hostJob: input.busy ? "busy" : "idle",
|
||||
distroJobs: {},
|
||||
servers: [
|
||||
{
|
||||
@@ -101,6 +113,19 @@ export function mount(input: {
|
||||
},
|
||||
],
|
||||
opencodeChecks: {
|
||||
...Object.fromEntries(
|
||||
distros.map((name) => [
|
||||
name,
|
||||
{
|
||||
distro: name,
|
||||
resolvedPath: null,
|
||||
version: null,
|
||||
expectedVersion: "current",
|
||||
matchesDesktop: null,
|
||||
error: null,
|
||||
},
|
||||
]),
|
||||
),
|
||||
Ubuntu: {
|
||||
distro: "Ubuntu",
|
||||
resolvedPath: "/usr/bin/opencode",
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
ssh: query.get("ssh"),
|
||||
storage: query.get("storage"),
|
||||
hold: query.get("hold"),
|
||||
distros: query.get("distros"),
|
||||
busy: query.get("busy"),
|
||||
updater: query.get("updater"),
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -187,12 +187,12 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.settings-wsl-distro-group [data-slot="radio-v2-items"] {
|
||||
.settings-wsl-distro-group[data-component="radio-v2"] [data-slot="radio-v2-items"] {
|
||||
width: 100%;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.settings-wsl-distro-row {
|
||||
.settings-wsl-distro-row[data-slot="radio-v2-item"] {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-height: 62px;
|
||||
@@ -375,7 +375,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.settings-wsl-catalog-row {
|
||||
.settings-wsl-catalog-row[data-slot="radio-v2-item"] {
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user