Compare commits
4 Commits
main
...
fix/mobile
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b495794c0 | |||
| 8cc06d4e75 | |||
| 2a2b1b8928 | |||
| dacd4887aa |
@@ -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)
|
||||
|
||||
@@ -196,7 +196,7 @@ function onSwipeEnd() {
|
||||
// Carousel area excluded
|
||||
if (swipeStartTarget.value?.closest?.('[data-no-tab-swipe]')) return
|
||||
// Skip when modal/overlay is open
|
||||
if (document.querySelector('.modal-overlay, .detail-overlay, .dialog-overlay')) return
|
||||
if (document.querySelector('.modal-overlay, .detail-overlay, .dialog-overlay, .overlay')) return
|
||||
|
||||
const tabs = visibleTabs.value.map(t => t.key)
|
||||
const currentIdx = tabs.indexOf(ui.currentSection)
|
||||
|
||||
@@ -2307,6 +2307,9 @@ watch(() => recipeStore.recipes, () => {
|
||||
|
||||
.form-select {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 10px;
|
||||
border: 1.5px solid #d4cfc7;
|
||||
border-radius: 8px;
|
||||
@@ -2328,6 +2331,7 @@ watch(() => recipeStore.recipes, () => {
|
||||
|
||||
.oil-search-wrap {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -2483,5 +2487,22 @@ watch(() => recipeStore.recipes, () => {
|
||||
.manage-toolbar {
|
||||
flex-direction: column;
|
||||
}
|
||||
.overlay-panel {
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
max-height: calc(100vh - 32px);
|
||||
}
|
||||
.overlay-header {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.overlay-header h3 {
|
||||
font-size: 15px;
|
||||
}
|
||||
.ratio-hint {
|
||||
white-space: normal;
|
||||
}
|
||||
.editor-section {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user