mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-01-10 10:12:31 +08:00
refactor: add shared fixtures and test.step() patterns
- Add tests/e2e/lib/fixtures.ts with shared test helpers - Add tests/e2e/fixtures/diagrams.ts with XML test data - Add expectBeforeAndAfterReload() helper for persistence tests - Add test.step() for better test reporting in complex tests - Consolidate mock helpers into fixtures module - Reduce code duplication across 17 test files
This commit is contained in:
@@ -1,17 +1,21 @@
|
||||
import { expect, test } from "@playwright/test"
|
||||
import { SINGLE_BOX_XML } from "./fixtures/diagrams"
|
||||
import {
|
||||
expect,
|
||||
getChatInput,
|
||||
getIframe,
|
||||
sendMessage,
|
||||
test,
|
||||
} from "./lib/fixtures"
|
||||
import { createMockSSEResponse } from "./lib/helpers"
|
||||
|
||||
test.describe("Copy/Paste Functionality", () => {
|
||||
test("can paste text into chat input", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
const chatInput = page.locator('textarea[aria-label="Chat input"]')
|
||||
const chatInput = getChatInput(page)
|
||||
await expect(chatInput).toBeVisible({ timeout: 10000 })
|
||||
|
||||
// Focus and paste text
|
||||
await chatInput.focus()
|
||||
await page.keyboard.insertText("Create a flowchart diagram")
|
||||
|
||||
@@ -20,11 +24,9 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
|
||||
test("can paste multiline text into chat input", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
const chatInput = page.locator('textarea[aria-label="Chat input"]')
|
||||
const chatInput = getChatInput(page)
|
||||
await expect(chatInput).toBeVisible({ timeout: 10000 })
|
||||
|
||||
await chatInput.focus()
|
||||
@@ -40,23 +42,16 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
status: 200,
|
||||
contentType: "text/event-stream",
|
||||
body: createMockSSEResponse(
|
||||
`<mxCell id="box" value="Test" style="rounded=1;" vertex="1" parent="1"><mxGeometry x="100" y="100" width="100" height="50" as="geometry"/></mxCell>`,
|
||||
SINGLE_BOX_XML,
|
||||
"Here is your diagram with a test box.",
|
||||
),
|
||||
})
|
||||
})
|
||||
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
const chatInput = page.locator('textarea[aria-label="Chat input"]')
|
||||
await expect(chatInput).toBeVisible({ timeout: 10000 })
|
||||
|
||||
// Send a message
|
||||
await chatInput.fill("Create a test box")
|
||||
await chatInput.press("ControlOrMeta+Enter")
|
||||
await sendMessage(page, "Create a test box")
|
||||
|
||||
// Wait for response
|
||||
await expect(
|
||||
@@ -68,7 +63,7 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
'[data-testid="copy-button"], button[aria-label*="Copy"], button:has(svg.lucide-copy), button:has(svg.lucide-clipboard)',
|
||||
)
|
||||
|
||||
// Copy button feature may not exist in all versions - skip if not available
|
||||
// Copy button feature may not exist - skip if not available
|
||||
const buttonCount = await copyButton.count()
|
||||
if (buttonCount === 0) {
|
||||
test.skip()
|
||||
@@ -76,7 +71,6 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
}
|
||||
|
||||
await copyButton.first().click()
|
||||
// Should show copied confirmation (toast or button state change)
|
||||
await expect(
|
||||
page.locator('text="Copied"').or(page.locator("svg.lucide-check")),
|
||||
).toBeVisible({ timeout: 3000 })
|
||||
@@ -84,16 +78,14 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
|
||||
test("paste XML into XML input works", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
// Find XML input textarea (different from chat input)
|
||||
// Find XML input textarea
|
||||
const xmlInput = page.locator(
|
||||
'textarea[placeholder*="XML"], textarea[placeholder*="mxCell"]',
|
||||
)
|
||||
|
||||
// XML input might be in a collapsed section - try to expand it
|
||||
// Try to expand XML section if collapsed
|
||||
const xmlToggle = page.locator(
|
||||
'button:has-text("XML"), [data-testid*="xml"], details summary',
|
||||
)
|
||||
@@ -101,7 +93,7 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
await xmlToggle.first().click()
|
||||
}
|
||||
|
||||
// XML input feature may not exist in all versions - skip if not available
|
||||
// Skip if XML input not available
|
||||
const xmlInputCount = await xmlInput.count()
|
||||
const isXmlVisible =
|
||||
xmlInputCount > 0 && (await xmlInput.first().isVisible())
|
||||
@@ -120,20 +112,13 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
|
||||
test("keyboard shortcuts work in chat input", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
const chatInput = page.locator('textarea[aria-label="Chat input"]')
|
||||
const chatInput = getChatInput(page)
|
||||
await expect(chatInput).toBeVisible({ timeout: 10000 })
|
||||
|
||||
// Type some text
|
||||
await chatInput.fill("Hello world")
|
||||
|
||||
// Select all with Ctrl+A
|
||||
await chatInput.press("ControlOrMeta+a")
|
||||
|
||||
// Type replacement text
|
||||
await chatInput.fill("New text")
|
||||
|
||||
await expect(chatInput).toHaveValue("New text")
|
||||
@@ -141,21 +126,16 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
|
||||
test("can undo/redo in chat input", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
const chatInput = page.locator('textarea[aria-label="Chat input"]')
|
||||
const chatInput = getChatInput(page)
|
||||
await expect(chatInput).toBeVisible({ timeout: 10000 })
|
||||
|
||||
// Type text
|
||||
await chatInput.fill("First text")
|
||||
await chatInput.press("Tab") // Blur to register change
|
||||
await chatInput.press("Tab")
|
||||
|
||||
await chatInput.focus()
|
||||
await chatInput.fill("Second text")
|
||||
|
||||
// Undo with Ctrl+Z
|
||||
await chatInput.press("ControlOrMeta+z")
|
||||
|
||||
// Verify page is still functional after undo
|
||||
@@ -164,11 +144,9 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
|
||||
test("chat input handles special characters", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
const chatInput = page.locator('textarea[aria-label="Chat input"]')
|
||||
const chatInput = getChatInput(page)
|
||||
await expect(chatInput).toBeVisible({ timeout: 10000 })
|
||||
|
||||
const specialText = "Test <>&\"' special chars 日本語 中文 🎉"
|
||||
@@ -179,18 +157,14 @@ test.describe("Copy/Paste Functionality", () => {
|
||||
|
||||
test("long text in chat input scrolls", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "networkidle" })
|
||||
await page
|
||||
.locator("iframe")
|
||||
.waitFor({ state: "visible", timeout: 30000 })
|
||||
await getIframe(page).waitFor({ state: "visible", timeout: 30000 })
|
||||
|
||||
const chatInput = page.locator('textarea[aria-label="Chat input"]')
|
||||
const chatInput = getChatInput(page)
|
||||
await expect(chatInput).toBeVisible({ timeout: 10000 })
|
||||
|
||||
// Very long text
|
||||
const longText = "This is a very long text. ".repeat(50)
|
||||
await chatInput.fill(longText)
|
||||
|
||||
// Input should handle it without error
|
||||
const value = await chatInput.inputValue()
|
||||
expect(value.length).toBeGreaterThan(500)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user