refactor(loading, auth, status): enhance UI components for improved aesthetics and functionality

- Redesigned Loading component to feature a full-screen loader with animated elements for a modern look.
- Updated SigninWithPassword component to include error handling and improved password visibility toggle.
- Refactored Status component to utilize a tone-based styling system for better visual feedback based on status types.
This commit is contained in:
AmirReza Jamali
2026-04-25 12:35:03 +03:30
parent f195bba03d
commit 2a4f3e7e4b
5 changed files with 350 additions and 52 deletions
+109
View File
@@ -0,0 +1,109 @@
/// <reference types="cypress" />
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");
});
});