Преглед изворни кода

feat(desktop): more e2e tests (#13975)

Filip пре 1 месец
родитељ
комит
4d5e86d8a5

+ 15 - 0
packages/app/e2e/commands/input-focus.spec.ts

@@ -0,0 +1,15 @@
+import { test, expect } from "../fixtures"
+import { promptSelector } from "../selectors"
+
+test("ctrl+l focuses the prompt", async ({ page, gotoSession }) => {
+  await gotoSession()
+
+  const prompt = page.locator(promptSelector)
+  await expect(prompt).toBeVisible()
+
+  await page.locator("main").click({ position: { x: 5, y: 5 } })
+  await expect(prompt).not.toBeFocused()
+
+  await page.keyboard.press("Control+L")
+  await expect(prompt).toBeFocused()
+})

+ 31 - 0
packages/app/e2e/commands/panels.spec.ts

@@ -0,0 +1,31 @@
+import { test, expect } from "../fixtures"
+import { modKey } from "../utils"
+
+const expanded = async (el: { getAttribute: (name: string) => Promise<string | null> }) => {
+  const value = await el.getAttribute("aria-expanded")
+  if (value !== "true" && value !== "false") throw new Error(`Expected aria-expanded to be true|false, got: ${value}`)
+  return value === "true"
+}
+
+test("review panel can be toggled via keybind", async ({ page, gotoSession }) => {
+  await gotoSession()
+
+  const treeToggle = page.getByRole("button", { name: "Toggle file tree" }).first()
+  await expect(treeToggle).toBeVisible()
+  if (await expanded(treeToggle)) await treeToggle.click()
+  await expect(treeToggle).toHaveAttribute("aria-expanded", "false")
+
+  const reviewToggle = page.getByRole("button", { name: "Toggle review" }).first()
+  await expect(reviewToggle).toBeVisible()
+  if (await expanded(reviewToggle)) await reviewToggle.click()
+  await expect(reviewToggle).toHaveAttribute("aria-expanded", "false")
+  await expect(page.locator("#review-panel")).toHaveCount(0)
+
+  await page.keyboard.press(`${modKey}+Shift+R`)
+  await expect(reviewToggle).toHaveAttribute("aria-expanded", "true")
+  await expect(page.locator("#review-panel")).toBeVisible()
+
+  await page.keyboard.press(`${modKey}+Shift+R`)
+  await expect(reviewToggle).toHaveAttribute("aria-expanded", "false")
+  await expect(page.locator("#review-panel")).toHaveCount(0)
+})

+ 32 - 0
packages/app/e2e/commands/tab-close.spec.ts

@@ -0,0 +1,32 @@
+import { test, expect } from "../fixtures"
+import { promptSelector } from "../selectors"
+import { modKey } from "../utils"
+
+test("mod+w closes the active file tab", async ({ page, gotoSession }) => {
+  await gotoSession()
+
+  await page.locator(promptSelector).click()
+  await page.keyboard.type("/open")
+  await expect(page.locator('[data-slash-id="file.open"]').first()).toBeVisible()
+  await page.keyboard.press("Enter")
+
+  const dialog = page
+    .getByRole("dialog")
+    .filter({ has: page.getByPlaceholder(/search files/i) })
+    .first()
+  await expect(dialog).toBeVisible()
+
+  await dialog.getByRole("textbox").first().fill("package.json")
+  const item = dialog.locator('[data-slot="list-item"][data-key^="file:"]').first()
+  await expect(item).toBeVisible({ timeout: 30_000 })
+  await item.click()
+  await expect(dialog).toHaveCount(0)
+
+  const tab = page.getByRole("tab", { name: "package.json" }).first()
+  await expect(tab).toBeVisible()
+  await tab.click()
+  await expect(tab).toHaveAttribute("aria-selected", "true")
+
+  await page.keyboard.press(`${modKey}+W`)
+  await expect(page.getByRole("tab", { name: "package.json" })).toHaveCount(0)
+})

+ 22 - 0
packages/app/e2e/prompt/prompt-drop-file-uri.spec.ts

@@ -0,0 +1,22 @@
+import { test, expect } from "../fixtures"
+import { promptSelector } from "../selectors"
+
+test("dropping text/plain file: uri inserts a file pill", async ({ page, gotoSession }) => {
+  await gotoSession()
+
+  const prompt = page.locator(promptSelector)
+  await prompt.click()
+
+  const path = process.platform === "win32" ? "C:\\opencode-e2e-drop.txt" : "/tmp/opencode-e2e-drop.txt"
+  const dt = await page.evaluateHandle((text) => {
+    const dt = new DataTransfer()
+    dt.setData("text/plain", text)
+    return dt
+  }, `file:${path}`)
+
+  await page.dispatchEvent("body", "drop", { dataTransfer: dt })
+
+  const pill = page.locator(`${promptSelector} [data-type="file"]`).first()
+  await expect(pill).toBeVisible()
+  await expect(pill).toHaveAttribute("data-path", path)
+})

+ 30 - 0
packages/app/e2e/prompt/prompt-drop-file.spec.ts

@@ -0,0 +1,30 @@
+import { test, expect } from "../fixtures"
+import { promptSelector } from "../selectors"
+
+test("dropping an image file adds an attachment", async ({ page, gotoSession }) => {
+  await gotoSession()
+
+  const prompt = page.locator(promptSelector)
+  await prompt.click()
+
+  const png = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO3+4uQAAAAASUVORK5CYII="
+  const dt = await page.evaluateHandle((b64) => {
+    const dt = new DataTransfer()
+    const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0))
+    const file = new File([bytes], "drop.png", { type: "image/png" })
+    dt.items.add(file)
+    return dt
+  }, png)
+
+  await page.dispatchEvent("body", "drop", { dataTransfer: dt })
+
+  const img = page.locator('img[alt="drop.png"]').first()
+  await expect(img).toBeVisible()
+
+  const remove = page.getByRole("button", { name: "Remove attachment" }).first()
+  await expect(remove).toBeVisible()
+
+  await img.hover()
+  await remove.click()
+  await expect(page.locator('img[alt="drop.png"]')).toHaveCount(0)
+})

