Files
ntfy/web/e2e/env.js
binwiederhier d7013703c1 Add Playwright end-to-end tests for the web app
Adds 56 Playwright tests in web/e2e/ that drive Chromium against a real
ntfy server: subscribing, publishing, notifications, signup/login/logout,
account settings, access tokens, reservations and languages. "make web-e2e"
builds the binary and runs them against a fresh local server; setting
NTFY_E2E_BASE_URL (plus an admin token and tier) runs them against an
existing server instead. docs/develop.md describes both.

The tests found two bugs, fixed here:

- Signup showed "Username is already taken" without the name, since it
  read the username from the error instead of the form.
- A poll that overlapped a WebSocket delivery could overwrite the stored
  message and drop its unread marker, or log a ConstraintError. Both
  write paths in SubscriptionManager now check and write in one
  transaction, and the poller skips messages that are already stored.
2026-10-07 17:26:35 +00:00

25 lines
1.2 KiB
JavaScript

import path from "node:path";
// Shared by the config and the specs, so both agree on which server to test.
//
// By default, a throwaway local server is started from build/ntfy-e2e (see server.mjs and
// "make web-e2e"). To test an existing server instead, set NTFY_E2E_BASE_URL, plus
// NTFY_E2E_ADMIN_TOKEN (to create and delete test users) and NTFY_E2E_TIER (code of an
// existing tier with reservations).
const root = path.resolve(__dirname, "../..");
export const remote = !!process.env.NTFY_E2E_BASE_URL;
export const port = 12586;
export const baseURL = process.env.NTFY_E2E_BASE_URL || `http://127.0.0.1:${port}`;
export const binary = path.join(root, "build", "ntfy-e2e");
export const configFile = path.join(root, "build", "e2e", "server.yml");
export const localTier = "e2e";
export const password = "secret12345";
// Read lazily: for the local server, Playwright sets this once server.mjs reports it
export const adminToken = () => process.env.NTFY_E2E_ADMIN_TOKEN;
export const tier = () => (remote ? process.env.NTFY_E2E_TIER : localTier);
// Random suffix so specs never share topics or users, even across reruns.
export const unique = (prefix) => `${prefix}${Math.random().toString(36).slice(2, 10)}`;