This project automates an end-to-end flow in Cymulate:
- Login with credentials from
.env. - Navigate from Dashboard to Findings.
- Apply filter Module = BAS.
- Read the first row values (Finding Name, Timestamp, Status) from the UI.
- Select the row and Export.
- Download the CSV and verify the first row matches the UI.
- Page Object Model (POM): Clear separation of concerns.
LoginPage– resilient login with role/placeholder/type fallbacks and optional cookie banner handling.DashboardPage– post-login navigation to Findings.FindingsTablePage– owns table readiness, filter flow, select first row, export, and first-row reads.BasePage– shared helpers (goto,waitVisible,waitNetworkIdle,click,fill,text) and a scoped logger.
- Resilient selectors: Prefer
data-testidand ARIA roles; scope withhasTextwhere needed. - Header-aware access: Build a header→index map at runtime to avoid brittle column indices.
- Deterministic downloads:
prepareDownloadsDir()cleansdownloads/;saveNextDownload(page)waits + saves the file explicitly. - CSV parsing & normalization:
utils/report.tsparses the exported CSV, normalizes headers and cell text, and returns a typedFindingRowfor comparison. - Type safety & readability: Strict TypeScript, small utilities, and human-readable logging (
STEP/INFO/WARN/ERROR).
- Node.js 18+ (recommended)
- Playwright browsers installed
npm install
npx playwright install --with-depsCreate a .env file at the project root (a .env.example is provided):
BASE_URL=https://app.cymulate.com/cyn
CY_EMAIL=your_email@example.com # or CY_MAIL
CY_PASSWORD=your_password_here # or CY_PASSThe code accepts either CY_EMAIL/CY_PASSWORD or CY_MAIL/CY_PASS.
Headless (records video and trace):
npm testHeaded (interactive debug):
npm run test:headedOpen the HTML report:
npm run report- HTML report:
playwright-report/ - Videos/Traces/Screenshots:
test-results/(linked from the HTML report) - Exported CSV:
downloads/(cleaned per test run)
- Missing browsers:
npx playwright install - Env not loaded: ensure
.envsits next topackage.jsonand variables are set as above - Download not saved: ensure
saveNextDownload(page)is awaited after triggering Export