This commit is contained in:
Louis Lam
2026-07-13 13:07:47 +08:00
parent 1b4dc81d14
commit 5f97cccee5
2 changed files with 32 additions and 48 deletions
+10 -48
View File
@@ -1,7 +1,11 @@
import { expect, test } from "@playwright/test";
import { login, screenshot } from "../util-test";
import { login, restoreSqliteSnapshot, screenshot } from "../util-test";
test.describe("Status Page", () => {
test.beforeEach(async ({ page }) => {
await restoreSqliteSnapshot(page);
});
test("create and edit", async ({ page }, testInfo) => {
test.setTimeout(60000); // Keep the timeout increase for stability
@@ -44,42 +48,16 @@ test.describe("Status Page", () => {
await page.getByTestId("tag-name-input").fill(tagName);
await page.getByTestId("tag-value-input").fill(tagValue);
await page.getByTestId("tag-color-select").click(); // Vue-Multiselect component
// DEBUG: Check for any overlays that could block the dropdown
const lostConnBanner = page.locator(".lost-connection");
console.log("DEBUG: lost-connection banner visible:", await lostConnBanner.isVisible().catch(() => false));
await screenshot(testInfo, page);
await page.getByTestId("tag-color-select").getByRole("option", { name: "Orange" }).click();
// DEBUG: Check if color was selected
const colorText = await page
.getByTestId("tag-color-select")
.textContent()
.catch(() => "N/A");
console.log("DEBUG: tag-color-select text after picking Orange:", colorText);
await screenshot(testInfo, page);
// DEBUG: Check button state before clicking
const addAnotherBtn = page.getByRole("button", { name: "Add Another Tag" });
const isDisabled = await addAnotherBtn.getAttribute("disabled");
console.log("DEBUG: 'Add Another Tag' button disabled attr:", isDisabled);
await screenshot(testInfo, page);
// Add another tag instead of submitting directly
await addAnotherBtn.click();
await page.getByRole("button", { name: "Add Another Tag" }).click();
// Add second tag
await page.getByTestId("tag-name-input").fill(tagName2);
await page.getByTestId("tag-value-input").fill(tagValue2);
await page.getByTestId("tag-color-select").click();
await page.getByTestId("tag-color-select").getByRole("option", { name: "Blue" }).click();
const colorText2 = await page
.getByTestId("tag-color-select")
.textContent()
.catch(() => "N/A");
console.log("DEBUG: tag-color-select text after picking Blue:", colorText2);
await screenshot(testInfo, page);
// Submit both tags
await page.getByTestId("add-tags-final-button").click();
@@ -147,20 +125,14 @@ test.describe("Status Page", () => {
await expect(page.getByTestId("monitor-name")).toHaveAttribute("href", monitorCustomUrl);
// TODO: no idea how to fix, after removed sqlite snapshot/restore feature
/* await expect(page.getByTestId("update-countdown-text")).toContainText("00:");
await expect(page.getByTestId("update-countdown-text")).toContainText("00:");
const updateCountdown = Number(
(await page.getByTestId("update-countdown-text").textContent()).match(/(\d+):(\d+)/)[2]
);
expect(updateCountdown).toBeGreaterThanOrEqual(refreshInterval - 10); // cant be certain when the timer will start, so ensure it's within expected range
expect(updateCountdown).toBeLessThanOrEqual(refreshInterval);*/
expect(updateCountdown).toBeLessThanOrEqual(refreshInterval);
// The status page navigates to public view after save
await page.waitForURL("/status/example");
// Wait for the status page theme to be applied to body
await page.waitForFunction((expectedTheme) => document.body.classList.contains(expectedTheme), theme, {
timeout: 10000,
});
await expect(page.locator("body")).toHaveClass(theme);
// Add Google Analytics ID to head and verify
await page.waitForFunction(
@@ -200,13 +172,6 @@ test.describe("Status Page", () => {
await screenshot(testInfo, page);
await page.waitForFunction(
(scriptUrl) => {
return document.head.innerHTML.includes(scriptUrl);
},
umamiAnalyticsScriptUrl,
{ timeout: 5000 }
);
expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsScriptUrl);
expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsWebsiteId);
@@ -343,11 +308,8 @@ test.describe("Status Page", () => {
await page.getByTestId("save-button").click();
await expect(page.getByTestId("edit-sidebar")).toHaveCount(0);
// Navigate to dashboard or anywhere to ensure any server-side cache is stale
await page.waitForTimeout(1000);
// Fetch RSS feed again - should use custom RSS title
const rssResponseCustom = await page.request.get("/status/security-test/rss?_t=" + Date.now());
const rssResponseCustom = await page.request.get("/status/security-test/rss");
expect(rssResponseCustom.status()).toBe(200);
const rssContentCustom = await rssResponseCustom.text();
+22
View File
@@ -1,6 +1,7 @@
const fs = require("fs");
const path = require("path");
const dbPath = "./../../data/playwright-test/kuma.db";
const serverUrl = require("../../config/playwright.config.js").url;
/**
* @param {TestInfo} testInfo Test info
@@ -37,3 +38,24 @@ export async function login(page) {
export function getSqliteDatabaseExists() {
return fs.existsSync(path.resolve(__dirname, dbPath));
}
/**
* Makes a request to the server to take a snapshot of the SQLite database.
* @param {Page|null} page Page
* @returns {Promise<Response>} Promise of response from snapshot request.
*/
export async function takeSqliteSnapshot(page = null) {
if (page) {
return page.goto("./_e2e/take-sqlite-snapshot");
} else {
return fetch(`${serverUrl}/_e2e/take-sqlite-snapshot`);
}
}
/**
* Makes a request to the server to restore the snapshot of the SQLite database.
* @returns {Promise<Response>} Promise of response from restoration request.
*/
export async function restoreSqliteSnapshot() {
return fetch(`${serverUrl}/_e2e/restore-sqlite-snapshot`);
}