test(select): [select] Optimized the E2E test cases of the select component. Fixed an issue where the allowCopy and autoSearch attributes do not take effect (#981)

* fix(select): [select] Fix the issue of ineffective allowCopy and autoSearch properties in the select component

* test(select): [select] Optimize select component e2e test cases

* test(select): [select] Optimize select component e2e test cases
This commit is contained in:
MomoPoppy 2023-11-30 20:33:07 +08:00 committed by GitHub
parent 4f76a8ae21
commit eed4535d34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 1326 additions and 808 deletions

View File

@ -1,34 +1,48 @@
import { test, expect } from '@playwright/test'
test('click', async ({ page }) => {
test('点击选中', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.waitForTimeout(300)
await page.goto('select#allow-create')
const input = page.locator('#preview .tiny-input__inner')
const wrap = page.locator('#allow-create')
const dropdown = page.locator('.tiny-select-dropdown')
const input = wrap.locator('.tiny-input__inner').first()
await input.click()
await input.fill('测试allow-create')
const KeyboardEvent = await page.evaluateHandle(() => new KeyboardEvent('keyup'))
await input.dispatchEvent('keyup', { KeyboardEvent })
await expect(input).toHaveValue('测试allow-create')
await page.getByRole('listitem').filter({ hasText: '测试allow-create' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '测试allow-create' }).click()
await expect(input).toHaveValue('测试allow-create')
await input.click()
await expect(input).toHaveValue('')
await expect(page.getByRole('listitem').filter({ hasText: '测试allow-create' })).toHaveClass(/selected/)
await expect(dropdown.getByRole('listitem').filter({ hasText: '测试allow-create' })).toHaveClass(/selected/)
})
test('press-enter', async ({ page }) => {
test('enter 选中', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.waitForTimeout(300)
await page.goto('select#allow-create')
const input = page.locator('#preview .tiny-input__inner')
await input.click()
const wrap = page.locator('#allow-create')
const dropdown = page.locator('.tiny-select-dropdown').nth(1)
const input = wrap.locator('.tiny-input__inner').nth(1)
await input.click()
await input.press('a')
await input.press('b')
await page.waitForTimeout(300)
await input.press('Enter')
await expect(page.locator('.tiny-select-dropdown__wrap')).toBeHidden()
await expect(dropdown).toBeHidden()
await expect(input).toHaveValue('ab')
await input.click()
await expect(input).toHaveValue('')
await expect(page.getByRole('listitem').filter({ hasText: 'ab' })).toHaveClass(/selected/)
await expect(dropdown.getByRole('listitem').filter({ hasText: 'ab' })).toHaveClass(/selected/)
})

View File

@ -46,6 +46,6 @@ p {
line-height: 1.5;
}
.tiny-button {
margin-bottom: 10px;
margin-right: 10px;
}
</style>

View File

@ -1,14 +1,29 @@
import { test, expect } from '@playwright/test'
test('automatic-dropdown', async ({ page }) => {
test('不可搜索时,获取焦点不下拉', async ({ page }) => {
await page.goto('select#automatic-dropdown')
const input = page.locator('#preview .tiny-input__inner')
const wrap = page.locator('#automatic-dropdown')
const input = wrap.locator('.tiny-input__inner').first()
const dropdown = page.locator('.tiny-select-dropdown').first()
await page.getByRole('button', { name: '点击获取焦点' }).click()
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await wrap.getByRole('button').first().click()
// 聚焦高亮
await expect(input).toHaveCSS('border-color', 'rgb(94, 124, 224)')
// 不下拉
await expect(dropdown).toBeHidden()
})
test('可搜索时,获取焦点自动下拉', async ({ page }) => {
await page.goto('select#automatic-dropdown')
const wrap = page.locator('#automatic-dropdown')
const input = wrap.locator('.tiny-input__inner').nth(1)
const dropdown = page.locator('.tiny-select-dropdown').nth(1)
await wrap.getByRole('button').nth(1).click()
// 聚焦下拉
await dropdown.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await expect(input).toHaveValue('双皮奶')
// 验证选中
await input.click()
await expect(page.getByRole('listitem').filter({ hasText: '双皮奶' })).toHaveClass(/selected/)
await page.locator('.rel').click()
await expect(page.locator('div').filter({ hasText: '黄金糕双皮奶蚵仔煎龙须面北京烤鸭' }).first()).toBeHidden()
})

View File

@ -54,6 +54,6 @@ p {
line-height: 1.5;
}
.tiny-button {
margin-bottom: 10px;
margin-right: 10px;
}
</style>

View File

@ -1,18 +1,20 @@
import { test, expect } from '@playwright/test'
test('basic', async ({ page }) => {
test('基础用法', async ({ page }) => {
await page.goto('select#basic-usage')
const input = page.locator('#preview .tiny-input__inner')
const wrap = page.locator('#basic-usage')
const input = wrap.locator('.tiny-input__inner')
const dropdown = page.locator('.tiny-select-dropdown')
await input.click()
await page.getByRole('listitem').filter({ hasText: '蚵仔煎' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '蚵仔煎' }).click()
await expect(input).toHaveValue('蚵仔煎')
await page.locator('#preview svg').nth(1).click()
await wrap.locator('.tiny-input__suffix svg').click()
await expect(page.getByRole('listitem').filter({ hasText: '蚵仔煎' })).toHaveClass(/selected/)
await page.getByRole('listitem').filter({ hasText: '北京烤鸭' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '北京烤鸭' }).click()
await expect(input).toHaveValue('北京烤鸭')
await input.click()
await expect(page.getByRole('listitem').filter({ hasText: '北京烤鸭' })).toHaveClass(/selected/)
await page.locator('.rel').click()
await expect(dropdown.getByRole('listitem').filter({ hasText: '北京烤鸭' })).toHaveClass(/selected/)
await wrap.click()
await expect(page.locator('div').filter({ hasText: '黄金糕双皮奶蚵仔煎龙须面北京烤鸭' }).first()).toBeHidden()
})

View File

@ -2,15 +2,19 @@ import { test, expect } from '@playwright/test'
test('binding-obj', async ({ page }) => {
await page.goto('select#binding-obj')
const input = page.locator('#preview .tiny-input__inner')
const valueLocator = page.locator('#preview .value')
const wrap = page.locator('#binding-obj')
const input = wrap.locator('.tiny-input__inner')
const dropdown = page.locator('.tiny-select-dropdown')
const valueLocator = wrap.locator('.value')
await input.click()
await page.getByRole('listitem').filter({ hasText: '龙须面' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '龙须面' }).click()
await expect(input).toHaveValue('龙须面')
await expect(valueLocator).toHaveText('{ "val": "选项4", "id": 4 }')
await input.click()
await page.getByRole('listitem').filter({ hasText: '蚵仔煎' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '蚵仔煎' }).click()
await expect(input).toHaveValue('蚵仔煎')
await expect(valueLocator).toHaveText('{ "val": "选项3", "id": 3 }')
})

View File

@ -2,13 +2,17 @@ import { expect, test } from '@playwright/test'
test('cache-op', async ({ page }) => {
await page.goto('select#cache-usage')
const input = page.locator('#preview .tiny-input__inner')
const cacheValue = page.locator('#preview .cache-value')
const wrap = page.locator('#cache-usage')
const dropdown = page.locator('.tiny-select-dropdown')
const input = wrap.locator('.tiny-input__inner')
const cacheValue = wrap.locator('.cache-value')
await input.click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await expect(cacheValue).toContainText(['选项1'])
await input.click()
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await expect(cacheValue).toContainText(['选项2'])
})

View File

@ -2,14 +2,19 @@ import { test, expect } from '@playwright/test'
test('clearable', async ({ page }) => {
await page.goto('select#clearable')
const input = page.locator('#preview .tiny-input__inner')
const icon = page.locator('#preview .tiny-input__suffix')
const wrap = page.locator('#clearable')
const dropdown = page.locator('.tiny-select-dropdown')
const input = wrap.locator('.tiny-input__inner')
const icon = wrap.locator('.tiny-input__suffix')
// 验证默认值
await expect(input).toHaveValue('蚵仔煎')
// 验证清空
await input.hover()
await icon.click()
await expect(input).toHaveValue('')
// 验证选中
await icon.click()
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await dropdown.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await expect(input).toHaveValue('双皮奶')
})

View File

@ -2,17 +2,29 @@ import { test, expect } from '@playwright/test'
test('collapse-tags', async ({ page }) => {
await page.goto('select#collapse-tags')
await expect(page.locator('span.tiny-tag')).toHaveCount(2)
await expect(page.locator('span').filter({ hasText: '黄金糕' }).nth(1)).toBeVisible()
await expect(page.locator('span').filter({ hasText: '+ 1' }).nth(1)).toBeVisible()
await page.getByText('黄金糕+ 1').click()
await expect(page.getByRole('listitem').filter({ hasText: '黄金糕' })).toHaveClass(/selected/)
await expect(page.getByRole('listitem').filter({ hasText: '双皮奶' })).toHaveClass(/selected/)
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).locator('span').nth(2).click()
await expect(page.locator('span').filter({ hasText: '+ 1' }).nth(1)).toBeHidden()
await expect(page.locator('span.tiny-tag')).toHaveCount(1)
await page.getByRole('listitem').filter({ hasText: '蚵仔煎' }).locator('span').nth(2).click()
await page.getByRole('listitem').filter({ hasText: '北京烤鸭' }).locator('span').nth(2).click()
await expect(page.locator('span').filter({ hasText: '+ 2' }).nth(1)).toBeVisible()
await expect(page.locator('span.tiny-tag')).toHaveCount(2)
const wrap = page.locator('#collapse-tags')
const dropdown = page.locator('.tiny-select-dropdown')
const tag = wrap.locator('.tiny-tag')
const option = dropdown.locator('.tiny-option')
// 验证默认值的折叠标签显示
await expect(tag).toHaveCount(2)
await expect(tag.filter({ hasText: '黄金糕' })).toBeVisible()
await expect(tag.filter({ hasText: '+ 1' })).toBeVisible()
// 点击下拉后选中效果
await tag.first().click()
await expect(option.filter({ hasText: '黄金糕' })).toHaveClass(/selected/)
await expect(option.filter({ hasText: '双皮奶' })).toHaveClass(/selected/)
// 取消选中一个
await option.filter({ hasText: '黄金糕' }).locator('span').nth(2).click()
await expect(tag.filter({ hasText: '+ 1' })).toBeHidden()
await expect(tag).toHaveCount(1)
// 再选中2个
await option.filter({ hasText: '蚵仔煎' }).locator('span').nth(2).click()
await option.filter({ hasText: '北京烤鸭' }).locator('span').nth(2).click()
await expect(tag.filter({ hasText: '+ 2' })).toBeVisible()
await expect(tag).toHaveCount(2)
})

View File

@ -0,0 +1,49 @@
import { test, expect } from '@playwright/test'
test('多选复制单个标签', async ({ page }) => {
await page.goto('select#copy-multi')
await page.waitForTimeout(1000)
await page.mouse.move(392, 316)
await page.waitForTimeout(1000)
await page.mouse.down()
await page.waitForTimeout(1000)
await page.mouse.move(346, 316)
await page.waitForTimeout(1000)
await page.mouse.up()
await page.keyboard.press('Control+C')
const valueInput = page.locator('.copy-value .tiny-input__inner')
await expect(valueInput).toHaveValue('')
await valueInput.focus()
await page.keyboard.press('Control+V')
await page.waitForTimeout(200)
await expect(valueInput).toHaveValue('黄金糕')
})
test('多选一键复制所有标签', async ({ page }) => {
await page.goto('select#copy-multi')
const wrap = page.locator('#copy-multi')
const select = wrap.locator('.tiny-select').nth(1)
const copyValueInput = wrap.locator('.copy-value .tiny-input__inner')
await select.hover()
await select.locator('.tiny-select__copy > .tiny-svg > .st0').click()
await copyValueInput.press('Control+V')
await expect(copyValueInput).toHaveValue('黄金糕,双皮奶')
})
test('多选设置复制文本分隔符', async ({ page }) => {
await page.goto('select#copy-multi')
const wrap = page.locator('#copy-multi')
const select = wrap.locator('.tiny-select').nth(2)
const copyValueInput = wrap.locator('.copy-value .tiny-input__inner')
await select.hover()
await select.locator('.tiny-select__copy > .tiny-svg > .st0').click()
await copyValueInput.press('Control+V')
await expect(copyValueInput).toHaveValue('黄金糕/双皮奶')
})

View File

@ -0,0 +1,70 @@
import { test, expect } from '@playwright/test'
test('单选无需配置可复制', async ({ page }) => {
await page.goto('select#copy-single')
const wrap = page.locator('#copy-single')
const valueInput = wrap.locator('.custom .tiny-input__inner')
await page.waitForTimeout(1000)
await page.mouse.move(393, 285)
await page.waitForTimeout(1000)
await page.mouse.down()
await page.waitForTimeout(1000)
await page.mouse.move(345, 285)
await page.waitForTimeout(200)
await page.mouse.up()
await page.keyboard.press('Control+C')
await expect(valueInput).toHaveValue('')
await valueInput.focus()
await page.keyboard.press('Control+V')
await page.waitForTimeout(200)
await expect(valueInput).toHaveValue('黄金糕')
})
test('单选可搜索配置 allow-copy 可复制', async ({ page }) => {
await page.goto('select#copy-single')
const wrap = page.locator('#copy-single')
const select = wrap.locator('.tiny-select').nth(1)
const valueInput = wrap.locator('.custom .tiny-input__inner')
await page.waitForTimeout(800)
await page.mouse.move(400, 350)
await page.waitForTimeout(800)
await page.mouse.down()
await page.waitForTimeout(800)
await page.mouse.move(344, 350)
await page.waitForTimeout(200)
await page.mouse.up()
await page.waitForTimeout(800)
await page.keyboard.press('Control+C')
await expect(valueInput).toHaveValue('')
await valueInput.click()
await page.keyboard.press('Control+V')
await page.waitForTimeout(2000)
await expect(valueInput).toHaveValue('黄金糕')
})
test('单选远程搜索配置 allow-copy 可复制', async ({ page }) => {
await page.goto('select#copy-single')
const wrap = page.locator('#copy-single')
const valueInput = wrap.locator('.custom .tiny-input__inner')
await page.waitForTimeout(1000)
await page.mouse.move(410, 433)
await page.waitForTimeout(1000)
await page.mouse.down()
await page.waitForTimeout(1000)
await page.mouse.move(346, 433)
await page.waitForTimeout(200)
await page.mouse.up()
await page.keyboard.press('Control+C')
await expect(valueInput).toHaveValue('')
await valueInput.focus()
await page.keyboard.press('Control+V')
await page.waitForTimeout(200)
await expect(valueInput).toHaveValue('Alabama')
})

View File

@ -20,7 +20,7 @@
<tiny-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
<p class="font-style">粘贴至此处</p>
<tiny-input v-model="inputVal" type="text"></tiny-input>
<tiny-input v-model="inputVal" type="text" class="custom"></tiny-input>
</div>
</template>

View File

@ -1,41 +1,84 @@
import { test, expect } from '@playwright/test'
test('disabled', async ({ page }) => {
test('下拉禁用', async ({ page }) => {
await page.goto('select#disabled')
const input = page.locator('#preview .tiny-input__inner')
const wrap = page.locator('#disabled')
const input = wrap.locator('.tiny-input__inner').first()
const hasDisabled = await input.evaluate((input) => input.hasAttribute('disabled'))
await expect(hasDisabled).toBe(true)
})
test('disabled-options-multiple', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/disabled-options')
const select = page.locator('#preview .tiny-select')
const tags = page.locator('#preview .tiny-select .tiny-tag')
test('多选某项禁用', async ({ page }) => {
await page.goto('select#disabled')
const wrap = page.locator('#disabled')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const tag = select.locator('.tiny-tag')
const option = dropdown.locator('.tiny-option')
await expect(tag).toHaveCount(0)
await select.click()
await expect(option.filter({ hasText: '双皮奶' })).toHaveClass(/is-disabled/)
await option.filter({ hasText: '双皮奶' }).click()
await expect(tag).toHaveCount(0)
await option.filter({ hasText: '黄金糕' }).click()
await expect(tag).toHaveCount(1)
await expect(tag.filter({ hasText: '黄金糕' })).toHaveCount(1)
})
test('单选某项禁用', async ({ page }) => {
await page.goto('select#disabled')
const wrap = page.locator('#disabled')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await select.click()
await expect(page.getByRole('listitem').filter({ hasText: '黄金糕' })).toHaveClass(/is-disabled/)
await expect(page.getByRole('listitem').filter({ hasText: '蚵仔煎' })).toHaveClass(/is-disabled/)
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await expect(tags).toHaveCount(0)
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await expect(tags).toHaveCount(1)
await expect(tags.filter({ hasText: '双皮奶' })).toHaveCount(1)
await expect(option.filter({ hasText: '全部' })).toHaveCount(0)
await expect(option.filter({ hasText: '双皮奶' })).toHaveClass(/is-disabled/)
await option.filter({ hasText: '双皮奶' }).click()
await expect(dropdown).toBeVisible()
await expect(input).toHaveValue('')
await option.filter({ hasText: '黄金糕' }).click()
await expect(dropdown).toBeHidden()
await expect(input).toHaveValue('黄金糕')
})
test('disabled-and-selected-options', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/disabled-and-selected-options')
const slect = page.locator('#preview .tiny-select')
const tags = page.locator('#preview .tiny-select .tiny-tag')
const listitem = page.getByRole('listitem')
await expect(tags.filter({ hasText: '黄金糕' }).locator('svg')).toHaveCount(0)
await slect.click()
await expect(listitem.filter({ hasText: '全部' })).toHaveCount(0)
await expect(listitem.filter({ hasText: '黄金糕' })).toHaveClass(/is-disabled/)
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await expect(tags.filter({ hasText: '黄金糕' }).locator('.tiny-svg')).toHaveCount(0)
await expect(tags.filter({ hasText: '双皮奶' }).locator('.tiny-svg')).toHaveCount(1)
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await expect(tags.filter({ hasText: '黄金糕' }).locator('.tiny-svg')).toHaveCount(0)
test('多选,禁用项默认选中', async ({ page }) => {
await page.goto('select#disabled')
const wrap = page.locator('#disabled')
const select = wrap.locator('.tiny-select').nth(3)
const dropdown = page.locator('body > .tiny-select-dropdown')
const tag = select.locator('.tiny-tag')
const option = dropdown.locator('.tiny-option')
// 默认值显示tag数
await expect(tag).toHaveCount(2)
// 禁用项默认选中不显示关闭图标
await expect(tag.filter({ hasText: '双皮奶' }).locator('svg')).toHaveCount(0)
// 非禁用项显示关闭图标
await expect(tag.filter({ hasText: '蚵仔煎' }).locator('svg')).toHaveCount(1)
// 下拉禁用和默认选中的效果
await select.click()
await expect(option.filter({ hasText: '全部' })).toHaveCount(1)
await expect(option.filter({ hasText: '双皮奶' })).toHaveClass(/is-disabled/)
await expect(option.filter({ hasText: '双皮奶' })).toHaveClass(/selected/)
await expect(option.filter({ hasText: '蚵仔煎' })).toHaveClass(/selected/)
// 点击禁用项不取消选中
await option.filter({ hasText: '双皮奶' }).click()
await expect(dropdown).toBeVisible()
await expect(tag).toHaveCount(2)
// 选中其他项
await option.filter({ hasText: '黄金糕' }).click()
await expect(dropdown).toBeVisible()
await expect(tag).toHaveCount(3)
})

View File

@ -45,37 +45,38 @@ const value2 = ref([])
const change = () => {
Modal.message({
message: 'change 事件'
message: 'change 事件',
duration: 500
})
}
const clear = () => {
Modal.message({
message: 'clear 事件'
message: '触发 clear 事件'
})
}
const focus = () => {
Modal.message({
message: 'focus 事件'
message: '触发 focus 事件'
})
}
const blur = () => {
Modal.message({
message: 'blur 事件'
message: '触发 blur 事件'
})
}
const removeTag = () => {
Modal.message({
message: 'remove-tag 事件'
message: '触发 remove-tag 事件'
})
}
const visibleChange = () => {
Modal.message({
message: 'visible-change 事件'
message: '触发 visible-change 事件'
})
}
</script>

View File

@ -1,76 +1,71 @@
import { test, expect } from '@playwright/test'
test('focus', async ({ page }) => {
await page.goto('select#envts-change')
test('单选事件', async ({ page }) => {
await page.goto('select#events')
const wrap = page.locator('#events')
const select = wrap.locator('.tiny-select').first()
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const model = page.locator('.tiny-modal')
const input = page.locator('#preview .tiny-input__inner')
await input.click()
await page.waitForTimeout(500)
await expect(model.filter({ hasText: 'focus事件' })).toHaveCount(1)
})
await expect(model.filter({ hasText: '触发 focus 事件' })).toHaveCount(1)
await expect(model.filter({ hasText: '触发 visible-change 事件' })).toHaveCount(1)
test('change', async ({ page }) => {
await page.goto('select#envts-change')
const model = page.locator('.tiny-modal')
const input = page.locator('#preview .tiny-input__inner')
await input.click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await option.first().click()
await expect(input).toHaveValue('黄金糕')
await expect(model.filter({ hasText: '触发 change 事件' })).toHaveCount(1)
await expect(model.filter({ hasText: '触发 visible-change 事件' })).toHaveCount(2)
await page.waitForTimeout(500)
await expect(model.filter({ hasText: 'changes事件' })).toHaveCount(1)
await wrap.click()
await expect(model.filter({ hasText: '触发 blur 事件' })).toHaveCount(1)
await page.waitForTimeout(200)
await input.hover()
await select.locator('.tiny-select__close').click()
await page.waitForTimeout(500)
await expect(input).toHaveValue('')
await expect(model.filter({ hasText: '触发 clear 事件' })).toHaveCount(1)
})
test('clear', async ({ page }) => {
await page.goto('select#envts-change')
test('多选事件', async ({ page }) => {
await page.goto('select#events')
const wrap = page.locator('#events')
const select = wrap.locator('.tiny-select').nth(1)
const tag = wrap.locator('.tiny-tag')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const model = page.locator('.tiny-modal')
const input = page.locator('#preview .tiny-input__inner')
await input.click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await expect(input).toHaveValue('黄金糕')
input.hover()
await page.locator('#preview .tiny-input .tiny-input__suffix').click()
await page.waitForTimeout(500)
await expect(model.filter({ hasText: 'clear事件' })).toHaveCount(1)
})
test('blur', async ({ page }) => {
await page.goto('select#envts-change')
const model = page.locator('.tiny-modal')
const input = page.locator('#preview .tiny-input__inner')
await input.click()
await input.blur()
await page.waitForTimeout(500)
await expect(model.filter({ hasText: 'blur事件' })).toHaveCount(1)
})
test('remove-tag', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/envts-remove')
const model = page.locator('.tiny-modal')
const select = page.locator('#preview .tiny-select')
const tags = page.locator('#preview .tiny-select .tiny-tag')
await select.click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await expect(tags.filter({ hasText: '黄金糕' })).toHaveCount(1)
await tags.filter({ hasText: '黄金糕' }).locator('.tiny-svg').click()
await page.waitForTimeout(500)
await expect(model.filter({ hasText: 'removeTag事件' })).toHaveCount(1)
})
await expect(model.filter({ hasText: '触发 focus 事件' })).toHaveCount(1)
await expect(model.filter({ hasText: '触发 visible-change 事件' })).toHaveCount(1)
test('visible-change', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/envts-remove')
const model = page.locator('.tiny-modal')
const input = page.locator('#preview .tiny-input__inner')
const select = page.locator('#preview .tiny-select')
await option.nth(1).click()
await expect(tag).toHaveCount(1)
await expect(model.filter({ hasText: '触发 change 事件' })).toHaveCount(1)
await option.nth(0).click()
await expect(model.filter({ hasText: '触发 change 事件' })).toHaveCount(2)
await expect(tag).toHaveCount(5)
await select.click()
await page.waitForTimeout(500)
await expect(model.filter({ hasText: 'visibleChange事件' })).toHaveCount(1)
await input.blur()
await page.waitForTimeout(500)
await expect(model.filter({ hasText: 'visibleChange事件' })).toHaveCount(1)
await tag.first().locator('.tiny-tag__close').click()
await expect(model.filter({ hasText: '触发 blur 事件' })).toHaveCount(1)
await expect(model.filter({ hasText: '触发 change 事件' })).toHaveCount(1)
await expect(model.filter({ hasText: '触发 remove-tag 事件' })).toHaveCount(1)
await expect(tag).toHaveCount(4)
await wrap.click()
await expect(model.filter({ hasText: '触发 visible-change 事件' })).toHaveCount(1)
await page.waitForTimeout(200)
await select.hover()
await select.locator('.tiny-select__close').click()
await expect(tag).toHaveCount(0)
await expect(model.filter({ hasText: '触发 change 事件' })).toHaveCount(1)
})

View File

@ -53,32 +53,33 @@ export default {
methods: {
change() {
Modal.message({
message: 'change 事件'
message: '触发 change 事件',
duration: 500
})
},
clear() {
Modal.message({
message: 'clear 事件'
message: '触发 clear 事件'
})
},
focus() {
Modal.message({
message: 'focus 事件'
message: '触发 focus 事件'
})
},
blur() {
Modal.message({
message: 'blur 事件'
message: '触发 blur 事件'
})
},
removeTag() {
Modal.message({
message: 'remove-tag 事件'
message: '触发 remove-tag 事件'
})
},
visibleChange() {
Modal.message({
message: 'visible-change 事件'
message: '触发 visible-change 事件'
})
}
}

View File

@ -1,50 +1,87 @@
import { expect, test } from '@playwright/test'
test('filter-nothing', async ({ page }) => {
test('默认搜索', async ({ page }) => {
await page.goto('select#filter-method')
const input = page.locator('#preview .tiny-input__inner')
const wrap = page.locator('#filter-method')
const select = wrap.locator('.tiny-select').first()
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
// 1.1 没有过滤到内容
await input.click()
// 1.1.1 验证 no-match-text
await expect(page.getByText('No Match')).toBeHidden()
await input.press('1')
await expect(input).toHaveValue('1')
await input.press('Enter')
await expect(page.getByText('No Match')).toBeVisible()
const listitems = await page.locator('.tiny-select-dropdown').getByRole('listitem').all()
listitems.forEach(async (item) => {
await expect(item).toHaveAttribute('display', 'none')
await page.waitForTimeout(500)
let allListItems = await option.all()
allListItems.forEach(async (item) => {
await expect(item).toHaveCSS('display', 'none')
})
})
test('filter-something', async ({ page }) => {
await page.goto('select#filter-method')
const input = page.locator('#preview .tiny-input__inner')
await input.click()
// 1.2 过滤到内容
await input.fill('双皮奶')
await expect(input).toHaveValue('双皮奶')
await input.press('Enter')
const listitems = await page
.locator('.tiny-select-dropdown')
.getByRole('listitem')
.filter({ hasNotText: '双皮奶' })
.all()
listitems.forEach(async (item) => {
await expect(item).toHaveAttribute('display', 'none')
await page.waitForTimeout(200)
allListItems.forEach(async (item) => {
const isVisibleItem = (await item.innerText()) === '双皮奶'
if (isVisibleItem) {
await expect(item).toHaveCSS('display', 'flex')
} else {
await expect(item).toHaveCSS('display', 'none')
}
})
await expect(page.locator('.tiny-select-dropdown').getByRole('listitem').filter({ hasText: '双皮奶' })).toBeVisible()
await page.locator('.tiny-select-dropdown').getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await expect(option.filter({ hasText: '双皮奶' })).toBeVisible()
await option.filter({ hasText: '双皮奶' }).click()
await expect(input).toHaveValue('双皮奶')
})
test('no-match-text', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/no-match-text')
const input = page.locator('#preview .tiny-input__inner')
test('自定义过滤', async ({ page }) => {
await page.goto('select#filter-method')
const wrap = page.locator('#filter-method')
const select = wrap.locator('.tiny-select').nth(1)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
// 1.1 没有过滤到内容
await input.click()
const listItems = page.locator('.tiny-select-dropdown__list').getByRole('listitem')
await expect((await listItems.all()).length).toEqual(5)
await expect(page.getByText('No Match')).toBeHidden()
await input.fill('1')
// 1.1.1 验证 no-match-text (待修复)
// await expect(page.getByText('No Match')).toBeHidden()
await input.press('1')
await expect(input).toHaveValue('1')
await input.press('Enter')
await expect(page.getByText('No Match')).toBeVisible()
// await expect(page.getByText('No Match')).toBeVisible()
await page.waitForTimeout(500)
let allListItems = await option.all()
allListItems.forEach(async (item) => {
await expect(item).toHaveCSS('display', 'none')
})
// 1.2 过滤到内容
await input.fill('双皮奶')
await expect(input).toHaveValue('双皮奶')
await input.press('Enter')
await page.waitForTimeout(200)
allListItems.forEach(async (item) => {
const isVisibleItem = (await item.innerText()) === '双皮奶'
if (isVisibleItem) {
await expect(item).toHaveCSS('display', 'flex')
} else {
await expect(item).toHaveCSS('display', 'none')
}
})
await expect(option.filter({ hasText: '双皮奶' })).toBeVisible()
await option.filter({ hasText: '双皮奶' }).click()
await expect(input).toHaveValue('双皮奶')
})

View File

@ -1,9 +1,10 @@
import { test, expect } from '@playwright/test'
test('hidedrop', async ({ page }) => {
await page.goto('select#hide-select-input-border')
const select = page.locator('#preview .tiny-select').first()
const dropdown = page.locator('.tiny-select-dropdown')
await page.goto('select#hide-drop')
const wrap = page.locator('#hide-drop')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
await select.click()
await expect(dropdown).toBeHidden()

View File

@ -0,0 +1,34 @@
<template>
<tiny-select v-model="value" :hide-drop="true">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
</template>
<script>
import { Select, Option } from '@opentiny/vue'
export default {
components: {
TinySelect: Select,
TinyOption: Option
},
data() {
return {
options: [
{ value: '选项1', label: '黄金糕' },
{ value: '选项2', label: '双皮奶' },
{ value: '选项3', label: '蚵仔煎' },
{ value: '选项4', label: '龙须面' },
{ value: '选项5', label: '北京烤鸭' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
.tiny-select {
width: 280px;
}
</style>

View File

@ -1,25 +1,68 @@
import { test, expect } from '@playwright/test'
test('default', async ({ page }) => {
test('下划线默认', async ({ page }) => {
await page.goto('select#input-box-type')
const select = page.locator('#preview .tiny-select').first()
const wrap = page.locator('#input-box-type')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await expect(select).toHaveClass(/tiny-select__underline/)
await expect(input).toHaveCSS('border-top-width', '0px')
await expect(input).toHaveCSS('border-left-width', '0px')
await expect(input).toHaveCSS('border-right-width', '0px')
await expect(input).toHaveCSS('border-color', 'rgb(173, 176, 184)')
await expect(select.locator('svg')).toHaveCSS('fill', 'rgb(87, 93, 108)')
await select.click()
await option.first().click()
await expect(dropdown).toBeHidden()
await expect(input).toHaveValue('黄金糕')
})
test('disable', async ({ page }) => {
test('下划线禁用', async ({ page }) => {
await page.goto('select#input-box-type')
const select = page.locator('#preview .tiny-select').nth(1)
const wrap = page.locator('#input-box-type')
const select = wrap.locator('.tiny-select').nth(1)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
await expect(select).toHaveClass(/tiny-select__underline/)
await expect(input).toHaveCSS('border-top-width', '0px')
await expect(input).toHaveCSS('border-left-width', '0px')
await expect(input).toHaveCSS('border-right-width', '0px')
await expect(input).toHaveCSS('border-color', 'rgb(223, 225, 230)')
await expect(input).toHaveCSS('cursor', 'not-allowed')
await expect(select.locator('svg')).toHaveCSS('fill', 'rgb(173, 176, 184)')
const hasDisabled = await input.evaluate((input) => input.hasAttribute('disabled'))
await expect(hasDisabled).toBe(true)
await select.click()
await expect(dropdown).toBeHidden()
await expect(input).toHaveValue('')
})
test('multiple', async ({ page }) => {
test('下划线多选', async ({ page }) => {
await page.goto('select#input-box-type')
const select = page.locator('#preview .tiny-select').nth(2)
const wrap = page.locator('#input-box-type')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input__inner')
const tag = wrap.locator('.tiny-tag')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await expect(select).toHaveClass(/tiny-select__underline/)
await expect(input).toHaveCSS('border-top-width', '0px')
await expect(input).toHaveCSS('border-left-width', '0px')
await expect(input).toHaveCSS('border-right-width', '0px')
await expect(input).toHaveCSS('border-color', 'rgb(173, 176, 184)')
await expect(select.locator('.tiny-select__caret')).toHaveCSS('fill', 'rgb(87, 93, 108)')
await select.click()
await expect(dropdown).toBeVisible()
await option.first().click()
await expect(tag).toHaveCount(5)
await expect(select).toHaveClass(/tiny-select__underline/)
await expect(select).toHaveClass(/tiny-select__multiple/)

View File

@ -1,29 +1,34 @@
import { expect, test } from '@playwright/test'
test('not-inherit-width', async ({ page }) => {
test('默认下拉弹框宽度由内容撑开', async ({ page }) => {
await page.goto('select#is-drop-inherit-width')
const input = page.getByPlaceholder('请选择').first()
await input.click()
await page.waitForTimeout(1000)
const listitem = page.getByRole('listitem').filter({ hasText: '双皮奶' })
const inputBox = await input.boundingBox()
const listitemBox = await listitem.boundingBox()
await page.waitForTimeout(3000)
const wrap = page.locator('#is-drop-inherit-width')
const select = wrap.locator('.tiny-select').nth(0)
const dropdown = page.locator('body > .tiny-select-dropdown')
const input = select.locator('.tiny-input__inner')
const option = dropdown.locator('.tiny-option')
await select.click()
const inputBox = await input.boundingBox()
const listitemBox = await option.first().boundingBox()
const result = listitemBox.width > inputBox.width
await expect(result).toBe(true)
})
test('inherit-width', async ({ page }) => {
test('下拉弹框宽度与输入框一致', async ({ page }) => {
await page.goto('select#is-drop-inherit-width')
const input = page.getByPlaceholder('请选择').nth(1)
await input.click()
await page.waitForTimeout(1000)
const listitem = page.getByRole('listitem').filter({ hasText: '双皮奶' })
const inputBox = await input.boundingBox()
const wrap = page.locator('#is-drop-inherit-width')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const input = select.locator('.tiny-input__inner')
const option = dropdown.locator('.tiny-option')
await select.click()
const inputBox = await input.boundingBox()
const listitemBox = await option.first().boundingBox()
const listitemBox = await listitem.boundingBox()
await page.waitForTimeout(3000)
const result = listitemBox.width === inputBox.width
await expect(result).toBe(true)
})

View File

@ -1,7 +1,9 @@
<template>
<div>
<tiny-button @click="handleFocus"> 点击获取焦点 </tiny-button>
<tiny-button @click="handleBlur"> 点击失去焦点 </tiny-button>
<div>
<tiny-button @click="handleFocus"> 点击获取焦点 </tiny-button>
<tiny-button @click="handleBlur"> 点击失去焦点 </tiny-button>
</div>
<tiny-select v-model="value" ref="drop" filterable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>

View File

@ -1,12 +1,16 @@
import { test, expect } from '@playwright/test'
test('manual-focus-blur', async ({ page }) => {
test('手动聚焦失焦', async ({ page }) => {
await page.goto('select#manual-focus-blur')
await page.getByRole('button', { name: '单击按钮 Select 将获取焦点' }).click()
await page.waitForTimeout(1000)
const dropdown = page.locator('.tiny-select-dropdown')
const wrap = page.locator('#manual-focus-blur')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const button = wrap.locator('.tiny-button')
await button.first().click()
await expect(dropdown).toBeVisible()
await page.getByRole('button', { name: '单击按钮 Select 将失去焦点' }).click()
await page.waitForTimeout(1000)
await button.nth(1).click()
await expect(dropdown).toBeHidden()
})

View File

@ -1,7 +1,9 @@
<template>
<div>
<tiny-button @click="handleFocus"> 点击获取焦点 </tiny-button>
<tiny-button @click="handleBlur"> 点击失去焦点 </tiny-button>
<div>
<tiny-button @click="handleFocus"> 点击获取焦点 </tiny-button>
<tiny-button @click="handleBlur"> 点击失去焦点 </tiny-button>
</div>
<tiny-select v-model="value" ref="drop" filterable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>

View File

@ -1,32 +1,56 @@
import { expect, test } from '@playwright/test'
test('grid-multiple', async ({ page }) => {
await page.goto('select#nest-checkbox-grid')
const suffix = page.locator('#preview .tiny-input__suffix')
const select = page.locator('#preview .tiny-select')
test('配置式配置映射字段', async ({ page }) => {
await page.goto('select#map-field')
const wrap = page.locator('#map-field')
const select = wrap.locator('.tiny-select').nth(0)
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const suffix = select.locator('.tiny-input__suffix')
const tag = select.locator('.tiny-tag')
await expect(tag).toHaveCount(2)
await expect(tag.first()).toHaveText('黄金糕')
await expect(tag.nth(1)).toHaveText('双皮奶')
await suffix.click()
await page.waitForTimeout(500)
await expect(dropdown).toBeVisible()
await expect(option.filter({ hasText: '黄金糕' })).toHaveClass(/selected/)
await expect(option.filter({ hasText: '双皮奶' })).toHaveClass(/selected/)
})
test('嵌套表格配置映射字段', async ({ page }) => {
await page.goto('select#map-field')
const wrap = page.locator('#map-field')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffix = select.locator('.tiny-input__suffix')
const tag = select.locator('.tiny-tag')
await expect(tag).toHaveCount(2)
await suffix.click()
await page.waitForTimeout(500)
const tr = page.locator('.tiny-select-dropdown .tiny-grid__body-wrapper .tiny-grid-body__row')
const currentTr = page.locator('.tiny-select-dropdown .tiny-grid__body-wrapper .row__selected')
const tr = dropdown.locator('.tiny-grid__body-wrapper .tiny-grid-body__row')
const currentTr = dropdown.locator('.tiny-grid__body-wrapper .row__selected')
await expect(tr).toHaveCount(5)
await expect(currentTr).toHaveCount(2)
await page.getByRole('row', { name: '华南区 广东省 珠海市' }).getByRole('cell').first().click()
await dropdown.getByRole('row', { name: '华南区 广东省 珠海市' }).getByRole('cell').first().click()
await expect(tag).toHaveCount(3)
await expect(currentTr).toHaveCount(3)
await page.getByRole('row', { name: '华南区 广东省 珠海市' }).getByRole('cell').first().click()
await dropdown.getByRole('row', { name: '华南区 广东省 珠海市' }).getByRole('cell').first().click()
await expect(tag).toHaveCount(2)
await expect(currentTr).toHaveCount(2)
await page.getByRole('row', { name: '区域 省份 城市' }).getByRole('cell').first().click()
await dropdown.getByRole('row', { name: '区域 省份 城市' }).getByRole('cell').first().click()
await expect(tag).toHaveCount(5)
await expect(currentTr).toHaveCount(5)
let all = await page.getByRole('row', { name: '区域 省份 城市' }).locator('.tiny-grid-checkbox__icon .tiny-svg')
let all = await dropdown
.getByRole('row', { name: '区域 省份 城市' })
.locator('.tiny-grid-checkbox__icon .tiny-svg')
.nth(1)
await expect(all).toHaveClass(/icon-checked-sur/)
await page.getByRole('row', { name: '区域 省份 城市' }).getByRole('cell').first().click()
await dropdown.getByRole('row', { name: '区域 省份 城市' }).getByRole('cell').first().click()
await page.waitForTimeout(500)
await expect(all).toBeHidden()
await expect(tag).toHaveCount(0)

View File

@ -1,14 +1,18 @@
import { expect, test } from '@playwright/test'
test('memoize-usage', async ({ page }) => {
test('手动缓存', async ({ page }) => {
await page.goto('select#memoize-usage')
const input = page.locator('#preview .tiny-input__inner')
const cacheValue = page.locator('#preview .cache-value')
const wrap = page.locator('#memoize-usage')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const cacheValue = wrap.locator('.cache-value')
await input.click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await select.click()
await option.filter({ hasText: '黄金糕' }).click()
await expect(cacheValue).toContainText(['选项1'])
await input.click()
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await select.click()
await option.filter({ hasText: '双皮奶' }).click()
await expect(cacheValue).toContainText(['选项2'])
})

View File

@ -47,6 +47,9 @@ export default {
MemorizeInstance.updateByKey(value)
this.cacheValue = window.localStorage.getItem('tiny_memorize_test456')
}
},
mounted() {
window.localStorage.setItem('tiny_memorize_test456', '')
}
}
</script>

View File

@ -2,18 +2,24 @@ import { test, expect } from '@playwright/test'
test('multiple-limit', async ({ page }) => {
await page.goto('select#multiple-limit')
const select = page.locator('#preview .tiny-select')
const wrap = page.locator('#multiple-limit')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const tag = select.locator('.tiny-tag')
await select.click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await page.waitForTimeout(2000)
const listitems = await page
.locator('.tiny-select-dropdown')
.getByRole('listitem')
.filter({ hasNotText: /黄金糕|双皮奶/ })
await option.nth(0).click()
await option.nth(1).click()
await expect(tag).toHaveCount(2)
await expect(option.filter({ hasText: '全部' })).toHaveCount(0)
await expect(listitems.nth(0)).toHaveClass(/is-disabled/)
await expect(listitems.nth(1)).toHaveClass(/is-disabled/)
await expect(listitems.nth(2)).toHaveClass(/is-disabled/)
const list = await option.all()
list.forEach(async (item, index) => {
if (index <= 1) {
await expect(item).toHaveClass(/selected/)
} else {
await expect(item).toHaveClass(/is-disabled/)
}
})
})

View File

@ -2,18 +2,22 @@ import { expect, test } from '@playwright/test'
test('test', async ({ page }) => {
await page.goto('select#multiple')
const select = page.locator('#preview .tiny-select')
const wrap = page.locator('#multiple')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const tag = select.locator('.tiny-tag')
await expect(select.locator('.tiny-tag')).toHaveCount(2)
await select.click()
await page.getByRole('listitem').filter({ hasText: '全部' }).click()
await expect(select.locator('.tiny-tag')).toHaveCount(7)
await page.getByRole('listitem').filter({ hasText: '全部' }).click()
await expect(select.locator('.tiny-tag')).toHaveCount(0)
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await expect(select.locator('.tiny-tag')).toHaveCount(1)
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await expect(select.locator('.tiny-tag')).toHaveCount(2)
await select.locator('.tiny-tag').filter({ hasText: '双皮奶' }).getByRole('img').click()
await expect(select.locator('.tiny-tag')).toHaveCount(1)
await expect(tag).toHaveCount(2)
await select.locator('.tiny-input__suffix').click()
await option.filter({ hasText: '全部' }).click()
await expect(tag).toHaveCount(7)
await option.filter({ hasText: '全部' }).click()
await expect(tag).toHaveCount(0)
await option.filter({ hasText: '黄金糕' }).click()
await expect(tag).toHaveCount(1)
await option.filter({ hasText: '双皮奶' }).click()
await expect(tag).toHaveCount(2)
await tag.filter({ hasText: '双皮奶' }).locator('.tiny-tag__close').click()
await expect(tag).toHaveCount(1)
})

View File

@ -1,23 +1,15 @@
import { test, expect } from '@playwright/test'
test('name', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/name')
test('原生属性', async ({ page }) => {
await page.goto('select#native-properties')
const wrap = page.locator('#native-properties')
const select = wrap.locator('.tiny-select')
const input = select.locator('.tiny-input__inner')
const input = page.locator('#preview .tiny-input__inner')
await expect(input).toHaveAttribute('name', 'inputName')
})
test('placeholder', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/name')
const input = page.locator('#preview .tiny-input__inner')
await expect(input).toHaveAttribute('placeholder', '自定义 placeholder')
const isHasAutocomplete = await input.evaluate((input) => input.hasAttribute('autocomplete'))
await expect(isHasAutocomplete).toBe(true)
})
test('autocomplete', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/name')
const input = page.locator('#preview .tiny-input__inner')
await expect(input).toHaveAttribute('autocomplete', 'off')
})

View File

@ -1,26 +1,44 @@
<template>
<div class="demo-select">
<p>场景1嵌套表格单选</p>
<tiny-select
ref="selectRef"
v-model="radioValue"
:filter-method="filter"
clearable
filterable
v-model="value1"
value-field="id"
:multiple="false"
text-field="city"
render-type="grid"
:grid-op="gridOpRadio"
:grid-op="gridOpSingle"
></tiny-select>
<p>场景2嵌套表格多选</p>
<tiny-select
v-model="value2"
multiple
value-field="id"
text-field="city"
render-type="grid"
:grid-op="gridOpMulti"
></tiny-select>
<p>场景3嵌套表格 + 可搜索 + 可清除</p>
<tiny-select
ref="select"
v-model="value3"
filterable
:filter-method="filter"
clearable
value-field="id"
text-field="city"
render-type="grid"
:grid-op="gridOpSingle"
></tiny-select>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ref, reactive } from 'vue'
import { Select as TinySelect } from '@opentiny/vue'
const radioValue = ref('')
const gridOpRadio = ref({
const gridOpSingle = reactive({
data: [
{ id: '001', area: '华南区', province: '广东省', city: '深圳1' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
@ -36,19 +54,39 @@ const gridOpRadio = ref({
]
})
const gridOpMulti = reactive({
data: [
{ id: '001', area: '华南区', province: '广东省', city: '深圳1' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'selection', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
})
const filter = (value) => {
if (!value) {
return gridOpRadio.value.data
return gridOpSingle.value.data
}
return gridOpRadio.value.data.filter((item) => {
return gridOpSingle.value.data.filter((item) => {
return item.city.includes(value)
})
}
</script>
<style scoped>
.demo-select .tiny-select {
width: 270px;
<style lang="less" scoped>
.tiny-select {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
}
</style>

View File

@ -1,27 +1,39 @@
import { test, expect } from '@playwright/test'
test('test-grid-select', async ({ page }) => {
await page.goto('select#disable-grid-select-radio')
const tags = page.locator('.grid-select .tiny-tag')
test('嵌套表格禁用某项(单选)', async ({ page }) => {
await page.goto('select#nest-grid-disable')
const wrap = page.locator('#nest-grid-disable')
await page.locator('.tiny-select__tags').click()
await page.getByRole('row', { name: '华南区 广东省 广州市' }).getByRole('cell').first().click()
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
await expect(tags.filter({ hasText: '广州市' })).toHaveCount(1)
await page.getByRole('row', { name: '华南区 广东省 深圳市' }).getByRole('cell').first().click()
await expect(tags.filter({ hasText: '深圳市' })).toHaveCount(0)
await select.click()
await expect(dropdown.locator('.tiny-grid-radio.is__disabled')).toHaveCount(3)
await expect(input).toHaveValue('')
await dropdown.getByRole('row').nth(1).getByRole('cell').first().click()
await expect(input).toHaveValue('')
await dropdown.getByRole('row').nth(2).getByRole('cell').first().click()
await expect(input).toHaveValue('深圳市')
})
test('test-grid-radio', async ({ page }) => {
await page.goto('select#disable-grid-select-radio')
test('嵌套表格禁用某项(多选)', async ({ page }) => {
await page.goto('select#nest-grid-disable')
const input = page.locator('.grid-radio .tiny-input__inner')
await input.click()
await page.getByRole('row', { name: '华南区 广东省 深圳市' }).getByRole('cell').first().click()
await expect(page.getByPlaceholder('请选择').nth(1)).toHaveValue('深圳市')
await input.click()
await page.getByRole('row', { name: '华南区 广东省 广州市' }).getByRole('cell').first().click()
await expect(page.getByPlaceholder('请选择').nth(1)).toHaveValue('深圳市')
await page.getByRole('row', { name: '华南区 广东省 佛山市' }).getByRole('cell').first().click()
await expect(page.getByPlaceholder('请选择').nth(1)).toHaveValue('佛山市')
const wrap = page.locator('#nest-grid-disable')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const tag = select.locator('.tiny-tag')
await select.click()
await dropdown.getByRole('row').nth(2).getByRole('cell').first().click()
await expect(tag).toHaveCount(0)
await dropdown.getByRole('row').nth(1).getByRole('cell').first().click()
await expect(tag).toHaveCount(1)
await dropdown.getByRole('row').nth(4).getByRole('cell').first().click()
await expect(tag).toHaveCount(1)
})

View File

@ -1,58 +0,0 @@
import { expect, test } from '@playwright/test'
test('remote-method', async ({ page }) => {
await page.goto('select#nest-grid-remote-filter')
const input = page.getByRole('textbox').nth(1)
const suffixSvg = page.locator('.tiny-input__suffix .tiny-select__caret').first()
await expect(suffixSvg).toBeHidden()
const dropdown = page.locator('.grid-remote')
await expect(dropdown).toBeHidden()
await input.fill(' ')
await input.press('Enter')
await page.waitForTimeout(1000)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).toBeEmpty()
await input.fill('')
await input.press('Enter')
await page.waitForTimeout(1000)
await expect(dropdown.locator('.tiny-grid__body tbody')).not.toBeEmpty()
await page.getByRole('row', { name: '华南区0 广东省0 广州市0' }).getByRole('cell').first().click()
const tags = page.locator('.tiny-select .tiny-tag')
await expect((await tags.all()).length).toEqual(1)
await expect(tags.first()).toContainText(/广州市0/)
await page.getByRole('row', { name: '华南区1 广东省1 广州市1' }).getByRole('cell').first().click()
await expect((await tags.all()).length).toEqual(2)
await expect(tags.first()).toContainText(/广州市0/)
await expect(tags.nth(1)).toContainText(/广州市1/)
})
test('remote-config', async ({ page }) => {
await page.goto('select#nest-grid-remote-filter')
const input = page.getByRole('textbox').nth(3)
const suffixSvg = page.locator('.tiny-input__suffix .tiny-select__caret').nth(1)
await expect(suffixSvg).toBeVisible()
const dropdown = page.locator('.grid-remote-config')
await expect(dropdown).toBeHidden()
await input.click()
await page.waitForTimeout(1000)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).not.toBeEmpty()
await page.getByRole('row', { name: '华南区0 广东省0 广州市0' }).getByRole('cell').first().click()
const tags = page.locator('.tiny-select .tiny-tag')
await expect((await tags.all()).length).toEqual(1)
await expect(tags.first()).toContainText(/广州市0/)
await page.getByRole('row', { name: '华南区1 广东省1 广州市1' }).getByRole('cell').first().click()
await expect((await tags.all()).length).toEqual(2)
await expect(tags.first()).toContainText(/广州市0/)
await expect(tags.nth(1)).toContainText(/广州市1/)
await tags.nth(0).locator('.tiny-svg').click()
await tags.nth(0).locator('.tiny-svg').click()
await expect((await tags.all()).length).toEqual(0)
await input.fill(' ')
await input.press('Enter')
await page.waitForTimeout(1000)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).toBeEmpty()
})

View File

@ -25,7 +25,7 @@
filterable
remote
:remote-method="remoteMethod"
:remote-config="{ autoSeach: true, clearData: true, showIcon: true }"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
value-field="id"
text-field="city"
render-type="grid"

View File

@ -0,0 +1,66 @@
import { expect, test } from '@playwright/test'
test('下拉表格远程搜索基础用法', async ({ page }) => {
await page.goto('select#nest-grid-remote-multi')
const wrap = page.locator('#nest-grid-remote-multi')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-select__input')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-input__suffix .tiny-select__caret').first()
// 下拉按钮不显示
await expect(suffixSvg).toBeHidden()
await expect(dropdown).toBeHidden()
await input.fill(' ')
await input.press('Enter')
await page.waitForTimeout(1000)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).toBeEmpty()
await input.fill('')
await input.press('Enter')
await page.waitForTimeout(1000)
await expect(dropdown.locator('.tiny-grid__body tbody')).not.toBeEmpty()
await page.getByRole('row', { name: '华南区0 广东省0 广州市0' }).getByRole('cell').first().click()
const tags = page.locator('.tiny-select .tiny-tag')
await expect((await tags.all()).length).toEqual(1)
await expect(tags.first()).toContainText(/广州市0/)
await page.getByRole('row', { name: '华南区1 广东省1 广州市1' }).getByRole('cell').first().click()
await expect((await tags.all()).length).toEqual(2)
await expect(tags.first()).toContainText(/广州市0/)
await expect(tags.nth(1)).toContainText(/广州市1/)
})
test('下拉表格远程搜索 + 自动搜索 + 显示按钮', async ({ page }) => {
await page.goto('select#nest-grid-remote-multi')
const wrap = page.locator('#nest-grid-remote-multi')
const select = wrap.locator('.tiny-select').nth(1)
const input = select.locator('.tiny-select__input')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-input__suffix .tiny-select__caret').first()
const tag = select.locator('.tiny-tag')
await expect(suffixSvg).toBeVisible()
await expect(dropdown).toBeHidden()
await select.click()
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).not.toBeEmpty()
await dropdown.getByRole('row', { name: '华南区0 广东省0 广州市0' }).getByRole('cell').first().click()
await expect((await tag.all()).length).toEqual(1)
await expect(tag.first()).toContainText(/广州市0/)
await dropdown.getByRole('row', { name: '华南区1 广东省1 广州市1' }).getByRole('cell').first().click()
await expect((await tag.all()).length).toEqual(2)
await expect(tag.first()).toContainText(/广州市0/)
await expect(tag.nth(1)).toContainText(/广州市1/)
await tag.nth(0).locator('.tiny-svg').click()
await tag.nth(0).locator('.tiny-svg').click()
await expect((await tag.all()).length).toEqual(0)
await input.fill(' ')
await input.press('Enter')
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).toBeEmpty()
})

View File

@ -27,7 +27,7 @@
filterable
remote
:remote-method="remoteMethod"
:remote-config="{ autoSeach: true, clearData: true, showIcon: true }"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
value-field="id"
text-field="city"
render-type="grid"

View File

@ -4,7 +4,7 @@
<tiny-select
v-model="radioValue"
placeholder="请输入关键词"
reserve-keyword
filterable
remote
:remote-method="remoteMethod"
value-field="coaNumber"
@ -17,11 +17,10 @@
<tiny-select
v-model="radioValue"
placeholder="请输入关键词"
reserve-keyword
filterable
remote
:remote-method="remoteMethod"
:remote-config="{ autoSeach: true, clearData: true, showIcon: true }"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
value-field="coaNumber"
text-field="coaNumber"
render-type="grid"

View File

@ -1,22 +1,25 @@
import { expect, test } from '@playwright/test'
test('nest-remote-method', async ({ page }) => {
await page.goto('select#nest-remote-grid')
const input = page.locator('#preview .tiny-input__inner').first()
const suffixSvg = page.locator('.tiny-input__suffix .tiny-select__caret').first()
test('下拉表格远程搜索基础用法', async ({ page }) => {
await page.goto('select#nest-grid-remote-single')
const wrap = page.locator('#nest-grid-remote-single')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = dropdown.locator('.tiny-input__suffix .tiny-select__caret')
await expect(suffixSvg).toBeHidden()
const dropdown = page.locator('.grid-remote')
await expect(dropdown).toBeHidden()
await input.focus()
await input.fill(' ')
await input.press('Enter')
await page.waitForTimeout(1000)
await page.waitForTimeout(200)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).toBeEmpty()
await input.fill('')
await input.press('Enter')
await page.waitForTimeout(1000)
await page.waitForTimeout(200)
await expect(dropdown.locator('.tiny-grid__body tbody')).not.toBeEmpty()
await page.getByRole('row', { name: '5100000' }).locator('div').first().click()
await expect(input).toHaveValue('5100000')
@ -28,16 +31,18 @@ test('nest-remote-method', async ({ page }) => {
await expect(page.getByRole('row', { name: '5900003' })).toHaveClass(/row__current/)
})
test('nest-remote-config', async ({ page }) => {
await page.goto('select#nest-remote-grid')
const input = page.locator('#preview .tiny-input__inner').nth(1)
const suffixSvg = page.locator('.tiny-input__suffix .tiny-select__caret').nth(1)
test('下拉表格远程搜索 + 自动搜索 + 显示按钮', async ({ page }) => {
await page.goto('select#nest-grid-remote-single')
const wrap = page.locator('#nest-grid-remote-single')
const select = wrap.locator('.tiny-select').nth(1)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-input__suffix .tiny-select__caret')
await expect(suffixSvg).toBeVisible()
const dropdown = page.locator('.grid-remote-config')
await expect(dropdown).toBeHidden()
await input.click()
await page.waitForTimeout(1000)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).not.toBeEmpty()
await page.getByRole('row', { name: '5100000' }).getByRole('cell').first().click()
@ -50,7 +55,6 @@ test('nest-remote-config', async ({ page }) => {
await expect(page.getByRole('row', { name: '5900003' })).toHaveClass(/row__current/)
await input.fill(' ')
await input.press('Enter')
await page.waitForTimeout(1000)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).toBeEmpty()
})

View File

@ -4,6 +4,7 @@
<tiny-select
v-model="radioValue"
placeholder="请输入关键词"
filterable
remote
:remote-method="remoteMethod"
value-field="coaNumber"
@ -19,7 +20,7 @@
filterable
remote
:remote-method="remoteMethod"
:remote-config="{ autoSeach: true, clearData: true, showIcon: true }"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
value-field="coaNumber"
text-field="coaNumber"
render-type="grid"

View File

@ -1,94 +1,92 @@
import { test, expect } from '@playwright/test'
test('grid-filterable', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/nest-checkbox-grid-clearable')
const input = page.locator('#preview .tiny-input__inner')
test('嵌套表格(单选)', async ({ page }) => {
await page.goto('select#nest-grid')
await input.click()
await page.waitForTimeout(500)
const tr = page.locator('.tiny-select-dropdown .tiny-grid__body-wrapper .tiny-grid-body__row')
await expect(tr).toHaveCount(5)
await input.fill('深圳')
await input.press('Enter')
await page.waitForTimeout(500)
await expect(tr).toHaveCount(2)
await page.getByRole('row', { name: '华南区 广东省 深圳1' }).getByRole('cell').first().click()
await expect(input).toHaveValue('深圳1')
await input.click()
await page.waitForTimeout(500)
await expect(tr.filter({ hasText: '深圳1' })).toHaveClass(/row__current/)
})
test('grid-clearable', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/nest-checkbox-grid-clearable')
const input = page.locator('#preview .tiny-input__inner')
const suffix = page.locator('#preview .tiny-input__suffix')
await input.click()
await page.waitForTimeout(500)
const tr = page.locator('.tiny-select-dropdown .tiny-grid__body-wrapper .tiny-grid-body__row')
await expect(tr).toHaveCount(5)
await input.fill('深圳')
await input.press('Enter')
await page.waitForTimeout(500)
await expect(tr).toHaveCount(2)
await page.getByRole('row', { name: '华南区 广东省 深圳1' }).getByRole('cell').first().click()
await expect(input).toHaveValue('深圳1')
await input.hover()
await suffix.click()
await expect(input).toHaveValue('')
})
// 嵌套表格单选
test('radio-grid', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/nest-radio-grid')
const input = page.locator('#preview .tiny-input__inner')
const suffixSvg = await page.locator('#preview .tiny-select__caret').first()
const wrap = page.locator('#nest-grid')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-select__caret')
const row = dropdown.getByRole('row')
await expect(suffixSvg).toHaveCount(1)
await expect(suffixSvg).toBeVisible()
await input.click()
await page.getByRole('row', { name: '华南区 广东省 广州市' }).getByRole('cell').first().click()
await page.waitForTimeout(1000)
await expect(input).toHaveValue('广州市')
await expect(dropdown).toBeVisible()
await expect(row).toHaveCount(6)
await row.nth(1).getByRole('cell').first().click()
await expect(input).toHaveValue('深圳1')
await input.click()
await page.getByRole('row', { name: '华南区 广东省 深圳市' }).getByRole('cell').first().click()
await page.waitForTimeout(1000)
await expect(input).toHaveValue('深圳市')
await expect(row.filter({ hasText: '深圳1' })).toHaveClass(/row__current/)
})
// 嵌套表格多选
test('grid-multiple', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/nest-checkbox-grid')
const suffix = page.locator('#preview .tiny-input__suffix')
const select = page.locator('#preview .tiny-select')
test('嵌套表格(多选)', async ({ page }) => {
await page.goto('select#nest-grid')
const wrap = page.locator('#nest-grid')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-select__caret')
const row = dropdown.getByRole('row')
const tag = select.locator('.tiny-tag')
const currentRow = dropdown.locator('.row__selected')
await expect(tag).toHaveCount(2)
await suffix.click()
await page.waitForTimeout(500)
const tr = page.locator('.tiny-select-dropdown .tiny-grid__body-wrapper .tiny-grid-body__row')
const currentTr = page.locator('.tiny-select-dropdown .tiny-grid__body-wrapper .row__selected')
await expect(tr).toHaveCount(5)
await expect(currentTr).toHaveCount(2)
await page.getByRole('row', { name: '华南区 广东省 珠海市' }).getByRole('cell').first().click()
await expect(tag).toHaveCount(3)
await expect(currentTr).toHaveCount(3)
await page.getByRole('row', { name: '华南区 广东省 珠海市' }).getByRole('cell').first().click()
await expect(tag).toHaveCount(2)
await expect(currentTr).toHaveCount(2)
await page.getByRole('row', { name: '区域 省份 城市' }).getByRole('cell').first().click()
await expect(tag).toHaveCount(5)
await expect(currentTr).toHaveCount(5)
let all = await page.getByRole('row', { name: '区域 省份 城市' }).locator('.tiny-grid-checkbox__icon .tiny-svg')
await expect(all).toHaveClass(/icon-checked-sur/)
await page.getByRole('row', { name: '区域 省份 城市' }).getByRole('cell').first().click()
await page.waitForTimeout(500)
await expect(all).toBeHidden()
await expect(tag).toHaveCount(0)
await expect(currentTr).toHaveCount(0)
await suffixSvg.click()
await expect(row).toHaveCount(6)
await expect(currentRow).toHaveCount(0)
await expect(row.nth(0).getByRole('cell').first().locator('.icon-half-select')).toBeHidden()
await expect(row.nth(0).getByRole('cell').first().locator('.icon-checked-sur')).toBeHidden()
await row.nth(1).getByRole('cell').first().click()
await row.nth(2).getByRole('cell').first().click()
await row.nth(3).getByRole('cell').first().click()
await expect(tag).toHaveCount(3)
await expect(currentRow).toHaveCount(3)
await expect(row.nth(0).getByRole('cell').first().locator('.icon-half-select')).toBeVisible()
await row.nth(0).getByRole('cell').first().click()
await expect(tag).toHaveCount(5)
await expect(currentRow).toHaveCount(5)
await expect(row.nth(0).getByRole('cell').first().locator('.icon-checked-sur')).toBeVisible()
await row.nth(0).getByRole('cell').first().click()
await expect(tag).toHaveCount(0)
await expect(currentRow).toHaveCount(0)
await expect(row.nth(0).getByRole('cell').first().locator('.icon-half-select')).toBeHidden()
await expect(row.nth(0).getByRole('cell').first().locator('.icon-checked-sur')).toBeHidden()
})
test('嵌套表格 + 可搜索 + 可清除', async ({ page }) => {
await page.goto('select#nest-grid')
const wrap = page.locator('#nest-grid')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-select__caret')
const row = dropdown.getByRole('row')
await input.click()
// 可搜索
await expect(row).toHaveCount(6)
await input.fill('深圳')
await input.press('Enter')
await page.waitForTimeout(200)
await expect(row).toHaveCount(3)
await row.nth(1).getByRole('cell').first().click()
await expect(input).toHaveValue('深圳1')
await input.click()
await page.waitForTimeout(200)
await expect(row.filter({ hasText: '深圳1' })).toHaveClass(/row__current/)
await page.waitForTimeout(200)
// 可清除
await input.hover()
await suffixSvg.nth(0).click()
await expect(input).toHaveValue('')
})

View File

@ -6,15 +6,16 @@
value-field="id"
text-field="city"
render-type="grid"
:grid-op="gridOpRadio"
:grid-op="gridOpSingle"
></tiny-select>
<p>场景2嵌套表格多选</p>
<tiny-select
v-model="value2"
multiple
value-field="id"
text-field="city"
render-type="grid"
:grid-op="gridOpRadio"
:grid-op="gridOpMulti"
></tiny-select>
<p>场景3嵌套表格 + 可搜索 + 可清除</p>
<tiny-select
@ -26,7 +27,7 @@
value-field="id"
text-field="city"
render-type="grid"
:grid-op="gridOpRadio"
:grid-op="gridOpSingle"
></tiny-select>
</div>
</template>
@ -41,10 +42,10 @@ export default {
methods: {
filter(value) {
if (!value) {
return this.gridOpRadio.data
return this.gridOpSingle.data
}
return this.gridOpRadio.data.filter((item) => {
return this.gridOpSingle.data.filter((item) => {
return item.city.includes(value)
})
}
@ -54,7 +55,7 @@ export default {
value1: '',
value2: [],
value3: '',
gridOpRadio: {
gridOpSingle: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '深圳1' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
@ -68,6 +69,21 @@ export default {
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
},
gridOpMulti: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '深圳1' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'selection', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
}
}
}

View File

@ -1,30 +1,33 @@
import { expect, test } from '@playwright/test'
test('grid-much-data', async ({ page }) => {
test('下拉表格大数据', async ({ page }) => {
await page.goto('select#nest-radio-grid-much-data')
const input = page.locator('#preview .tiny-input__inner')
const suffixSvg = await page.locator('#preview .tiny-select__caret').first()
const wrap = page.locator('#nest-radio-grid-much-data')
const select = wrap.locator('.tiny-select')
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-input__suffix .tiny-select__caret')
const row = dropdown.getByRole('row')
await expect(suffixSvg).toHaveCount(1)
await expect(suffixSvg).toBeVisible()
const dropdown = page.locator('.tiny-select-dropdown')
await expect(dropdown).toBeHidden()
await input.click()
await page.waitForTimeout(1000)
await expect(dropdown).toBeVisible()
await expect(dropdown.locator('.tiny-grid__body tbody')).not.toBeEmpty()
await page.getByRole('row', { name: '华南区0 广东省 广州市' }).getByRole('cell').first().click()
await row.nth(1).getByRole('cell').first().click()
await expect(input).toHaveValue('广州市')
await input.click()
await page.waitForTimeout(1000)
await expect(dropdown.locator('.tiny-grid-body__row').first()).toHaveClass(/row__current/)
await expect((await dropdown.locator('.tiny-grid-body__row').all()).length).toEqual(7)
await expect(page.getByRole('row', { name: '华南区12 广东省 广州市' })).not.toBeInViewport()
await dropdown.locator('.tiny-grid-body__row').nth(6).scrollIntoViewIfNeeded()
await expect((await dropdown.locator('.tiny-grid-body__row').all()).length).toEqual(7)
await page.waitForTimeout(1000)
await dropdown.locator('.tiny-grid-body__row').nth(6).scrollIntoViewIfNeeded()
await expect((await dropdown.locator('.tiny-grid-body__row').all()).length).toEqual(7)
await page.waitForTimeout(1000)
await page.waitForTimeout(200)
await expect(row.nth(1)).toHaveClass(/row__current/)
await expect(row).toHaveCount(8)
await expect(page.getByRole('row', { name: '华南区12 广东省 广州市' })).toBeHidden()
await row.nth(7).scrollIntoViewIfNeeded()
await expect(row).toHaveCount(8)
await row.nth(7).scrollIntoViewIfNeeded()
await expect(row).toHaveCount(8)
await page.getByRole('row', { name: '华南区12 广东省 广州市' }).getByRole('cell').first().click()
})

View File

@ -1,76 +1,81 @@
import { test, expect } from '@playwright/test'
test('radio-tree', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/nest-radio-tree')
const input = page.locator('#preview .tiny-input__inner')
const suffixSvg = await page.locator('#preview .tiny-select__caret').first()
test('下拉树单选', async ({ page }) => {
await page.goto('select#nest-tree')
const wrap = page.locator('#nest-tree')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-input__suffix .tiny-select__caret')
const treeNode = dropdown.locator('.tiny-tree-node')
await expect(suffixSvg).toHaveCount(1)
await expect(suffixSvg).toBeVisible()
await expect(input).toHaveValue('三级 1-1-2')
await input.click()
await page.waitForTimeout(1000)
await expect(page.getByRole('treeitem', { name: '三级 1-1-2' })).toHaveClass(/is-current/)
await page.getByRole('treeitem', { name: '二级 2-1' }).locator('div').filter({ hasText: '二级 2-1' }).click()
await page.waitForTimeout(1000)
await expect(treeNode.filter({ hasText: /^三级 1-1-2$/ })).toHaveClass(/is-current/)
await treeNode.filter({ hasText: /^二级 2-1$/ }).click()
await expect(input).toHaveValue('二级 2-1')
await input.click()
await page.waitForTimeout(1000)
await expect(page.getByRole('treeitem', { name: '二级 2-1' })).toHaveClass(/is-current/)
await expect(treeNode.filter({ hasText: /^二级 2-1$/ })).toHaveClass(/is-current/)
})
test('tree-multiple', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/nest-checkbox-tree')
const suffix = page.locator('#preview .tiny-input__suffix')
const select = page.locator('#preview .tiny-select')
const selectDropdown = page.locator('.tiny-select-dropdown')
test('下拉树多选', async ({ page }) => {
await page.goto('select#nest-tree')
const wrap = page.locator('#nest-tree')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const suffixSvg = select.locator('.tiny-input__suffix .tiny-select__caret')
const treeNode = dropdown.locator('.tiny-tree-node')
const checkedTreeNodes = dropdown.locator('.tiny-tree-node.is-checked')
const tag = select.locator('.tiny-tag')
await expect(tag).toHaveCount(2)
await suffix.click()
await page.waitForTimeout(500)
const treeNodes = selectDropdown.getByRole('treeitem')
const checkedTreeNodes = selectDropdown.locator('.tiny-tree-node.is-checked')
await page.waitForTimeout(500)
await expect(checkedTreeNodes).toHaveCount(4)
await expect(treeNodes).toHaveCount(7)
await suffixSvg.click()
await expect(checkedTreeNodes).toHaveCount(2)
await expect(treeNode).toHaveCount(7)
await page
.locator('div')
.filter({ hasText: /^一级 2$/ })
.locator('.tiny-checkbox')
.click()
await page.waitForTimeout(500)
await expect(checkedTreeNodes).toHaveCount(7)
await expect(tag).toHaveCount(7)
await expect(checkedTreeNodes).toHaveCount(4)
await expect(tag).toHaveCount(4)
})
test('下拉树可搜索', async ({ page }) => {
await page.goto('select#nest-tree')
test('filterable-tree', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/nest-filterable-tree')
const input = page.locator('#preview .tiny-input__inner')
const selectDropdown = page.locator('.tiny-select-dropdown')
const wrap = page.locator('#nest-tree')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const treeNode = dropdown.locator('.tiny-tree-node')
const hiddenTreeNodes = dropdown.locator('.tiny-tree-node.is-hidden')
const checkedTreeNodes = dropdown.locator('.tiny-tree-node.is-current')
await expect(input).toHaveValue('')
await expect(selectDropdown).toBeHidden()
await expect(dropdown).toBeHidden()
await input.click()
await page.waitForTimeout(500)
const treeNodes = selectDropdown.getByRole('treeitem')
await expect(treeNodes).toHaveCount(7)
await expect(treeNode).toHaveCount(7)
await input.fill('2-')
await input.press('Enter')
await page.waitForTimeout(500)
const hiddenTreeNodes = selectDropdown.locator('.tiny-tree-node.is-hidden')
await expect(hiddenTreeNodes).toHaveCount(4)
const checkedTreeNodes = selectDropdown.locator('.tiny-tree-node.is-checked')
await expect(checkedTreeNodes).toHaveCount(0)
await page.getByRole('treeitem', { name: '一级 2' }).locator('div').filter({ hasText: '一级 2' }).click()
await page.waitForTimeout(500)
await expect(selectDropdown).toBeHidden()
await page.waitForTimeout(1000)
await expect(input).toHaveValue('一级 2')
await treeNode.getByText(/^一级 2$/).click()
await expect(dropdown).toBeHidden()
await expect(input).toHaveValue('一级 2')
await input.click()
await page.waitForTimeout(1000)
await expect(checkedTreeNodes).toHaveCount(3)
await expect(page.locator('.is-current .tiny-tree-node__content')).toHaveText('二级 2-2')
await expect(checkedTreeNodes.locator('.tiny-tree-node__content').nth(0)).toHaveText(/^一级 2$/)
})

View File

@ -1,20 +1,36 @@
import { test, expect } from '@playwright/test'
test('no-data-text', async ({ page }) => {
test('默认空数据文本', async ({ page }) => {
await page.goto('select#no-data-text')
const input = page.locator('#preview .tiny-input__inner').first()
const wrap = page.locator('#no-data-text')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
await input.click()
await page.waitForTimeout(1000)
await expect(page.locator('body>.tiny-select-dropdown .tiny-select-dropdown__empty')).toHaveText('None')
await expect(dropdown.locator('.tiny-select-dropdown__empty')).toHaveText('暂无相关数据')
})
test('show-empty-image', async ({ page }) => {
test('自定义空数据文本', async ({ page }) => {
await page.goto('select#no-data-text')
const input = page.locator('#preview .tiny-input__inner').nth(1)
const wrap = page.locator('#no-data-text')
const select = wrap.locator('.tiny-select').nth(1)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
await input.click()
await page.waitForTimeout(1000)
await expect(page.locator('body>.tiny-select-dropdown .tiny-select-dropdown__empty')).toHaveText('暂无数据')
await expect(page.locator('.tiny-select-dropdown__empty-images')).toBeVisible()
await expect(dropdown.locator('.tiny-select-dropdown__empty')).toHaveText('None')
})
test('显示空数据图片', async ({ page }) => {
await page.goto('select#no-data-text')
const wrap = page.locator('#no-data-text')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
await input.click()
await expect(dropdown.locator('.tiny-select-dropdown__empty-images')).toBeVisible()
})

View File

@ -1,44 +1,48 @@
import { test, expect } from '@playwright/test'
test('radio-optimization', async ({ page }) => {
test('单选虚拟滚动', async ({ page }) => {
await page.goto('select#optimization')
const select = page.locator('#preview .tiny-select').first()
const input = page.locator('#preview .tiny-input__inner').first()
const wrap = page.locator('#optimization')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await select.click()
await expect((await option.all()).length).toEqual(10)
await expect(option.filter({ hasText: '黄金糕17' })).toBeHidden()
await option.nth(9).scrollIntoViewIfNeeded()
await page.waitForTimeout(1000)
const options = page.locator('.tiny-select-dropdown__list').getByRole('listitem')
await page.waitForTimeout(1000)
await expect((await options.all()).length).toEqual(10)
await expect(options.filter({ hasText: '黄金糕17' })).not.toBeInViewport()
await options.nth(9).scrollIntoViewIfNeeded()
await page.waitForTimeout(1000)
await options.nth(9).scrollIntoViewIfNeeded()
await expect(options.filter({ hasText: '黄金糕17' })).toBeInViewport()
await options.filter({ hasText: '黄金糕17' }).click()
await expect(option.filter({ hasText: '黄金糕17' })).toBeHidden()
await option.nth(9).scrollIntoViewIfNeeded()
await option.filter({ hasText: '黄金糕17' }).click()
await expect(input).toHaveValue('黄金糕17')
})
test('select-optimization', async ({ page }) => {
test('多选虚拟滚动', async ({ page }) => {
await page.goto('select#optimization')
const select = page.locator('#preview .tiny-select').nth(1)
const tags = page.locator('#preview .tiny-select .tiny-tag')
const wrap = page.locator('#optimization')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const tag = page.locator('#preview .tiny-select .tiny-tag')
await select.click()
await expect((await option.all()).length).toEqual(10)
await expect(option.filter({ hasText: '黄金糕17' })).toBeHidden()
await expect(option.filter({ hasText: '黄金糕16' })).toBeHidden()
await page.waitForTimeout(500)
await option.nth(9).scrollIntoViewIfNeeded()
await page.waitForTimeout(1000)
const options = page.locator('.tiny-select-dropdown__list').getByRole('listitem')
await expect((await options.all()).length).toEqual(10)
await expect(options.filter({ hasText: '黄金糕17' })).not.toBeInViewport()
await expect(options.filter({ hasText: '黄金糕16' })).not.toBeInViewport()
await options.nth(9).scrollIntoViewIfNeeded()
await page.waitForTimeout(1000)
await options.nth(9).scrollIntoViewIfNeeded()
await expect(options.filter({ hasText: '黄金糕16' })).toBeInViewport()
await expect(options.filter({ hasText: '黄金糕17' })).toBeInViewport()
await options.filter({ hasText: '黄金糕17' }).click()
await expect(tags.first()).toHaveText('黄金糕17')
await expect((await tags.all()).length).toEqual(1)
await options.filter({ hasText: '黄金糕16' }).click()
await expect((await tags.all()).length).toEqual(2)
await expect(tags.nth(1)).toHaveText('+ 1')
await option.nth(9).scrollIntoViewIfNeeded()
await expect(option.filter({ hasText: '黄金糕16' })).toBeVisible()
await expect(option.filter({ hasText: '黄金糕17' })).toBeVisible()
// TODO: 修改多选虚拟滚动后打开
// await option.filter({ hasText: '黄金糕17' }).click()
// await expect(tag.first()).toHaveText('黄金糕17')
// await expect((await tag.all()).length).toEqual(1)
// await option.filter({ hasText: '黄金糕16' }).click()
// await expect((await tag.all()).length).toEqual(2)
// await expect(tag.nth(1)).toHaveText('+ 1')
})

View File

@ -2,11 +2,20 @@ import { test, expect } from '@playwright/test'
test('option-group', async ({ page }) => {
await page.goto('select#option-group')
const select = page.locator('#preview .tiny-select')
const wrap = page.locator('#option-group')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const title = dropdown.locator('.tiny-option-group__title')
const group = dropdown.locator('.tiny-option-group ')
await select.click()
const listitems = page.locator('.tiny-option')
await expect(listitems.filter({ hasText: '上海' })).toHaveClass(/is-disabled/)
await expect(listitems.filter({ hasText: '北京' })).toHaveClass(/is-disabled/)
const groups = page.locator('.tiny-option-group')
await expect((await groups.all()).length).toEqual(2)
await expect(title.nth(0)).toHaveText('热门城市')
await expect(title.nth(1)).toHaveText('城市名')
await expect(option.filter({ hasText: '上海' })).toHaveClass(/is-disabled/)
await expect(option.filter({ hasText: '北京' })).toHaveClass(/is-disabled/)
await expect(group.nth(0).locator('.tiny-option')).toHaveCount(2)
await expect(group.nth(1).locator('.tiny-option')).toHaveCount(4)
await expect((await group.all()).length).toEqual(2)
})

View File

@ -1,28 +1,27 @@
<template>
<div class="demo-select">
<tiny-select v-model="value" popper-class="drop" :popper-append-to-body="false" placement="top">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
</div>
<tiny-select v-model="value" popper-class="drop" :popper-append-to-body="false" placement="top">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
</template>
<script setup>
import { ref } from 'vue'
import { reacitve } from 'vue'
import { Select as TinySelect, Option as TinyOption } from '@opentiny/vue'
const options = ref([
const options = reacitve([
{ value: '选项1', label: '黄金糕' },
{ value: '选项2', label: '双皮奶' },
{ value: '选项3', label: '蚵仔煎' },
{ value: '选项4', label: '龙须面' },
{ value: '选项5', label: '北京烤鸭' }
])
const value = ref('')
const value = reacitve('')
</script>
<style lang="less" scoped>
.tiny-select {
width: 280px;
margin-top: 30px;
}
</style>

View File

@ -2,10 +2,14 @@ import { test, expect } from '@playwright/test'
test('popup-style-position', async ({ page }) => {
await page.goto('select#popup-style-position')
const select = page.locator('#preview .tiny-select')
const wrap = page.locator('#popup-style-position')
const select = wrap.locator('.tiny-select')
const dropdown = select.locator('.tiny-select__tags-group > .tiny-select-dropdown')
await select.click()
const selectDropdown = select.locator('.tiny-select-dropdown')
await expect(selectDropdown).toHaveCount(1)
await expect(selectDropdown).toHaveClass(/drop/)
await expect(dropdown).toHaveCount(1)
await expect(dropdown).toHaveClass(/drop/)
await expect(dropdown).toHaveCSS('background-color', 'rgb(213, 232, 255)')
await expect(dropdown).toHaveAttribute('x-placement', 'top')
})

View File

@ -1,9 +1,7 @@
<template>
<div class="demo-select">
<tiny-select v-model="value" popper-class="drop" :popper-append-to-body="false" placement="top">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
</div>
<tiny-select v-model="value" popper-class="drop" :popper-append-to-body="false" placement="top">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
</template>
<script>
@ -32,6 +30,7 @@ export default {
<style lang="less" scoped>
.tiny-select {
width: 280px;
margin-top: 30px;
}
</style>

View File

@ -1,36 +1,65 @@
import { expect, test } from '@playwright/test'
test('reserve-keyword', async ({ page }) => {
test('远程搜索单选', async ({ page }) => {
await page.goto('select#remote-method')
const tags = page.locator('#preview .tiny-select .tiny-tag')
const searchInput = page.locator('#preview .tiny-select__input')
await searchInput.focus()
await searchInput.press('a')
await page.waitForTimeout(1000)
await page.getByRole('listitem').filter({ hasText: 'Alabama' }).click()
await expect(searchInput).toHaveValue('a')
await expect((await tags.all()).length).toEqual(1)
await searchInput.press('l')
await page.waitForTimeout(1000)
const wrap = page.locator('#remote-method')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const options = page.locator('.tiny-select-dropdown__list .tiny-option')
await input.focus()
await expect(option).toHaveCount(0)
await expect(dropdown.locator('.tiny-select-dropdown__empty')).toBeVisible()
await expect((await options.all()).length).toEqual(3)
await options.filter({ hasText: 'Alaska' }).click()
await page.waitForTimeout(1000)
await expect((await tags.all()).length).toEqual(2)
await expect(searchInput).toHaveValue('al')
await input.fill('al')
await input.press('Enter')
await page.waitForTimeout(800)
await expect((await option.all()).length).toEqual(3)
await option.filter({ hasText: 'Alaska' }).click()
await expect(input).toHaveValue('Alaska')
})
test('远程搜索多选 + 保留搜索关键字', async ({ page }) => {
await page.goto('select#remote-method')
test('focus-remote-method', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/focus-remote-method')
const input = page.locator('#preview .tiny-input__inner')
const wrap = page.locator('#remote-method')
const select = wrap.locator('.tiny-select').nth(1)
const input = select.locator('.tiny-select__input')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const tag = select.locator('.tiny-tag')
await input.focus()
await expect(option).toHaveCount(0)
await input.press('a')
await input.press('Enter')
await page.waitForTimeout(300)
await option.filter({ hasText: 'Alabama' }).click()
await expect(input).toHaveValue('a')
await expect((await tag.all()).length).toEqual(1)
await input.press('l')
await page.waitForTimeout(500)
await expect((await option.all()).length).toEqual(3)
await option.filter({ hasText: 'Alaska' }).click()
await page.waitForTimeout(300)
await expect((await tag.all()).length).toEqual(2)
await expect(input).toHaveValue('al')
})
test('获焦时触发远程搜索', async ({ page }) => {
await page.goto('select#remote-method')
const wrap = page.locator('#remote-method')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await input.click()
const listitems = await page.locator('.tiny-select-dropdown').getByRole('listitem')
await expect(listitems).toHaveCount(0)
await page.waitForTimeout(1000)
await expect(listitems).toHaveCount(50)
await expect(option).toHaveCount(0)
await page.waitForTimeout(300)
await expect(option).toHaveCount(50)
})

View File

@ -1,52 +0,0 @@
import { test, expect } from '@playwright/test'
test('search-allow-copy', async ({ page }) => {
await page.goto('select#search-allow-copy')
const input = page.locator('#preview .tiny-input__inner')
const options = page.locator('.tiny-select-dropdown').locator('.tiny-option')
await input.click()
await input.fill('双皮')
await input.press('Enter')
await page.waitForTimeout(1000)
await page.mouse.move(340, 356)
await page.waitForTimeout(1000)
await page.mouse.down()
await page.waitForTimeout(1000)
await page.mouse.move(278, 356)
await page.waitForTimeout(200)
await page.mouse.up()
await page.keyboard.press('Control+C')
const valueInput = page.locator('.custom')
await expect(valueInput).toHaveValue('')
await valueInput.focus()
await page.keyboard.press('Control+V')
await page.waitForTimeout(200)
await expect(valueInput).toHaveValue('双皮')
})
test('remote-search-allow-copy', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/remote-search-allow-copy')
const input = page.locator('#preview .tiny-input__inner')
const options = page.locator('.tiny-select-dropdown').locator('.tiny-option')
input.press('a')
await page.waitForTimeout(1000)
await options.filter({ hasText: 'Alaska' }).click()
await expect(input).toHaveValue('Alaska')
await page.mouse.move(340, 356)
await page.waitForTimeout(1000)
await page.mouse.down()
await page.waitForTimeout(1000)
await page.mouse.move(278, 356)
await page.waitForTimeout(200)
await page.mouse.up()
await expect(page.locator('.tiny-select-dropdown')).toBeHidden()
await page.keyboard.press('Control+C')
const valueInput = page.locator('.custom')
await expect(valueInput).toHaveValue('')
await valueInput.focus()
await page.keyboard.press('Control+V')
await page.waitForTimeout(200)
await expect(valueInput).toHaveValue('Alaska')
})

View File

@ -1,49 +1,64 @@
import { expect, test } from '@playwright/test'
test('searchable-multiple', async ({ page }) => {
await page.goto('select#searchable')
const select = page.locator('#preview .tiny-select').first()
const dropdown = page.locator('.tiny-select-dropdown').nth(1)
const options = dropdown.locator('.tiny-option')
const searchInput = dropdown.locator('.tiny-input__inner')
const tags = select.locator('.tiny-tag')
await expect(searchInput).toBeHidden()
await select.click()
await page.waitForTimeout(500)
await expect(searchInput).toBeVisible()
await searchInput.fill('双皮奶')
await searchInput.press('Enter')
await page.waitForTimeout(500)
const hiddenOptions = await options.filter({ hasNotText: /双皮奶|全部/ }).all()
hiddenOptions.forEach(async (item) => {
await expect(item).toHaveCSS('display', 'none')
})
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await page.waitForTimeout(500)
await expect((await tags.all()).length).toEqual(1)
})
test('searchable-single', async ({ page }) => {
await page.goto('select#searchable')
const select = page.locator('#preview .tiny-select').nth(1)
const input = page.locator('#preview .tiny-input__inner').nth(2)
const dropdown = page.locator('.tiny-select-dropdown').nth(1)
const options = dropdown.locator('.tiny-option')
const searchInput = dropdown.locator('.tiny-input__inner')
await expect(searchInput).toBeHidden()
const wrap = page.locator('#searchable')
const select = wrap.locator('.tiny-select').nth(0)
const dropdown = page.locator('body > .tiny-select-dropdown')
const input = dropdown.locator('.tiny-input__inner')
const option = dropdown.locator('.tiny-option')
await expect(input).toBeHidden()
await select.click()
await page.waitForTimeout(500)
await expect(searchInput).toBeVisible()
await searchInput.fill('双皮奶')
await searchInput.press('Enter')
await expect(input).toBeVisible()
await input.fill('双皮奶')
await input.press('Enter')
await page.waitForTimeout(500)
const hiddenOptions = await options.filter({ hasNotText: /双皮奶|全部/ }).all()
hiddenOptions.forEach(async (item) => {
await expect(item).toHaveCSS('display', 'none')
const list = await option.all()
list.forEach(async (item) => {
const text = await item.innerText()
const isVisibleItem = text === '双皮奶' || text === '全部'
if (isVisibleItem) {
await expect(item).toHaveCSS('display', 'flex')
} else {
await expect(item).toHaveCSS('display', 'none')
}
})
await page.getByRole('listitem').filter({ hasText: '双皮奶' }).click()
await option.filter({ hasText: '双皮奶' }).click()
await page.waitForTimeout(500)
await expect(input).toHaveValue('双皮奶')
})
test('searchable-multiple', async ({ page }) => {
await page.goto('select#searchable')
const wrap = page.locator('#searchable')
const select = wrap.locator('.tiny-select').nth(1)
const dropdown = page.locator('body > .tiny-select-dropdown')
const input = dropdown.locator('.tiny-input__inner')
const option = dropdown.locator('.tiny-option')
const tags = select.locator('.tiny-tag')
await expect(input).toBeHidden()
await select.click()
await page.waitForTimeout(500)
await expect(input).toBeVisible()
await input.fill('双皮奶')
await input.press('Enter')
await page.waitForTimeout(500)
const list = await option.all()
list.forEach(async (item) => {
const text = await item.innerText()
const isVisibleItem = text === '双皮奶' || text === '全部'
if (isVisibleItem) {
await expect(item).toHaveCSS('display', 'flex')
} else {
await expect(item).toHaveCSS('display', 'none')
}
})
await option.filter({ hasText: '双皮奶' }).click()
await page.waitForTimeout(500)
await expect((await tags.all()).length).toEqual(1)
})

View File

@ -2,10 +2,13 @@ import { test, expect } from '@playwright/test'
test('show-alloption', async ({ page }) => {
await page.goto('select#show-alloption')
const select = page.locator('#preview .tiny-select')
const options = page.locator('.tiny-select-dropdown').locator('.tiny-option')
const wrap = page.locator('#show-alloption')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await select.click()
await page.waitForTimeout(500)
await expect(options.filter({ hasText: '全部' })).toBeHidden()
await expect(option.filter({ hasText: '全部' })).toBeHidden()
})

View File

@ -1,8 +1,52 @@
import { test, expect } from '@playwright/test'
test('size-medium', async ({ page }) => {
await page.goto('select#size-medium')
test('默认尺寸', async ({ page }) => {
await page.goto('select#size')
const input = page.locator('#preview .tiny-input')
await expect(input).toHaveClass(/tiny-input-medium/)
const wrap = page.locator('#size')
const select = wrap.locator('.tiny-select').nth(0)
const input = select.locator('.tiny-input')
const tag = select.locator('.tiny-tag')
await expect(input.locator('.tiny-input__inner')).toHaveCSS('height', '28px')
await expect(tag.nth(0)).toHaveClass(/tiny-tag--light/)
})
test('medium 尺寸', async ({ page }) => {
await page.goto('select#size')
const wrap = page.locator('#size')
const select = wrap.locator('.tiny-select').nth(1)
const input = select.locator('.tiny-input')
const tag = select.locator('.tiny-tag')
await expect(input).toHaveClass(/tiny-input-medium/)
await expect(input.locator('.tiny-input__inner')).toHaveCSS('height', '40px')
await expect(tag.nth(0)).toHaveClass(/tiny-tag--medium tiny-tag--light/)
})
test('small 尺寸', async ({ page }) => {
await page.goto('select#size')
const wrap = page.locator('#size')
const select = wrap.locator('.tiny-select').nth(2)
const input = select.locator('.tiny-input')
const tag = select.locator('.tiny-tag')
await expect(input).toHaveClass(/tiny-input-small/)
await expect(input.locator('.tiny-input__inner')).toHaveCSS('height', '32px')
await expect(tag.nth(0)).toHaveClass(/tiny-tag--small tiny-tag--light/)
})
test('mini 尺寸', async ({ page }) => {
await page.goto('select#size')
const wrap = page.locator('#size')
const select = wrap.locator('.tiny-select').nth(3)
const input = select.locator('.tiny-input')
const tag = select.locator('.tiny-tag')
await expect(input).toHaveClass(/tiny-input-mini/)
await expect(input.locator('.tiny-input__inner')).toHaveCSS('height', '24px')
await expect(tag.nth(0)).toHaveClass(/tiny-tag--mini tiny-tag--light/)
})

View File

@ -1,11 +1,14 @@
import { expect, test } from '@playwright/test'
test('slot-default', async ({ page }) => {
test('选项插槽', async ({ page }) => {
await page.goto('select#slot-default')
const input = page.locator('#preview .tiny-input__inner')
const options = page.locator('.tiny-select-dropdown').locator('.tiny-option')
const wrap = page.locator('#slot-default')
const select = wrap.locator('.tiny-select')
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await input.click()
await page.waitForTimeout(1000)
await expect(options.filter({ hasText: '选项1' })).toBeVisible()
await expect(option.filter({ hasText: '选项1' })).toBeVisible()
})

View File

@ -1,12 +1,15 @@
import { expect, test } from '@playwright/test'
test('slot-empty', async ({ page }) => {
test('空数据插槽', async ({ page }) => {
await page.goto('select#slot-empty')
const input = page.locator('#preview .tiny-input__inner')
const options = page.locator('.tiny-select-dropdown').locator('.tiny-option')
const wrap = page.locator('#slot-empty')
const select = wrap.locator('.tiny-select')
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await input.click()
await page.waitForTimeout(1000)
await expect((await options.all()).length).toEqual(0)
await expect(page.locator('.tiny-select-dropdown')).toHaveText('没有选项')
await expect((await option.all()).length).toEqual(0)
await expect(page.locator('.tiny-select-dropdown')).toHaveText('空数据插槽')
})

View File

@ -1,12 +1,15 @@
import { expect, test } from '@playwright/test'
test('slot-footer', async ({ page }) => {
test('底部插槽', async ({ page }) => {
await page.goto('select#slot-footer')
const input = page.locator('#preview .tiny-input__inner')
const options = page.locator('.tiny-select-dropdown').locator('.tiny-option')
const wrap = page.locator('#slot-footer')
const select = wrap.locator('.tiny-select')
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
await input.click()
await page.waitForTimeout(1000)
await expect((await options.all()).length).toEqual(5)
await expect((await option.all()).length).toEqual(5)
await expect(page.locator('.select-footer')).toHaveText('底部插槽')
})

View File

@ -1,11 +1,17 @@
import { test, expect } from '@playwright/test'
test('custom-prefix', async ({ page }) => {
await page.goto('select#custom-prefix')
const prefix = page.locator('#preview .tiny-input .tiny-input__prefix .tiny-svg')
test('输入框前缀插槽', async ({ page }) => {
await page.goto('select#slot-prefix')
const wrap = page.locator('#slot-prefix')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const prefix = select.locator('.tiny-input .tiny-input__prefix .tiny-svg')
const tag = select.locator('.tiny-tag')
await expect(prefix).toBeVisible()
await page.locator('.tiny-select__tags').click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await expect(page.locator('.tiny-select span').filter({ hasText: '黄金糕' }).nth(1)).toBeVisible()
await select.click()
await option.filter({ hasText: '黄金糕' }).click()
await expect(tag.filter({ hasText: '黄金糕' })).toBeVisible()
})

View File

@ -1,8 +1,15 @@
import { test } from '@playwright/test'
import { expect, test } from '@playwright/test'
test('custom-reference', async ({ page }) => {
await page.goto('select#custom-reference-slot')
const reference = page.locator('#preview .custom-reference')
await page.goto('select#slot-reference')
const wrap = page.locator('#slot-reference')
const select = wrap.locator('.tiny-select')
const dropdown = page.locator('body > .tiny-select-dropdown')
const option = dropdown.locator('.tiny-option')
const reference = select.locator('.custom-reference')
await expect(option).toHaveCount(0)
await reference.click()
await page.getByRole('listitem').filter({ hasText: '黄金糕' }).click()
await option.filter({ hasText: '黄金糕' }).click()
})

View File

@ -1,32 +0,0 @@
import { test, expect } from '@playwright/test'
test('tag-select', async ({ page }) => {
await page.goto('select#tag-select')
await page.mouse.move(345, 324)
await page.waitForTimeout(1000)
await page.mouse.down()
await page.waitForTimeout(1000)
await page.mouse.move(278, 324)
await page.waitForTimeout(200)
await page.mouse.up()
await page.keyboard.press('Control+C')
const valueInput = page.locator('.copy-value')
await expect(valueInput).toHaveValue('')
await valueInput.focus()
await page.keyboard.press('Control+V')
await page.waitForTimeout(200)
await expect(valueInput).toHaveValue('黄金糕')
})
test('tag-copy-all', async ({ page }) => {
await page.goto('http://localhost:7130/pc/select/tag-copy-all')
const select = page.locator('#preview .tiny-select')
await select.hover()
await page.locator('.tiny-select__copy > .tiny-svg > .st0').click()
const copyValueInput = page.locator('.copy-value')
await copyValueInput.press('Control+V')
await expect(copyValueInput).toHaveValue('黄金糕')
})

View File

@ -203,17 +203,17 @@ export default {
'codeFiles': ['option-group.vue']
},
{
'demoId': 'search-allow-copy',
'demoId': 'copy-single',
'name': { 'zh-CN': '单选可复制', 'en-US': 'Single choice replicable' },
'desc': {
'zh-CN': '<p>通过 <code>allow-copy</code> 属性设置单选可搜索时,鼠标可滑动选中并复制输入框的内容。</p>\n',
'en-US':
'<p>When setting radio searchable through the <code>allow-copy</code> attribute, the mouse can slide to select and copy the content of the input box. </p>\n'
},
'codeFiles': ['search-allow-copy.vue']
'codeFiles': ['copy-single.vue']
},
{
'demoId': 'tag-select',
'demoId': 'copy-multi',
'name': { 'zh-CN': '多选可复制', 'en-US': 'Multiple choices can be copied' },
'desc': {
'zh-CN':
@ -221,7 +221,7 @@ export default {
'en-US':
'<p>By setting the <code>tag-selectable</code> attribute in the input box, the label can be selected with the mouse, and then copied by pressing Ctrl+C or right-click <code>copyable</code> attribute settings enable one click copying of all label text content separated by commas.</p>\n'
},
'codeFiles': ['tag-select.vue']
'codeFiles': ['copy-multi.vue']
},
{
'demoId': 'native-properties',
@ -345,7 +345,7 @@ export default {
'codeFiles': ['nest-grid-disable.vue']
},
{
'demoId': 'nest-remote-grid',
'demoId': 'nest-grid-remote-single',
'name': { 'zh-CN': '下拉表格远程搜索(单选)', 'en-US': 'Select table Remote Search (Single)' },
'desc': {
'zh-CN':
@ -353,10 +353,10 @@ export default {
'en-US':
'<p>Enable remote search through <code>remote</code>,<code>remote-method</code>, and <code>filterable</code>. Set up automatic search and display expansion buttons through <code>remote-config</code>.</p>'
},
'codeFiles': ['nest-remote-grid.vue']
'codeFiles': ['nest-grid-remote-single.vue']
},
{
'demoId': 'nest-grid-remote-filter',
'demoId': 'nest-grid-remote-multi',
'name': { 'zh-CN': '下拉表格远程搜索(多选)', 'en-US': 'Select table Remote Search (Multiple)' },
'desc': {
'zh-CN':
@ -364,7 +364,7 @@ export default {
'en-US':
'<p>Enable remote search through <code>remote</code>,<code>remote-method</code>, and <code>filterable</code>. Set up automatic search and display expansion buttons through <code>remote-config</code> <code>reserve-keyword</code> set to retain search keywords after selecting multiple options.</p>'
},
'codeFiles': ['nest-grid-remote-filter.vue']
'codeFiles': ['nest-grid-remote-multi.vue']
},
{
'demoId': 'nest-radio-grid-much-data',
@ -376,33 +376,6 @@ export default {
},
'codeFiles': ['nest-radio-grid-much-data.vue']
},
{
'demoId': 'events',
'name': { 'zh-CN': '事件', 'en-US': 'Events' },
'desc': {
'zh-CN':
'<div class="tip custom-block">' +
'<p class="custom-block-title">事件说明</p>\n' +
'<p>change监听 v-model 的值发生变化。</p>\n' +
'<p>clear监听单选时点击清空按钮。</p>\n' +
'<p>blur监听 input 失去焦点。</p>\n' +
'<p>focus监听 input 获得焦点。</p>\n' +
'<p>visible-change监听下拉框可见状态的变化。</p>\n' +
'<p>remove-tag监听多选移除选中的标签。</p>\n' +
'</div>\n',
'en-US':
'<div class="tip custom-block">' +
'<p class="custom-block-title"> Event Description</p>\n' +
'<p>changeListen for changes in the value of the v-model.</p>' +
'<p>clearWhen listening to radio selection, click the clear button.</p>\n' +
'<p>blurListening to input losing focus.</p>\n' +
'<p>focusListening for input to gain focus.</p>\n' +
'<p>visible-change: Listen for changes in the visible status of the dropdown box</p>\n' +
'<p>remove-tagListen for multiple selections to remove selected tags.</p>\n' +
'</div>\n'
},
'codeFiles': ['events.vue']
},
{
'demoId': 'slot-default',
'name': { 'zh-CN': '选项插槽', 'en-US': 'Option slot' },
@ -449,6 +422,33 @@ export default {
'en-US': '<p>Customize the HTML template of the trigger source through the <code>reference</code> slot.</p>'
},
'codeFiles': ['slot-reference.vue']
},
{
'demoId': 'events',
'name': { 'zh-CN': '事件', 'en-US': 'Events' },
'desc': {
'zh-CN':
'<div class="tip custom-block">' +
'<p class="custom-block-title">事件说明</p>\n' +
'<p>change监听 v-model 的值发生变化。</p>\n' +
'<p>clear监听单选时点击清空按钮。</p>\n' +
'<p>blur监听 input 失去焦点。</p>\n' +
'<p>focus监听 input 获得焦点。</p>\n' +
'<p>visible-change监听下拉框可见状态的变化。</p>\n' +
'<p>remove-tag监听多选移除选中的标签。</p>\n' +
'</div>\n',
'en-US':
'<div class="tip custom-block">' +
'<p class="custom-block-title"> Event Description</p>\n' +
'<p>changeListen for changes in the value of the v-model.</p>' +
'<p>clearWhen listening to radio selection, click the clear button.</p>\n' +
'<p>blurListening to input losing focus.</p>\n' +
'<p>focusListening for input to gain focus.</p>\n' +
'<p>visible-change: Listen for changes in the visible status of the dropdown box</p>\n' +
'<p>remove-tagListen for multiple selections to remove selected tags.</p>\n' +
'</div>\n'
},
'codeFiles': ['events.vue']
}
],
apis: [
@ -465,7 +465,7 @@ export default {
'en-US':
'Is it allowed to copy the content of the input box, applicable to single choice searchable scenarios'
},
'demoId': 'search-allow-copy'
'demoId': 'copy-single'
},
{
'name': 'allow-create',
@ -517,7 +517,7 @@ export default {
'en-US':
'Is the one click copy function enabled. Click the copy button to copy the text content of all labels with one click, separated by commas, only applicable to multiple selections'
},
'demoId': 'tag-select'
'demoId': 'copy-multi'
},
{
'name': 'collapse-tags',
@ -846,7 +846,7 @@ export default {
'zh-CN': '输入框中的标签是否可通过鼠标选中复制',
'en-US': 'Can the label in the input box be copied by selecting it with the mouse'
},
'demoId': 'tag-select'
'demoId': 'copy-multi'
},
{
'name': 'tag-type',
@ -879,7 +879,7 @@ export default {
'zh-CN': '自定义复制文本的分隔符,需结合 copyable 属性使用',
'en-US': 'The separator for custom copied text needs to be used in conjunction with the copyable attribute'
},
'demoId': 'tag-select'
'demoId': 'copy-multi'
},
{
'name': 'text-field',

View File

@ -523,8 +523,8 @@ export const handleFocus =
state.softFocus = false
}
if (props.remote && state.filterOrSearch && state.firstAutoSeach) {
state.firstAutoSeach = false
if (props.remote && state.filterOrSearch && state.firstAutoSearch) {
state.firstAutoSearch = false
api.resetFilter()
}
}
@ -1584,8 +1584,6 @@ export const buildRadioConfig =
export const onMouseenterNative =
({ state }) =>
(e) => {
if (e.target === e.currentTarget) return
state.inputHovering = true
if (state.searchSingleCopy && state.selectedLabel) {