/// Cypress.env("AUTO_LOGIN", false); describe("sign-in page", () => { after(() => { Cypress.env("AUTO_LOGIN", true); }); beforeEach(() => { cy.clearCookies(); cy.clearLocalStorage(); cy.intercept("POST", "**/api/proxy/profile/login*", (req) => { req.reply({ delay: 2500, statusCode: 200, body: { success: true, message: "ok", data: { access_token: "e2e-access-token", refresh_token: "e2e-refresh-token", expires_at: Date.now() + 60_000, user: { id: "507f1f77bcf86cd799439011", username: "tester", email: "tester@example.com", role: "admin", }, }, }, }); }).as("loginRequest"); cy.visit("/auth/sign-in"); cy.location("pathname").should("eq", "/auth/sign-in"); }); it("keeps the sign-in box centered and visible in viewport", () => { cy.get("div[class*='max-w-'][class*='shadow-theme-xs'][class*='rounded-2xl']") .first() .should("be.visible") .then(($card) => { const rect = $card[0].getBoundingClientRect(); cy.window().then((win) => { const viewportCenterX = win.innerWidth / 2; const viewportCenterY = win.innerHeight / 2; const cardCenterX = rect.left + rect.width / 2; const cardCenterY = rect.top + rect.height / 2; expect(rect.top).to.be.gte(0); expect(rect.left).to.be.gte(0); expect(rect.bottom).to.be.lte(win.innerHeight); expect(rect.right).to.be.lte(win.innerWidth); expect(Math.abs(cardCenterX - viewportCenterX)).to.be.lessThan(80); expect(Math.abs(cardCenterY - viewportCenterY)).to.be.lessThan(100); }); }); }); it("toggles theme correctly", () => { cy.get("html").should("not.have.class", "dark"); cy.contains("button", "Switch to dark mode").click(); cy.get("html").should("have.class", "dark"); cy.contains("button", "Switch to light mode").click(); cy.get("html").should("not.have.class", "dark"); }); it("shows required errors under each field and does not call login API", () => { cy.contains('button[type="submit"]', "Sign in").click(); cy.get("p.text-red") .should("have.length", 2) .each(($message) => { expect($message.text().trim()).to.eq("This field is required"); }); cy.get("@loginRequest.all").should("have.length", 0); }); it("shows and hides password value when lock icon is clicked", () => { cy.get('input[name="password"]').as("passwordInput"); cy.get("@passwordInput").should("have.attr", "type", "password"); cy.get('button[aria-label="Show password"]').click(); cy.get("@passwordInput").should("have.attr", "type", "text"); cy.get('button[aria-label="Hide password"]').click(); cy.get("@passwordInput").should("have.attr", "type", "password"); }); it("shows default button text first, then spinner while submitting", () => { cy.contains('button[type="submit"]', "Sign in") .as("submitButton") .should("be.visible") .and("not.be.disabled"); cy.get('input[name="username"]').type("tester"); cy.get('input[name="password"]').type("Secret123!"); cy.get("@submitButton").click(); cy.get('button[type="submit"]') .find("div.animate-spin", { timeout: 10000 }) .should("exist"); cy.get('button[type="submit"]').should("not.contain", "Sign in"); }); });