import { expect, test } from "@playwright/test"; import { readFile } from "node:fs/promises"; const apiUrl = "http://localhost:5302/api"; test("CSV export has safe cells and headers, and browser download preserves its UTF-8 bytes", async ({ page }) => { await page.addInitScript(() => window.localStorage.setItem("uiLanguage", "en")); expect((await page.request.post(`${apiUrl}/auth/login`, { data: { email: "e2e@example.test", password: "E2ePassword123!" } })).status()).toBe(200); const me = await (await page.request.get(`${apiUrl}/auth/me`)).json(); const csrf = (await page.context().cookies()).find(cookie => cookie.name === "XSRF-TOKEN")!.value; const headers = { "X-CSRF-TOKEN": csrf, "X-Session-Context": me.sessionContext }; const companyName = `B05 Ærlig Økonomi Ås ${Date.now()}`; const createdCompany = await page.request.post(`${apiUrl}/companies`, { headers, data: { name: companyName } }); expect(createdCompany.status()).toBe(201); const company = await createdCompany.json(); const createdJob = await page.request.post(`${apiUrl}/jobapplications`, { headers, data: { companyId: company.id, jobTitle: "=1+1", status: "Saved", notes: " \t+SUM(1,2)\r\næøå" }, }); expect(createdJob.status()).toBe(201); const job = await createdJob.json(); const response = await page.request.get(`${apiUrl}/export/jobs?format=csv`); expect(response.status()).toBe(200); expect(response.headers()["content-type"]).toBe("text/csv; charset=utf-8"); expect(response.headers()["content-disposition"]).toMatch(/^attachment; filename=job-tracker-export-\d{4}-\d{2}-\d{2}\.csv;/); const bytes = await response.body(); expect([...bytes.subarray(0, 3)]).toEqual([0xef, 0xbb, 0xbf]); expect(bytes.toString("utf8")).toContain(`${companyName},,,'=1+1,Saved,`); expect(bytes.toString("utf8")).toContain('"\' \t+SUM(1,2)\r\næøå"'); const raw = await (await page.request.get(`${apiUrl}/export/jobs?format=json`)).json(); expect(raw.find((item: { Id: number }) => item.Id === job.id)).toMatchObject({ JobTitle: "=1+1", Notes: " \t+SUM(1,2)\r\næøå" }); await page.goto("/settings"); const pending = page.waitForEvent("download"); await page.getByRole("button", { name: "Export CSV", exact: true }).click(); const download = await pending; expect(download.suggestedFilename()).toMatch(/^job-tracker-export-\d{4}-\d{2}-\d{2}\.csv$/); expect(await readFile((await download.path())!)).toEqual(bytes); });