describe('Tasks (待办)', () => { beforeEach(() => { cy.visit('/tasks', { onBeforeLoad(win) { win.localStorage.setItem('sp_login_expires', String(Date.now() + 86400000)) } }) cy.get('header').should('be.visible') }) // ---- Sub tabs ---- it('shows sub tabs: 待办, 目标, 清单', () => { cy.get('.sub-tab').should('have.length', 3) cy.get('.sub-tab').eq(0).should('contain', '待办') cy.get('.sub-tab').eq(1).should('contain', '目标') cy.get('.sub-tab').eq(2).should('contain', '清单') }) it('defaults to 待办 sub tab', () => { cy.get('.sub-tab').contains('待办').should('have.class', 'active') }) it('switches between sub tabs', () => { cy.get('.sub-tab').contains('目标').click() cy.get('.sub-tab').contains('目标').should('have.class', 'active') cy.get('.sub-tab').contains('清单').click() cy.get('.sub-tab').contains('清单').should('have.class', 'active') }) // ---- Inbox ---- it('shows inbox input', () => { cy.get('.inbox-card').should('be.visible') cy.get('.inbox-card .capture-input').should('be.visible') }) it('adds item to inbox', () => { cy.get('.inbox-card .capture-input').type('收集箱测试') cy.get('.inbox-card .capture-btn').click() cy.get('.inbox-item').should('contain', '收集箱测试') }) it('inbox item has quadrant assignment buttons', () => { cy.get('.inbox-card .capture-input').type('分类测试') cy.get('.inbox-card .capture-btn').click() cy.get('.inbox-item-actions button').should('have.length.gte', 4) }) it('moves inbox item to quadrant', () => { cy.get('.inbox-card .capture-input').type('移入q1') cy.get('.inbox-card .capture-btn').click() // Click 🔴 (q1 - urgent important) cy.get('.inbox-item').contains('移入q1').parent().find('.inbox-item-actions button').first().click() cy.get('.inbox-item').should('not.contain', '移入q1') cy.get('.todo-item').should('contain', '移入q1') }) // ---- Quadrants ---- it('shows 4 quadrants', () => { cy.get('.quadrant').should('have.length', 4) cy.get('.q-urgent-important').should('contain', '紧急且重要') cy.get('.q-important').should('contain', '重要不紧急') cy.get('.q-urgent').should('contain', '紧急不重要') cy.get('.q-neither').should('contain', '不紧急不重要') }) it('adds todo directly to a quadrant', () => { cy.get('.q-urgent-important .add-todo-row input').type('直接添加任务{enter}') cy.get('.q-urgent-important .todo-item').should('contain', '直接添加任务') }) it('toggles todo completion', () => { cy.get('.q-important .add-todo-row input').type('完成测试{enter}') cy.get('.q-important .todo-item').contains('完成测试').parent().find('input[type="checkbox"]').check() // Enable "show done" to verify cy.get('#todoShowDone, .toggle-label input').check() cy.get('.todo-item').contains('完成测试').parent().find('span.done').should('exist') }) it('deletes a todo', () => { cy.get('.q-neither .add-todo-row input').type('待删除todo{enter}') cy.get('.todo-item').contains('待删除todo').parent().find('.remove-btn').click() cy.get('.todo-item').should('not.contain', '待删除todo') }) it('search filters todos', () => { cy.get('.q-urgent-important .add-todo-row input').type('搜索目标A{enter}') cy.get('.q-important .add-todo-row input').type('搜索目标B{enter}') cy.get('.search-input').type('目标A') cy.get('.todo-item').should('have.length', 1) cy.get('.todo-item').should('contain', '搜索目标A') }) // ---- Goals ---- it('creates a goal', () => { cy.get('.sub-tab').contains('目标').click() cy.get('.btn-accent').contains('新目标').click() cy.get('.edit-form input').first().type('减肥5斤') cy.get('.edit-form input[type="month"]').type('2026-06') cy.get('.btn-accent').contains('保存').click() cy.get('.goal-card').should('contain', '减肥5斤') }) it('deletes a goal', () => { cy.get('.sub-tab').contains('目标').click() cy.get('.btn-accent').contains('新目标').click() cy.get('.edit-form input').first().type('待删除目标') cy.get('.btn-accent').contains('保存').click() cy.get('.goal-card').contains('待删除目标').parent().find('.remove-btn').click() cy.get('.goal-card').should('not.contain', '待删除目标') }) // ---- Checklists ---- it('creates a checklist', () => { cy.get('.sub-tab').contains('清单').click() cy.get('.btn-accent').contains('新清单').click() cy.get('.checklist-card').should('exist') }) it('adds items to checklist', () => { cy.get('.sub-tab').contains('清单').click() cy.get('.btn-accent').contains('新清单').click() cy.get('.checklist-card .add-todo-row input').first().type('清单项目1{enter}') cy.get('.checklist-item').should('contain', '清单项目1') }) it('toggles checklist item', () => { cy.get('.sub-tab').contains('清单').click() cy.get('.btn-accent').contains('新清单').click() cy.get('.checklist-card .add-todo-row input').first().type('打勾测试{enter}') cy.get('.checklist-item').contains('打勾测试').parent().find('input[type="checkbox"]').check() cy.get('.checklist-item').contains('打勾测试').should('have.class', 'done') }) it('deletes a checklist', () => { cy.get('.sub-tab').contains('清单').click() cy.get('.btn-accent').contains('新清单').click() cy.get('.checklist-card').should('exist') cy.get('.checklist-header .remove-btn').first().click() }) })