Files
SnapOtter/tests/e2e-analytics/settings-analytics.spec.ts
T
SnapOtter fc8b549d78 fix: gate captureException on user consent and fix HEIC PII scrubbing
captureException now checks isRequestOptedIn before forwarding errors
to Sentry, closing a gap where server errors leaked to an external
service even when no user had consented. The PII scrubbing regex is
also fixed: he[ic]f? failed to match .heic due to word-boundary
behavior and is replaced with hei[cf]? which correctly covers .heic,
.heif, and .hei.

Adds 88 new analytics tests across unit, integration, and e2e layers
proving PostHog/Sentry are never invoked when analytics is disabled or
users have not consented, plus full 7-day reminder lifecycle coverage.
2026-04-29 23:47:19 +08:00

96 lines
3.9 KiB
TypeScript

import { expect, test } from "./helpers";
// These tests use the pre-authenticated storageState from auth.setup.ts
// where the user has already accepted analytics consent.
test.describe("Settings - Product Analytics Tab", () => {
test("Product Analytics nav item is visible in settings", async ({ loggedInPage: page }) => {
await page.locator("aside").getByText("Settings").click();
await expect(page.getByRole("button", { name: /product analytics/i })).toBeVisible({
timeout: 5_000,
});
});
test("clicking Product Analytics tab shows analytics section", async ({ loggedInPage: page }) => {
await page.locator("aside").getByText("Settings").click();
await page.getByRole("button", { name: /product analytics/i }).click();
// Should show the analytics description
await expect(page.getByText(/anonymous usage data/i)).toBeVisible({ timeout: 5_000 });
});
test("toggle shows enabled state after accepting consent", async ({ loggedInPage: page }) => {
await page.locator("aside").getByText("Settings").click();
await page.getByRole("button", { name: /product analytics/i }).click();
// Auth setup accepted consent, so toggle should show enabled
await expect(page.getByText(/analytics enabled/i)).toBeVisible({ timeout: 5_000 });
});
test("toggle off disables analytics", async ({ loggedInPage: page }) => {
await page.locator("aside").getByText("Settings").click();
await page.getByRole("button", { name: /product analytics/i }).click();
// Find and click the toggle button
const toggleButton = page.locator("button.rounded-full");
await toggleButton.click();
await expect(page.getByText(/analytics disabled/i)).toBeVisible({ timeout: 5_000 });
});
test("toggle on re-enables analytics", async ({ loggedInPage: page }) => {
await page.locator("aside").getByText("Settings").click();
await page.getByRole("button", { name: /product analytics/i }).click();
const toggleButton = page.locator("button.rounded-full");
// Ensure we're in disabled state first
const text = await page.getByText(/analytics (enabled|disabled)/i).textContent();
if (text?.toLowerCase().includes("enabled")) {
await toggleButton.click();
await expect(page.getByText(/analytics disabled/i)).toBeVisible({ timeout: 5_000 });
}
// Now toggle on
await toggleButton.click();
await expect(page.getByText(/analytics enabled/i)).toBeVisible({ timeout: 5_000 });
});
test("toggle state persists after closing and reopening settings", async ({
loggedInPage: page,
}) => {
// Open settings and disable analytics
await page.locator("aside").getByText("Settings").click();
await page.getByRole("button", { name: /product analytics/i }).click();
const toggleButton = page.locator("button.rounded-full");
// Ensure enabled, then disable
const text = await page.getByText(/analytics (enabled|disabled)/i).textContent();
if (text?.toLowerCase().includes("enabled")) {
await toggleButton.click();
await expect(page.getByText(/analytics disabled/i)).toBeVisible({ timeout: 5_000 });
}
// Close dialog
await page.keyboard.press("Escape");
await page.waitForTimeout(500);
// Reopen and check the state persisted
await page.locator("aside").getByText("Settings").click();
await page.getByRole("button", { name: /product analytics/i }).click();
await expect(page.getByText(/analytics disabled/i)).toBeVisible({ timeout: 5_000 });
// Re-enable for other tests
await toggleButton.click();
await expect(page.getByText(/analytics enabled/i)).toBeVisible({ timeout: 5_000 });
});
test("privacy policy link is present", async ({ loggedInPage: page }) => {
await page.locator("aside").getByText("Settings").click();
await page.getByRole("button", { name: /product analytics/i }).click();
await expect(page.getByText(/privacy/i)).toBeVisible({ timeout: 5_000 });
});
});