test(dropdown): [dropdown] Optimize dropdown component e2e test cases (#930)

This commit is contained in:
MomoPoppy 2023-11-25 18:04:25 +08:00 committed by GitHub
parent c21f67f1ad
commit 9dc713243a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 285 additions and 63 deletions

View File

@ -4,21 +4,28 @@ test('基本用法', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#basic-usage')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = page.locator('body > .tiny-dropdown-menu > .tiny-dropdown-item')
const wrap = page.locator('#basic-usage')
const dropDown = wrap.locator('.tiny-dropdown')
console.log(dropDown)
const dropDownMenu = page.locator('body').locator('.my-class')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
const dropDownSvg = dropDown.locator('svg')
await expect(dropDown.locator('svg > path')).toHaveAttribute('d', 'M2 6h20L12 19z')
// 箭头是否存在
await expect(dropDownSvg).toBeVisible()
await expect(dropDownSvg.locator('path')).toHaveAttribute('d', 'M2 6h20L12 19z')
await page.waitForTimeout(500)
await dropDown.hover()
await expect(dropDownMenu).toBeVisible()
// 箭头是否变成向上
await expect(dropDown.locator('svg')).toHaveCSS('transform', 'matrix(-1, 0, 0, -1, 0, 0)')
await expect(dropDown.locator('.tiny-dropdown--visible')).toHaveCSS('transform', 'matrix(1, 0, 0, -1, 0, 0)')
await expect(dropDownMenuItem).toHaveCount(6)
await expect(dropDownMenuItem.filter({ hasText: '双皮奶' })).toHaveClass(/is-disabled/)
await expect(dropDownMenuItem.filter({ hasText: '双皮奶' })).toHaveCSS('cursor', 'not-allowed')
// 测试悬浮效果
await page.waitForTimeout(500)
await dropDownMenuItem.first().hover()
await expect(dropDownMenuItem.first()).toHaveCSS('color', 'rgb(82, 110, 204)')
await expect(dropDownMenuItem.first()).toHaveCSS('background-color', 'rgb(242, 245, 252)')

View File

@ -4,14 +4,58 @@ test('禁用下拉菜单', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#disabled')
const preview = page.locator('#preview')
const disabledDropDown = preview.locator('.tiny-dropdown').nth(1)
const wrap = page.locator('#disabled')
const disabledDropDown = wrap.locator('.tiny-dropdown').nth(0)
const dropDownTrigger = disabledDropDown.locator('.tiny-dropdown__trigger')
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
await expect(disabledDropDown.locator('.tiny-dropdown__trigger')).toHaveAttribute('disabled', 'true')
await expect(disabledDropDown.locator('.tiny-dropdown__trigger')).toHaveCSS('cursor', 'not-allowed')
await expect(disabledDropDown.locator('.tiny-dropdown__title')).toHaveCSS('color', 'rgb(173, 176, 184)')
await expect(dropDownTrigger).toHaveClass(/is-disabled/)
await expect(dropDownTrigger).toHaveCSS('cursor', 'not-allowed')
await expect(dropDownTrigger).toHaveCSS('color', 'rgb(173, 176, 184)')
await expect(disabledDropDown.locator('svg')).toHaveCSS('fill', 'rgb(173, 176, 184)')
await page.waitForTimeout(1200)
await disabledDropDown.hover()
await expect(dropDownMenu).not.toBeVisible()
})
test('按钮类型禁用', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#disabled')
const wrap = page.locator('#disabled')
const dropDown = wrap.locator('.tiny-dropdown').nth(1)
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const textButton = dropDown.locator('.tiny-button').nth(0)
const triggerButton = dropDown.locator('.tiny-button').nth(1)
// 按钮有禁用类名
await expect(textButton).toHaveClass(/is-disabled/)
await expect(triggerButton).toHaveClass(/is-disabled/)
// 禁用手势
await expect(textButton).toHaveCSS('cursor', 'not-allowed')
await expect(triggerButton).toHaveCSS('cursor', 'not-allowed')
// 禁用文本色
await expect(textButton).toHaveCSS('color', 'rgb(173, 176, 184)')
await expect(triggerButton).toHaveCSS('color', 'rgb(173, 176, 184)')
// 图标禁用色
await expect(triggerButton.locator('svg')).toHaveCSS('fill', 'rgb(173, 176, 184)')
await page.waitForTimeout(1200)
await triggerButton.hover()
await expect(dropDownMenu).not.toBeVisible()
})
test('菜单项禁用', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#disabled')
const wrap = page.locator('#disabled')
const dropDown = wrap.locator('.tiny-dropdown').nth(2)
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
await page.waitForTimeout(1200)
await dropDown.hover()
await expect(dropDownMenu).toBeVisible()
await expect(dropDownMenuItem.filter({ hasText: '不能选择' })).toHaveClass(/is-disabled/)
await expect(dropDownMenuItem.filter({ hasText: '不能选择' })).toHaveCSS('color', 'rgb(173, 176, 184)')
})

