Add 5 new Garmin E2E tests for expiry warnings and lifecycle
All checks were successful
Deploy / deploy (push) Successful in 1m39s

New tests:
- Yellow warning banner when token expires in 10 days (warning level)
- Red critical banner when token expires in 5 days (critical level)
- Expired token state shows token input for re-entry
- Connection persists after page reload
- Can reconnect after disconnecting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-13 18:20:42 +00:00
parent b3c711b9af
commit 5bfe51d630
2 changed files with 185 additions and 3 deletions

View File

@@ -187,5 +187,186 @@ test.describe("garmin connection", () => {
const expiryText = page.getByText(/\d+ days/i);
await expect(expiryText).toBeVisible();
});
test("shows yellow warning banner when token expires in 10 days", async ({
page,
}) => {
// Connect with tokens expiring in 10 days (warning level: 8-14 days)
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + 10);
const validTokens = JSON.stringify({
oauth1: { token: "test-token-warning", secret: "test-secret" },
oauth2: { access_token: "test-access-token" },
expires_at: expiresAt.toISOString(),
});
const tokenInput = page.locator("#tokenInput");
await tokenInput.fill(validTokens);
await page.getByRole("button", { name: /save tokens/i }).click();
// Wait for connected state
await expect(page.getByText("Connected", { exact: true })).toBeVisible({
timeout: 10000,
});
// Should show warning banner with yellow styling
const warningBanner = page.getByTestId("expiry-warning");
await expect(warningBanner).toBeVisible();
await expect(warningBanner).toContainText("Token expiring soon");
// Verify yellow warning styling (not red critical)
await expect(warningBanner).toHaveClass(/bg-yellow/);
});
test("shows red critical banner when token expires in 5 days", async ({
page,
}) => {
// Connect with tokens expiring in 5 days (critical level: <= 7 days)
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + 5);
const validTokens = JSON.stringify({
oauth1: { token: "test-token-critical", secret: "test-secret" },
oauth2: { access_token: "test-access-token" },
expires_at: expiresAt.toISOString(),
});
const tokenInput = page.locator("#tokenInput");
await tokenInput.fill(validTokens);
await page.getByRole("button", { name: /save tokens/i }).click();
// Wait for connected state
await expect(page.getByText("Connected", { exact: true })).toBeVisible({
timeout: 10000,
});
// Should show critical banner with red styling
const warningBanner = page.getByTestId("expiry-warning");
await expect(warningBanner).toBeVisible();
await expect(warningBanner).toContainText("Token expires soon!");
// Verify red critical styling
await expect(warningBanner).toHaveClass(/bg-red/);
});
test("shows expired state with token input when tokens have expired", async ({
page,
}) => {
// Connect with tokens that expire yesterday (already expired)
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() - 1);
const validTokens = JSON.stringify({
oauth1: { token: "test-token-expired", secret: "test-secret" },
oauth2: { access_token: "test-access-token" },
expires_at: expiresAt.toISOString(),
});
const tokenInput = page.locator("#tokenInput");
await tokenInput.fill(validTokens);
await page.getByRole("button", { name: /save tokens/i }).click();
// Wait for save to complete
await page.waitForTimeout(1000);
// Should show expired state
const expiredText = page.getByText("Token Expired");
await expect(expiredText).toBeVisible({ timeout: 10000 });
// Token input should be visible to allow re-entry
await expect(page.locator("#tokenInput")).toBeVisible();
// Red indicator should be visible
const redIndicator = page.locator(".bg-red-500").first();
await expect(redIndicator).toBeVisible();
});
test("connection persists after page reload", async ({ page }) => {
// First connect with valid tokens
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + 60);
const validTokens = JSON.stringify({
oauth1: { token: "test-token-persist", secret: "test-secret" },
oauth2: { access_token: "test-access-token" },
expires_at: expiresAt.toISOString(),
});
const tokenInput = page.locator("#tokenInput");
await tokenInput.fill(validTokens);
await page.getByRole("button", { name: /save tokens/i }).click();
// Wait for connected state
await expect(page.getByText("Connected", { exact: true })).toBeVisible({
timeout: 10000,
});
// Reload the page
await page.reload();
await page.waitForLoadState("networkidle");
// Should still show connected state
await expect(page.getByText("Connected", { exact: true })).toBeVisible({
timeout: 10000,
});
// Green indicator should still be visible
const greenIndicator = page.locator(".bg-green-500").first();
await expect(greenIndicator).toBeVisible();
});
test("can reconnect after disconnecting", async ({ page }) => {
// First connect
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + 30);
const validTokens = JSON.stringify({
oauth1: { token: "test-token-reconnect", secret: "test-secret" },
oauth2: { access_token: "test-access-token" },
expires_at: expiresAt.toISOString(),
});
const tokenInput = page.locator("#tokenInput");
await tokenInput.fill(validTokens);
await page.getByRole("button", { name: /save tokens/i }).click();
// Wait for connected state
await expect(page.getByText("Connected", { exact: true })).toBeVisible({
timeout: 10000,
});
// Disconnect
await page.getByRole("button", { name: /disconnect/i }).click();
await expect(page.getByText(/not connected/i)).toBeVisible({
timeout: 10000,
});
// Reconnect with new tokens
const newExpiresAt = new Date();
newExpiresAt.setDate(newExpiresAt.getDate() + 90);
const newTokens = JSON.stringify({
oauth1: {
token: "test-token-reconnect-new",
secret: "test-secret-new",
},
oauth2: { access_token: "test-access-token-new" },
expires_at: newExpiresAt.toISOString(),
});
const newTokenInput = page.locator("#tokenInput");
await newTokenInput.fill(newTokens);
await page.getByRole("button", { name: /save tokens/i }).click();
// Wait for reconnection
await expect(page.getByText("Connected", { exact: true })).toBeVisible({
timeout: 10000,
});
// Green indicator should be visible
const greenIndicator = page.locator(".bg-green-500").first();
await expect(greenIndicator).toBeVisible();
});
});
});