Files
TX/artifacts/tx-os/tests/notes-composer-color.spec.mjs
T
riyadhafraa 2b31b5e3aa Remove title field from notes and update tests to reflect changes
Refactors the notes feature by removing the `title` field and updating all related tests and UI components to use `content` instead.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 7464969c-726a-4ec2-a3b2-8ff63f91f6ed
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/591TuZw
Replit-Helium-Checkpoint-Created: true
2026-05-11 07:53:40 +00:00

111 lines
3.7 KiB
JavaScript

// E2E regression for the inline notes composer color picker.
// The composer auto-saves on outside mousedown. Radix popovers render in
// a portal outside the composer's DOM, so picking a color used to count
// as an "outside click" and saved the note with the OLD color before the
// swatch's onClick had a chance to update state. This test guards that
// fix: pick a non-default color, click outside, then assert the saved
// note has that color.
import { test, expect } from "@playwright/test";
import pg from "pg";
const DATABASE_URL = process.env.DATABASE_URL;
if (!DATABASE_URL) {
throw new Error("DATABASE_URL must be set to run this UI test");
}
const TEST_PASSWORD = "TestPass123!";
const TEST_PASSWORD_HASH =
"$2b$10$Bs636ukPMyz01nKrsi.5m.JlDXSN22AVCvn8cgPWWDbo5yJRQX2vu";
const pool = new pg.Pool({ connectionString: DATABASE_URL });
const createdUserIds = [];
function uniq() {
return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
}
async function createUser(prefix, displayEn) {
const username = `${prefix}_${uniq()}`;
const { rows } = await pool.query(
`INSERT INTO users (username, email, password_hash, display_name_en, preferred_language, is_active)
VALUES ($1, $2, $3, $4, 'en', true) RETURNING id`,
[username, `${username}@example.com`, TEST_PASSWORD_HASH, displayEn],
);
const id = rows[0].id;
createdUserIds.push(id);
await pool.query(
`INSERT INTO user_roles (user_id, role_id)
SELECT $1, id FROM roles WHERE name = 'user'`,
[id],
);
return { id, username };
}
test.afterAll(async () => {
if (createdUserIds.length > 0) {
await pool.query(`DELETE FROM notes WHERE user_id = ANY($1::int[])`, [
createdUserIds,
]);
await pool.query(`DELETE FROM user_roles WHERE user_id = ANY($1::int[])`, [
createdUserIds,
]);
await pool.query(`DELETE FROM users WHERE id = ANY($1::int[])`, [
createdUserIds,
]);
}
await pool.end();
});
async function loginViaUi(page, username) {
await page.goto("/login");
await page.locator("#username").fill(username);
await page.locator("#password").fill(TEST_PASSWORD);
await Promise.all([
page.waitForURL((url) => !url.pathname.endsWith("/login"), {
timeout: 15_000,
}),
page.locator('form button[type="submit"]').click(),
]);
}
test("composer persists chosen color when saving via outside click", async ({
page,
}) => {
const user = await createUser("notes_color_e2e", "Color Tester");
await loginViaUi(page, user.username);
await page.goto("/notes");
await expect(page.getByTestId("notes-page")).toBeVisible();
// Open the composer and type some content.
const content = `color-test ${uniq()}`;
await page.getByTestId("notes-composer").click();
await page.getByTestId("notes-composer-content").fill(content);
// Open the color popover and pick a non-default swatch.
await page
.getByTestId("notes-composer")
.locator('button[aria-label="Color"]')
.click();
// NOTE_COLORS[1] is the first non-default swatch ("red"); use it as the
// target. The swatch button has aria-label set to its color id.
const swatch = page.locator('[role="dialog"] button[aria-label="red"]')
.or(page.locator('button[aria-label="red"]'));
await swatch.first().click();
// Click far outside the composer to trigger auto-save.
const savePromise = page.waitForResponse(
(r) =>
new URL(r.url()).pathname === "/api/notes" &&
r.request().method() === "POST" &&
r.status() >= 200 &&
r.status() < 300,
);
await page.mouse.click(10, 10);
const resp = await savePromise;
const note = await resp.json();
expect(note.content).toBe(content);
expect(note.color).toBe("red");
});