View File

@ -1,19 +1,51 @@
import { test, expect } from '@playwright/test'
test('内置事件', async ({ page }) => {
test('按钮类型内置事件', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#events')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const wrap = page.locator('#events')
const dropDown = wrap.locator('.tiny-dropdown').nth(0)
const notify = page.locator('.tiny-notify')
const dropDownMenuItem = page.locator('body > .tiny-dropdown-menu > .tiny-dropdown-item')
await dropDown.locator('button').first().click()
// 验证 button-click
await dropDown.locator('button').nth(0).click()
await expect(notify.filter({ hasText: '下拉菜单内置按钮点击事件' })).toBeVisible()
// 验证 visible-change
await page.waitForTimeout(500)
await dropDown.locator('button').nth(1).hover()
await expect(notify.filter({ hasText: '下拉菜单显隐事件,当前为显示' })).toBeVisible()
await dropDownMenuItem.filter({ hasText: '狮子头' }).click()
await page.waitForTimeout(500)
await dropDown.locator('button').nth(0).hover()
await expect(notify.filter({ hasText: '下拉菜单显隐事件,当前为隐藏' })).toBeVisible()
// 验证 item-click
await page.waitForTimeout(500)
await dropDown.locator('button').nth(1).hover()
await dropDownMenuItem.filter({ hasText: '黄金糕' }).click()
await expect(notify.filter({ hasText: 'itemClick 回调事件' })).toBeVisible()
})
test('配置式内置事件', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#events')
const wrap = page.locator('#events')
const notify = page.locator('.tiny-notify')
const dropDown = wrap.locator('.tiny-dropdown').nth(1)
await expect(dropDown).toHaveClass(/options-event/)
const dropDownMenuItem = page.locator('body > .tiny-dropdown-menu > .tiny-dropdown-item')
// 验证 visible-change
await page.waitForTimeout(500)
await dropDown.hover()
await expect(notify.filter({ hasText: '下拉菜单显隐事件,当前为显示' })).toBeVisible()
// 验证 item-click
await dropDownMenuItem.filter({ hasText: '黄金糕' }).click()
await expect(notify.filter({ hasText: 'itemClick 回调事件' })).toBeVisible()
// 验证 visible-change
await expect(notify.filter({ hasText: '下拉菜单显隐事件,当前为隐藏' })).toBeVisible()
})

View File

@ -18,7 +18,7 @@
</tiny-dropdown>
<p>场景2配置式</p>
<tiny-dropdown @item-click="itemClick" @button-click="buttonClick" @visible-change="visibleChange">
<tiny-dropdown class="options-event" @item-click="itemClick" @visible-change="visibleChange">
<template #dropdown>
<tiny-dropdown-menu :options="options"> </tiny-dropdown-menu>
</template>

View File

