From 8cc06d4e75e445a47b5289a633c8e96be2c0c467 Mon Sep 17 00:00:00 2001 From: Hera Zhao Date: Sat, 18 Apr 2026 18:20:27 +0000 Subject: [PATCH] =?UTF-8?q?test(e2e):=20=E6=89=8B=E6=9C=BA=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E9=85=8D=E6=96=B9=20overlay=20=E5=AE=BD=E5=BA=A6=20+?= =?UTF-8?q?=20swipe=20=E5=B1=8F=E8=94=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 responsive.cy.js 里的 Mobile edit recipe overlay 块,覆盖: - overlay-panel 无横向溢出 - 成分/用量/单价/小计 4 列 header 都在 panel 内 - 精油搜索输入不会撑出 panel 右边 - editor 打开时模拟横向 swipe,当前 tab 不切换 --- frontend/cypress/e2e/responsive.cy.js | 69 +++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/frontend/cypress/e2e/responsive.cy.js b/frontend/cypress/e2e/responsive.cy.js index 8cc5689..04efa25 100644 --- a/frontend/cypress/e2e/responsive.cy.js +++ b/frontend/cypress/e2e/responsive.cy.js @@ -39,6 +39,75 @@ describe('Responsive Design', () => { }) }) + describe('Mobile edit recipe overlay (375x667)', () => { + let adminToken + + before(() => { + cy.getAdminToken().then(token => { adminToken = token }) + }) + + beforeEach(() => { + cy.viewport(375, 667) + cy.visit('/manage', { + onBeforeLoad(win) { + win.localStorage.setItem('oil_auth_token', adminToken) + } + }) + cy.get('.recipe-manager', { timeout: 10000 }).should('exist') + cy.contains('公共配方库', { timeout: 10000 }).should('be.visible').click() + cy.get('.recipe-row', { timeout: 10000 }).should('have.length.gte', 1) + cy.get('.recipe-row .row-info').first().click() + cy.get('.overlay-panel', { timeout: 5000 }).should('be.visible') + }) + + it('editor table fits within panel without horizontal overflow', () => { + cy.get('.overlay-panel').then($panel => { + const panel = $panel[0] + expect(panel.scrollWidth, 'panel has no horizontal overflow') + .to.be.lte(panel.clientWidth + 1) + }) + cy.get('.overlay-panel .editor-table').then($table => { + const tableRect = $table[0].getBoundingClientRect() + const panelRect = Cypress.$('.overlay-panel')[0].getBoundingClientRect() + expect(tableRect.right, 'table right edge').to.be.lte(panelRect.right + 1) + expect(tableRect.left, 'table left edge').to.be.gte(panelRect.left - 1) + }) + }) + + it('all 4 data column headers (成分/用量/单价/小计) are visible in panel', () => { + const headers = ['成分', '用量', '单价', '小计'] + headers.forEach(label => { + cy.get('.overlay-panel .editor-table thead th').contains(label).then($th => { + const thRect = $th[0].getBoundingClientRect() + const panelRect = Cypress.$('.overlay-panel')[0].getBoundingClientRect() + expect(thRect.right, `${label} header right`).to.be.lte(panelRect.right + 1) + expect(thRect.left, `${label} header left`).to.be.gte(panelRect.left - 1) + }) + }) + }) + + it('oil search input does not push the row past panel edge', () => { + cy.get('.overlay-panel .form-select').first().then($input => { + const inputRect = $input[0].getBoundingClientRect() + const panelRect = Cypress.$('.overlay-panel')[0].getBoundingClientRect() + expect(inputRect.right, 'oil input right').to.be.lte(panelRect.right + 1) + }) + }) + + it('horizontal swipe does not switch tabs while editor overlay is open', () => { + cy.get('.nav-tab.active').invoke('text').then(activeBefore => { + // Overlay covers .main — touch events bubble from .overlay up to .main's handler + cy.get('.overlay') + .trigger('touchstart', { touches: [{ clientX: 320, clientY: 400 }], force: true }) + .trigger('touchmove', { touches: [{ clientX: 60, clientY: 400 }], force: true }) + .trigger('touchend', { force: true }) + cy.wait(200) + cy.get('.overlay-panel').should('be.visible') + cy.get('.nav-tab.active').invoke('text').should('eq', activeBefore) + }) + }) + }) + describe('Tablet viewport (768x1024)', () => { beforeEach(() => { cy.viewport(768, 1024)