Some checks failed
- Backend: FastAPI + SQLite (WAL mode), 22 tables, ~40 API endpoints - Frontend: Vue 3 + Vite + Pinia + Vue Router, 8 views, 3 stores - Database: migrate from JSON file to SQLite with proper schema - Dockerfile: multi-stage build (node + python) - Deploy: K8s manifests (namespace, deployment, service, ingress, pvc, backup) - CI/CD: Gitea Actions (test, deploy, PR preview at pr-$id.planner.oci.euphon.net) - Tests: 20 Cypress E2E test files, 196 test cases, ~85% coverage - Doc: test-coverage.md with full feature coverage report Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
141 lines
5.5 KiB
JavaScript
141 lines
5.5 KiB
JavaScript
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()
|
|
})
|
|
})
|