@ -1,14 +1,15 @@
import { test, expect } from '@playwright/test'
test('菜单隐藏方式', async ({ page }) => {
test('点击后不收起', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#hide-on-click')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const wrap = page.locator('#hide-on-click')
const dropDown = wrap.locator('.tiny-dropdown')
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = page.locator('body > .tiny-dropdown-menu > .tiny-dropdown-item')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
await page.waitForTimeout(1300)
await dropDown.hover()
await expect(dropDownMenu).toBeVisible()
// 点击菜单项后菜单不消失

View File

@ -12,11 +12,11 @@
</template>
<script setup>
import { ref } from 'vue'
import { reactive } from 'vue'
import { iconStarDisable } from '@opentiny/vue-icon'
import { Dropdown as TinyDropdown, DropdownMenu as TinyDropdownMenu, Notify } from '@opentiny/vue'
const options = ref([
const options = reactive([
{
label: '老友粉1',
icon: iconStarDisable(),
@ -39,7 +39,33 @@ const options = ref([
}
])
function itemClick(data) {
const menuOptions = reactive({
options: [
{
label: '老友粉',
icon: iconStarDisable(),
children: [
{
label: '老友粉2.1',
children: [{ label: '狮子头3.1' }]
},
{ label: '老友粉2.2' },
{ label: '老友粉2.3', disabled: true }
]
},
{
label: '狮子头',
divided: true
},
{
label: '黄金糕',
divided: true,
icon: iconStarDisable()
}
]
})
const itemClick = (data) => {
Notify({
type: 'info',
title: 'itemData',

View File

@ -1,16 +1,42 @@
import { test, expect } from '@playwright/test'
test('多级菜单', async ({ page }) => {
test('多级菜单,使用 menu-options', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#multi-level')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const dropDownMenuItem = page.locator('body > .tiny-dropdown-menu > .tiny-dropdown-item')
const wrap = page.locator('#multi-level')
const dropDown = wrap.locator('.tiny-dropdown').first()
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
const notify = page.locator('.tiny-notify')
await page.waitForTimeout(1500)
await dropDown.hover()
await dropDownMenuItem.getByText('老友粉1').hover()
await expect(dropDownMenu).toBeVisible()
await dropDownMenuItem.first().hover()
await dropDownMenuItem.getByText('老友粉2.1').hover()
await dropDownMenuItem.getByText('狮子头3.1').click()
await expect(
notify.filter({
hasText: '配置式可以通过 data.itemData 获取配置数据:{"label":"狮子头3.1"}'
})
).toBeVisible()
})
test('多级菜单,使用 options', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#multi-level')
const wrap = page.locator('#multi-level')
const dropDown = wrap.locator('.tiny-dropdown').nth(1)
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
const notify = page.locator('.tiny-notify')
await page.waitForTimeout(1500)
await dropDown.hover()
await expect(dropDownMenu).toBeVisible()
await dropDownMenuItem.first().hover()
await dropDownMenuItem.getByText('老友粉2.1').hover()
await dropDownMenuItem.getByText('狮子头3.1').click()
await expect(

View File

@ -1,7 +1,7 @@
<template>
<div>
<p>场景1使用 menu-options 属性定义 children</p>
<tiny-dropdown :menu-options="menuOptions"></tiny-dropdown>
<tiny-dropdown :menu-options="menuOptions" @item-click="itemClick"></tiny-dropdown>
<p>场景2使用 options 属性定义 children</p>
<tiny-dropdown @item-click="itemClick">
<template #dropdown>
@ -68,15 +68,7 @@ export default {
icon: iconStarDisable()
}
]
},
childrenOption: [
{
label: '老友粉2.1',
children: [{ label: '狮子头3.1' }]
},
{ label: '老友粉2.2' },
{ label: '老友粉2.3', disabled: true }
]
}
}
},
methods: {

View File

@ -1,18 +1,98 @@
import { test, expect } from '@playwright/test'
test('使用配置式', async ({ page }) => {
// 场景1
test('配置式:使用 menu-options', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#options')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const menuOptionDropDown = dropDown.first()
const titleOptionDropDown = dropDown.nth(2)
const wrap = page.locator('#options')
const dropDown = wrap.locator('.tiny-dropdown').first()
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = page.locator('body > .tiny-dropdown-menu > .tiny-dropdown-item')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
await expect(titleOptionDropDown).toContainText('点击下拉')
await menuOptionDropDown.hover()
await page.waitForTimeout(200)
await dropDown.hover()
await expect(dropDownMenu.first()).toBeVisible()
await expect(dropDownMenuItem.first()).toContainText('老友粉')
await expect(dropDownMenuItem.first()).toHaveClass(/is-disabled/)
await expect(dropDownMenuItem.nth(2)).toContainText('黄金糕')
// 检测配置的图标是否出现
await expect(dropDownMenuItem.nth(2).locator('svg > path')).toHaveAttribute('d', /^M12 2\.8c\.1 0.+2-\.6-\.3-1-\.3z$/)
})
// 场景2
test('配置式:使用 menu-options 和 title', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#options')
const wrap = page.locator('#options')
const dropDown = wrap.locator('.tiny-dropdown').nth(1)
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
await expect(dropDown).toContainText('点击下拉')
await page.waitForTimeout(200)
await dropDown.hover()
await expect(dropDownMenu.first()).toBeVisible()
await expect(dropDownMenuItem.first()).toContainText('老友粉')
await expect(dropDownMenuItem.first()).toHaveClass(/is-disabled/)
await expect(dropDownMenuItem.nth(2)).toContainText('黄金糕')
// 检测配置的图标是否出现
await expect(dropDownMenuItem.nth(2).locator('svg > path')).toHaveAttribute('d', /^M12 2\.8c\.1 0.+2-\.6-\.3-1-\.3z$/)
})
// 场景3
test('配置式:使用 menu-options 和 text-field', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#options')
const wrap = page.locator('#options')
const dropDown = wrap.locator('.tiny-dropdown').nth(2)
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
await page.waitForTimeout(1200)
await dropDown.hover()
await expect(dropDownMenu.first()).toBeVisible()
await expect(dropDownMenuItem.first()).toContainText('老友粉')
await expect(dropDownMenuItem.first()).toHaveClass(/is-disabled/)
await expect(dropDownMenuItem.nth(2)).toContainText('黄金糕')
// 检测配置的图标是否出现
await expect(dropDownMenuItem.nth(2).locator('svg > path')).toHaveAttribute('d', /^M12 2\.8c\.1 0.+2-\.6-\.3-1-\.3z$/)
})
// 场景4
test('配置式:使用 options', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#options')
const wrap = page.locator('#options')
const dropDown = wrap.locator('.tiny-dropdown').nth(3)
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
await page.waitForTimeout(300)
await dropDown.hover()
await expect(dropDownMenu.first()).toBeVisible()
await expect(dropDownMenuItem.first()).toContainText('老友粉')
await expect(dropDownMenuItem.first()).toHaveClass(/is-disabled/)
await expect(dropDownMenuItem.nth(2)).toContainText('黄金糕')
// 检测配置的图标是否出现
await expect(dropDownMenuItem.nth(2).locator('svg > path')).toHaveAttribute('d', /^M12 2\.8c\.1 0.+2-\.6-\.3-1-\.3z$/)
})
// 场景5
test('配置式:使用 options 和 text-field ', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#options')
const wrap = page.locator('#options')
const dropDown = wrap.locator('.tiny-dropdown').nth(4)
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const dropDownMenuItem = dropDownMenu.locator('.tiny-dropdown-item')
await page.waitForTimeout(300)
await dropDown.hover()
await expect(dropDownMenu.first()).toBeVisible()
await expect(dropDownMenuItem.first()).toContainText('老友粉')
await expect(dropDownMenuItem.first()).toHaveClass(/is-disabled/)

View File

@ -4,8 +4,9 @@ test('不同尺寸', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#size')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const wrap = page.locator('#size')
const dropDown = wrap.locator('.tiny-dropdown')
const defaultDropDown = dropDown.first()
const mediumDropDown = dropDown.nth(1)
const smallDropDown = dropDown.nth(2)

View File

@ -2,7 +2,7 @@
<tiny-dropdown @visible-change="visibleChange">
<span>默认插槽</span>
<template #suffix-icon>
<tiny-icon-sandwich-collapse></tiny-icon-sandwich-collapse>
<tiny-icon-ascending></tiny-icon-ascending>
</template>
<template #dropdown>
<tiny-dropdown-menu>
@ -17,12 +17,12 @@
</template>
<script setup>
import { iconSandwichCollapse } from '@opentiny/vue-icon'
import { iconAscending } from '@opentiny/vue-icon'
import {
Dropdown as TinyDropdown,
DropdownMenu as TinyDropdownMenu,
DropdownItem as TinyDropdownItem
} from '@opentiny/vue'
const TinyIconSandwichCollapse = iconSandwichCollapse()
const TinyIconAscending = iconAscending()
</script>

View File

@ -1,11 +1,18 @@
import { test, expect } from '@playwright/test'
test('默认插槽', async ({ page }) => {
test('插槽', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#slot-default')
await page.goto('dropdown#slots')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const wrap = page.locator('#slots')
const dropDown = wrap.locator('.tiny-dropdown')
const dropDownSvg = dropDown.locator('svg')
// 默认插槽
await expect(dropDown).toContainText('默认插槽')
// suffix-icon 插槽
await expect(dropDownSvg.locator('path')).toHaveAttribute(
'd',
'M337.288 105.538c11.775-6.513 13.163-7.275 22.5-2.313l4.188 2.3c3.712 4.863 4.387 5.75 5.063 9.962l.475 3.388v377.463h-37.5V163.875l-105.5 105.538L200 242.9l137.288-137.362zM500 418.75v37.5h-75v-37.5h75zm37.5-87.5v37.5H425v-37.5h112.5zm37.5-87.5v37.5H425v-37.5h150zm37.5-87.5v37.5H425v-37.5h187.5z'
)
})

View File

@ -1,11 +1,11 @@
import { test, expect } from '@playwright/test'
test('触发对象,配置split-button属性', async ({ page }) => {
test('按钮类型', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#split-button')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const wrap = page.locator('#split-button')
const dropDown = wrap.locator('.tiny-dropdown')
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const textBtn = dropDown.locator('button').first()
const dropDownBtn = dropDown.locator('button').nth(1)
@ -16,7 +16,9 @@ test('触发对象,配置split-button属性', async ({ page }) => {
await expect(textBtn).toHaveCSS('color', 'rgb(255, 255, 255)')
await expect(dropDownBtn).toHaveCSS('background-color', 'rgb(80, 212, 171)')
await expect(dropDownBtn).toHaveCSS('color', 'rgb(255, 255, 255)')
// 文字悬浮不出现下拉菜单
await page.waitForTimeout(500)
await textBtn.hover()
await expect(dropDownMenu).not.toBeVisible()
await dropDownBtn.hover()

View File

@ -4,8 +4,8 @@ test('自定义文本', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#title')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const wrap = page.locator('#title')
const dropDown = wrap.locator('.tiny-dropdown')
await expect(dropDown).toContainText('自定义文本')
})

View File

@ -4,14 +4,18 @@ test('触发方式', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('dropdown#trigger')
const preview = page.locator('#preview')
const dropDown = preview.locator('.tiny-dropdown')
const wrap = page.locator('#trigger')
const dropDown = wrap.locator('.tiny-dropdown')
const dropDownMenu = page.locator('body > .tiny-dropdown-menu')
const hoverTrigger = dropDown.first()
const clickTrigger = dropDown.nth(1)
// hover
await page.waitForTimeout(1200)
await hoverTrigger.hover()
await expect(dropDownMenu.first()).toBeVisible()
// click
await page.waitForTimeout(1200)
await clickTrigger.hover()
await expect(dropDownMenu.nth(1)).not.toBeVisible()
await clickTrigger.click()