describe('Authentication Flow', () => { let adminToken let adminUsername before(() => { cy.getAdminToken().then(token => { adminToken = token cy.request({ url: '/api/me', headers: { Authorization: `Bearer ${token}` } }).then(res => { adminUsername = res.body.username }) }) }) it('shows login button when not authenticated', () => { cy.visit('/') cy.contains('登录').should('be.visible') }) it('opens login modal when clicking login', () => { cy.visit('/') cy.contains('登录').click() cy.get('[class*="overlay"], [class*="modal"], [class*="login"]').should('be.visible') }) it('login modal has username and password fields', () => { cy.visit('/') cy.contains('登录').click() cy.get('input[placeholder*="用户名"], input[type="text"]').should('exist') cy.get('input[type="password"]').should('exist') }) it('shows error for invalid login', () => { cy.visit('/') cy.contains('登录').click() cy.get('input[placeholder*="用户名"], input[type="text"]').first().type('nonexistent_user_xyz') cy.get('input[type="password"]').first().type('wrongpassword') cy.contains('button', /登录|确定|提交/).click() cy.wait(1000) // The modal should still be visible (login failed) cy.get('[class*="overlay"], [class*="modal"], [class*="login"]').should('exist') }) it('authenticated user sees their name in header', () => { cy.visit('/', { onBeforeLoad(win) { win.localStorage.setItem('oil_auth_token', adminToken) } }) cy.get('.app-header', { timeout: 8000 }).should('be.visible') cy.get('.user-name', { timeout: 8000 }).should('be.visible') }) it('logout clears auth and shows login button', () => { cy.visit('/', { onBeforeLoad(win) { win.localStorage.setItem('oil_auth_token', adminToken) } }) cy.get('.user-name', { timeout: 8000 }).should('be.visible') // Click user name to open menu cy.get('.user-name').click() // Click logout cy.contains(/退出|登出|logout/i).click() // Should show login button again cy.contains('登录', { timeout: 5000 }).should('be.visible') }) it('protected tabs become accessible after login', () => { cy.visit('/', { onBeforeLoad(win) { win.localStorage.setItem('oil_auth_token', adminToken) } }) cy.get('.nav-tab', { timeout: 10000 }).should('have.length.gte', 3) cy.get('.nav-tab').contains('管理配方').click() // Should navigate to manage page, not show login modal cy.url().should('include', '/manage') }) })