文件
OmniCard/mpuniapp/pages/template/swipe-card-stack/swipe-card-stack.test.js

270 行
8.2 KiB
JavaScript

jest.setTimeout(60000)
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
const isWeb = platformInfo.startsWith('web') || platformInfo.startsWith('h5')
const isMP = platformInfo.startsWith('mp')
const isHarmony = platformInfo.startsWith('harmony')
const isPad = process.env.UNI_AUTOMATOR_IS_PAD == 'true'
const PAGE_PATH = '/pages/template/swipe-card-stack/swipe-card-stack'
const WAIT_FOR_CARD_INIT = 800
const WAIT_FOR_DRAG_RENDER = 120
const WAIT_FOR_RELEASE = 800
describe('template-swipe-card-stack', () => {
// TODO: 小程序端待补充适配后放开。
if (isMP || (isHarmony && isPad)) {
it('skip', () => {
expect(1).toBe(1)
})
return
}
let page
let windowInfo
async function openPage() {
try {
page = await program.reLaunch(PAGE_PATH)
} catch (error) {
if (!isWeb) {
throw error
}
page = await program.currentPage()
}
await page.waitFor('.card')
await page.waitFor(WAIT_FOR_CARD_INIT)
}
async function getCards() {
const cards = await page.$$('.card')
expect(cards.length).toBe(3)
return cards
}
async function getCardInfos() {
const cards = await getCards()
const infos = []
for (let i = 0; i < cards.length; i++) {
const rect = await cards[i].offset()
const size = await cards[i].size()
infos.push({
card: cards[i],
index: i,
top: rect.top,
left: rect.left,
width: size.width,
height: size.height
})
}
return infos
}
async function getTopCardInfo() {
const infos = await getCardInfos()
infos.sort((a, b) => a.top - b.top)
return infos[0]
}
async function getBackCardInfo() {
const infos = await getCardInfos()
infos.sort((a, b) => b.top - a.top)
return infos[0]
}
async function getTopCardIndex() {
return (await getTopCardInfo()).index
}
function createTouch(x, y) {
const pointX = Math.round(x)
const pointY = Math.round(y)
return {
identifier: 1,
pageX: pointX,
pageY: pointY,
clientX: pointX,
clientY: pointY,
screenX: pointX,
screenY: pointY
}
}
function createTouchEvent(x, y, isEnd = false) {
const touch = createTouch(x, y)
return {
touches: isEnd ? [] : [touch],
changedTouches: [touch]
}
}
async function dragCard(cardInfo, offsetX, offsetY = 0, options = {}) {
const startX = cardInfo.left + cardInfo.width / 2
const startY = cardInfo.top + Math.min(220, cardInfo.height / 2)
const steps = options.steps || 4
const interval = options.interval || 80
await cardInfo.card.touchstart(createTouchEvent(startX, startY))
for (let i = 1; i <= steps; i++) {
const nextX = startX + offsetX * i / steps
const nextY = startY + offsetY * i / steps
await cardInfo.card.touchmove(createTouchEvent(nextX, nextY))
await page.waitFor(interval)
}
if (options.release !== false) {
await cardInfo.card.touchend(createTouchEvent(startX + offsetX, startY + offsetY, true))
await page.waitFor(WAIT_FOR_RELEASE)
}
return cardInfo.card
}
async function dragTopCard(offsetX, offsetY = 0, options = {}) {
return await dragCard(await getTopCardInfo(), offsetX, offsetY, options)
}
function getTransformTranslate(transform) {
const translateMatched = transform.match(/translate(?:3d)?\(\s*([-0-9.]+)px(?:\s*,\s*([-0-9.]+)px)?/)
if (translateMatched != null) {
return {
x: parseFloat(translateMatched[1] || '0'),
y: parseFloat(translateMatched[2] || '0')
}
}
const matrix3dMatched = transform.match(/matrix3d\(([^)]+)\)/)
if (matrix3dMatched != null) {
const matrixValues = matrix3dMatched[1].split(',').map((value) => parseFloat(value.trim()))
return {
x: matrixValues[12] || 0,
y: matrixValues[13] || 0
}
}
const matrixMatched = transform.match(/matrix\(([^)]+)\)/)
expect(matrixMatched).not.toBeNull()
const matrixValues = matrixMatched[1].split(',').map((value) => parseFloat(value.trim()))
return {
x: matrixValues[4] || 0,
y: matrixValues[5] || 0
}
}
function expectTransformMoved(transform) {
const translate = getTransformTranslate(transform)
expect(Math.abs(translate.x) + Math.abs(translate.y)).toBeGreaterThan(0)
}
async function expectCardIsDragging(card) {
await page.waitFor(WAIT_FOR_DRAG_RENDER)
const transform = await card.style('transform')
expectTransformMoved(transform)
}
async function expectCardDraggedBeyondSwitchThreshold(card, direction) {
await page.waitFor(WAIT_FOR_DRAG_RENDER)
const transform = await card.style('transform')
const translateX = getTransformTranslate(transform).x
const threshold = windowInfo.screenWidth / 10
if (direction > 0) {
expect(translateX).toBeGreaterThan(threshold)
} else {
expect(translateX).toBeLessThan(-threshold)
}
}
async function screenShot() {
const image = await program.screenshot({
fullPage: true
})
expect(image).toSaveImageSnapshot()
}
beforeAll(async () => {
windowInfo = await program.callUniMethod('getWindowInfo')
})
beforeEach(async () => {
await openPage()
})
it('renders card stack', async () => {
const cards = await getCards()
const images = await page.$$('.card-img')
expect(images.length).toBe(3)
for (let i = 0; i < cards.length; i++) {
const rect = await cards[i].offset()
const size = await cards[i].size()
expect(rect.left).toBeGreaterThanOrEqual(0)
expect(rect.top).toBeGreaterThanOrEqual(0)
expect(size.width).toBeGreaterThan(0)
expect(size.height).toBeGreaterThan(0)
}
})
it('does not move a back card when dragging behind the top card', async () => {
const backCardInfo = await getBackCardInfo()
const beforeTransform = await backCardInfo.card.style('transform')
await dragCard(backCardInfo, Math.round(windowInfo.screenWidth * 0.35), 0, { release: false })
expect(await backCardInfo.card.style('transform')).toBe(beforeTransform)
await screenShot()
})
it('keeps current card after a short drag and release', async () => {
const topCardIndexBefore = await getTopCardIndex()
const draggedCard = await dragTopCard(20, 0, { release: false })
await expectCardIsDragging(draggedCard)
await screenShot()
await draggedCard.touchend(createTouchEvent(windowInfo.screenWidth / 2 + 20, windowInfo.screenHeight / 2, true))
await page.waitFor(WAIT_FOR_RELEASE)
expect(await getTopCardIndex()).toBe(topCardIndexBefore)
expect((await getCards()).length).toBe(3)
})
it('right drag feedback screenshot', async () => {
const topCardIndexBefore = await getTopCardIndex()
const draggedCard = await dragTopCard(Math.round(windowInfo.screenWidth * 0.45), 0, { release: false })
await expectCardIsDragging(draggedCard)
await screenShot()
expect(await getTopCardIndex()).toBe(topCardIndexBefore)
expect((await getCards()).length).toBe(3)
})
it('right drag reaches switch threshold', async () => {
const topCardIndexBefore = await getTopCardIndex()
const draggedCard = await dragTopCard(Math.round(windowInfo.screenWidth * 0.45), 0, { release: false })
await expectCardDraggedBeyondSwitchThreshold(draggedCard, 1)
expect(await getTopCardIndex()).toBe(topCardIndexBefore)
expect((await getCards()).length).toBe(3)
})
it('left drag feedback screenshot', async () => {
const topCardIndexBefore = await getTopCardIndex()
const draggedCard = await dragTopCard(Math.round(windowInfo.screenWidth * -0.45), 0, { release: false })
await expectCardIsDragging(draggedCard)
await screenShot()
expect(await getTopCardIndex()).toBe(topCardIndexBefore)
expect((await getCards()).length).toBe(3)
})
it('left drag reaches switch threshold', async () => {
const topCardIndexBefore = await getTopCardIndex()
const draggedCard = await dragTopCard(Math.round(windowInfo.screenWidth * -0.45), 0, { release: false })
await expectCardDraggedBeyondSwitchThreshold(draggedCard, -1)
expect(await getTopCardIndex()).toBe(topCardIndexBefore)
expect((await getCards()).length).toBe(3)
})
})