import { test, expect, type Page } from '@playwright/test'; async function login(page: Page) { await page.goto('/login/'); await page.fill('#lg-username', 'demo'); await page.fill('#lg-password', 'demo'); await page.click('button[type=submit]'); await expect(page.getByTestId('nav-menu')).toBeVisible(); } async function openCurveEditor(page: Page) { // The builder (and so the curve editor) is desktop-only. await page.setViewportSize({ width: 1400, height: 900 }); await login(page); // The curve editor is a leaf modal opened from a piecewise stage inside the // inline profile builder — never a standalone entry point (guidelines §6.4). await page.selectOption('#cp-profile', 'custom_profile'); await expect(page.getByTestId('profile-builder')).toBeVisible(); await page.getByTestId('stage-solver').first().selectOption('piecewise'); await page.getByTestId('stage-open-curve').click(); await expect(page.getByTestId('curve-modal')).toBeVisible(); } test('the curve editor imports CSV and applies the curve', async ({ page }) => { await openCurveEditor(page); await expect(page.getByTestId('curve-chart')).toBeVisible(); await page.getByTestId('curve-csv-toggle').click(); await page.getByTestId('curve-csv').fill('time_s,altitude_m,rate_ms\n0,0,0\n600,3000,5\n1200,9000,10'); await page.getByTestId('curve-csv-import').click(); // Three imported points, and the implied-rate readout follows them. await expect(page.getByTestId('curve-rows').locator('tr')).toHaveCount(3); await expect(page.getByTestId('curve-rates')).toContainText('5.00 m/s'); await expect(page.getByTestId('curve-rates')).toContainText('10.00 m/s'); await page.getByTestId('curve-apply').click(); await expect(page.getByTestId('curve-modal')).toHaveCount(0); // The applied curve is recorded on the stage (badge shows the point count). await expect(page.getByTestId('stage-open-curve')).toContainText('3'); }); test('a non-monotonic curve is flagged and cannot be applied', async ({ page }) => { await openCurveEditor(page); await page.getByTestId('curve-csv-toggle').click(); // Time goes backwards on the third row. await page.getByTestId('curve-csv').fill('0,0,0\n600,3000,5\n300,9000,10'); await page.getByTestId('curve-csv-import').click(); await expect(page.getByTestId('curve-problems')).toBeVisible(); await expect(page.getByTestId('curve-apply')).toBeDisabled(); });