+ 18 - 0
packages/app/e2e/prompt/prompt-multiline.spec.ts

@@ -0,0 +1,18 @@
+import { test, expect } from "../fixtures"
+import { promptSelector } from "../selectors"
+
+test("shift+enter inserts a newline without submitting", async ({ page, gotoSession }) => {
+  await gotoSession()
+
+  await expect(page).toHaveURL(/\/session\/?$/)
+
+  const prompt = page.locator(promptSelector)
+  await prompt.click()
+  await page.keyboard.type("line one")
+  await page.keyboard.press("Shift+Enter")
+  await page.keyboard.type("line two")
+
+  await expect(page).toHaveURL(/\/session\/?$/)
+  await expect(prompt).toContainText("line one")
+  await expect(prompt).toContainText("line two")
+})

+ 23 - 0
packages/app/e2e/prompt/prompt-slash-terminal.spec.ts

@@ -0,0 +1,23 @@
+import { test, expect } from "../fixtures"
+import { promptSelector, terminalSelector } from "../selectors"
+
+test("/terminal toggles the terminal panel", async ({ page, gotoSession }) => {
+  await gotoSession()
+
+  const prompt = page.locator(promptSelector)
+  const terminal = page.locator(terminalSelector)
+
+  await expect(terminal).not.toBeVisible()
+
+  await prompt.click()
+  await page.keyboard.type("/terminal")
+  await expect(page.locator('[data-slash-id="terminal.toggle"]').first()).toBeVisible()
+  await page.keyboard.press("Enter")
+  await expect(terminal).toBeVisible()
+
+  await prompt.click()
+  await page.keyboard.type("/terminal")
+  await expect(page.locator('[data-slash-id="terminal.toggle"]').first()).toBeVisible()
+  await page.keyboard.press("Enter")
+  await expect(terminal).not.toBeVisible()
+})