// Ignore uncaught exceptions from the Vue app during E2E tests. Cypress.on('uncaught:exception', () => false) // Login as planner user by injecting session into localStorage Cypress.Commands.add('loginAsPlanner', (password = '123456') => { // Hash the password and call login API cy.window().then(async (win) => { const buf = await win.crypto.subtle.digest('SHA-256', new TextEncoder().encode(password)) const hash = Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('') cy.request('POST', '/api/login', { hash }).then(() => { win.localStorage.setItem('sp_login_expires', String(Date.now() + 7 * 86400000)) }) }) }) // Inject planner login session directly (skip API call) Cypress.Commands.add('injectSession', () => { cy.window().then(win => { win.localStorage.setItem('sp_login_expires', String(Date.now() + 7 * 86400000)) }) }) // Navigate via tab button Cypress.Commands.add('goToTab', (label) => { cy.get('.tab-btn').contains(label).click() }) // Verify toast message appears Cypress.Commands.add('expectToast', (text) => { cy.get('.toast').should('contain', text) })