import { test, expect } from "@playwright/test";
import { submitLoginWithThrottle } from "./auth";
test.setTimeout(90000);

test("documented demo administrator can sign in", async ({ page }) => {
    await submitLoginWithThrottle(page, async () => {
        await page
            .getByLabel("Email address", { exact: true })
            .fill("admin@school.test");
        await page
            .getByLabel("Password", { exact: true })
            .fill("SchoolDemo2026!");
    });
    await expect(page).toHaveURL("http://127.0.0.1:8098/");
    await expect(
        page.getByRole("heading", { name: "School overview", exact: true }),
    ).toBeVisible();
});

test("login rejects an incorrect autofilled password even when input state has valid credentials", async ({
    page,
}) => {
    await submitLoginWithThrottle(
        page,
        async () => {
            await page
                .getByLabel("Email address", { exact: true })
                .fill("admin@school.test");
            const password = page.getByLabel("Password", { exact: true });
            await password.fill("SchoolDemo2026!");
            await password.evaluate((input) => {
                Object.getOwnPropertyDescriptor(
                    HTMLInputElement.prototype,
                    "value",
                )?.set?.call(input, "AnIncorrectPassword2026");
            });
        },
        true,
    );
    await expect(page.getByRole("alert")).toContainText(
        "The email or password is incorrect",
    );
    await expect(page).toHaveURL("http://127.0.0.1:8098/login");
});

test("login submits the current autofilled password rather than stale input state", async ({
    page,
}) => {
    await submitLoginWithThrottle(
        page,
        async () => {
            await page
                .getByLabel("Email address", { exact: true })
                .fill("admin@school.test");
            const password = page.getByLabel("Password", { exact: true });
            await password.fill("AnOldSavedPassword2026");
            // Password managers can set the native input value without a React change event.
            await password.evaluate((input, value) => {
                const setter = Object.getOwnPropertyDescriptor(
                    HTMLInputElement.prototype,
                    "value",
                )?.set;
                setter?.call(input, value);
            }, "SchoolDemo2026!");
            await expect(password).toHaveValue("SchoolDemo2026!");
        },
        true,
    );
    await expect(page).toHaveURL("http://127.0.0.1:8098/", { timeout: 3000 });
});
