/** * Scenario: database-view-edit-inline * * Verifies that double-clicking a cell opens the InlineEditor, editing and * blurring persists the value to Baserow, and a page reload confirms persistence. * * Flow: * 1. Navigate to a page with an existing database-view (grid view). * 2. Locate the cell for "Task Alpha" in the primary field column. * 3. Double-click the cell — InlineEditor should appear. * 4. Clear the value and type a new name. * 5. Blur the input (Tab key) to trigger onSave. * 6. Verify the new value appears in the table without full reload. * 7. Reload the page. * 8. Verify the new value is still present (persisted to Baserow). */ import { test, expect } from "@playwright/test"; import * as fs from "fs"; import * as path from "path"; import type { BaserowSeed } from "../fixtures/baserow"; import { deleteBaserowRows } from "../fixtures/cleanup"; const BASE_URL = process.env.E2E_DOCMOST_URL ?? "http://localhost:5173"; const BRIDGE_URL = process.env.E2E_BRIDGE_URL ?? "http://localhost:4001"; const SEED_FILE = path.resolve(__dirname, "../.auth/baserow-seed.json"); const EDITED_VALUE = "Task Alpha EDITED"; test.describe("database-view inline edit", () => { let seed: BaserowSeed; test.beforeAll(() => { if (!fs.existsSync(SEED_FILE)) { throw new Error(`Seed file not found at ${SEED_FILE}.`); } seed = JSON.parse(fs.readFileSync(SEED_FILE, "utf-8")) as BaserowSeed; }); test("double-click cell, edit, blur — value persists after reload", async ({ page, request, }) => { // Navigate to the app and ensure a page with the database-view is loaded. // We use the bridge API directly to verify persistence (bypassing the UI cache). await page.goto(BASE_URL); // Wait for editor surface. In a real suite, a shared page fixture would // create the page + insert the node once. Here we use a simpler approach: // navigate to the app root and look for any existing database-view node. // If none exists, skip gracefully (test ordering dependency on insert spec). const tableRenderer = page .getByTestId("table-renderer") .or(page.locator("[data-node-type='database-view'] table")) .first(); // If no database-view page exists yet, create one inline. const rendererExists = await tableRenderer.isVisible({ timeout: 5_000 }).catch(() => false); if (!rendererExists) { test.skip( true, "No database-view page found. Run database-view-insert spec first.", ); return; } // Locate the cell containing "Task Alpha" in the primary column. const taskAlphaCell = page .getByTestId(`cell-${seed.rowIds[0]}-${seed.primaryFieldName}`) .or(page.getByRole("cell", { name: "Task Alpha" })) .first(); await taskAlphaCell.waitFor({ state: "visible", timeout: 10_000 }); // Double-click to open the inline editor. await taskAlphaCell.dblclick(); // The InlineEditor input should appear. const inlineInput = page .getByTestId("inline-editor-input") .or(page.locator("input[class*='input'], .inline-editor input")) .first(); await inlineInput.waitFor({ state: "visible", timeout: 5_000 }); // Clear and type the new value. await inlineInput.selectText(); await inlineInput.fill(EDITED_VALUE); // Blur to trigger onSave (Tab key moves focus away). await inlineInput.press("Tab"); // The editor should close and the new value should be visible in the cell. await expect(taskAlphaCell.or(page.getByText(EDITED_VALUE))).toContainText( EDITED_VALUE, { timeout: 10_000 }, ); // Reload the page — this forces a fresh fetch from Baserow via the bridge. await page.reload(); // Wait for the table to re-render. await tableRenderer.waitFor({ state: "visible", timeout: 20_000 }); // The edited value must still be present — confirms persistence to Baserow. await expect(page.getByText(EDITED_VALUE)).toBeVisible({ timeout: 15_000 }); }); test.afterAll(async ({ request }) => { // Restore "Task Alpha" on the first row so subsequent tests start clean. // We call the bridge PATCH endpoint directly. if (!seed?.rowIds[0]) return; await request.patch( `${BRIDGE_URL}/api/v1/tables/${seed.tableId}/rows/${seed.rowIds[0]}`, { headers: { Authorization: "Bearer brg_e2e_admin", "Content-Type": "application/json", }, data: { fields: { [seed.primaryFieldName]: "Task Alpha" }, }, }, ); }); });