diff --git a/packages/components/dialog/__tests__/dialog.test.tsx b/packages/components/dialog/__tests__/dialog.test.tsx
index 82417ee12b..14d1ccd0bf 100644
--- a/packages/components/dialog/__tests__/dialog.test.tsx
+++ b/packages/components/dialog/__tests__/dialog.test.tsx
@@ -5,6 +5,8 @@ import { rAF } from '@element-plus/test-utils/tick'
import triggerCompositeClick from '@element-plus/test-utils/composite-click'
import { Delete } from '@element-plus/icons-vue'
import Dialog from '../src/dialog.vue'
+import triggerEvent from '@element-plus/test-utils/trigger-event'
+import { EVENT_CODE } from '@element-plus/constants'
const AXIOM = 'Rem is the best girl'
@@ -179,6 +181,28 @@ describe('Dialog.vue', () => {
expect(wrapper.find('.test-footer-class').exists()).toBe(false)
})
+ test('should close the modal when pressing Escape when `closeOnPressEscape` is true', async () => {
+ const onClose = vi.fn()
+ const wrapper = mount(
+
+ )
+
+ await nextTick()
+
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+ expect(wrapper.vm.visible).toBeTruthy()
+
+ await wrapper.setProps({ closeOnPressEscape: true })
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+
+ expect(wrapper.vm.visible).toBeFalsy()
+ expect(onClose).toHaveBeenCalledTimes(1)
+ })
+
describe('mask related', () => {
test('should not have overlay mask when mask is false', async () => {
const wrapper = mount(
diff --git a/packages/components/image-viewer/__tests__/image-viewer.test.tsx b/packages/components/image-viewer/__tests__/image-viewer.test.tsx
index e8d22b9d3f..380e83103b 100644
--- a/packages/components/image-viewer/__tests__/image-viewer.test.tsx
+++ b/packages/components/image-viewer/__tests__/image-viewer.test.tsx
@@ -1,8 +1,10 @@
import { nextTick } from 'vue'
import { mount } from '@vue/test-utils'
-import { describe, expect, test } from 'vitest'
+import { describe, expect, test, vi } from 'vitest'
import { IMAGE_FAIL, IMAGE_SUCCESS } from '@element-plus/test-utils/mock'
import ImageViewer from '../src/image-viewer.vue'
+import triggerEvent from '@element-plus/test-utils/trigger-event'
+import { EVENT_CODE } from '@element-plus/constants'
async function doubleWait() {
await nextTick()
@@ -39,6 +41,30 @@ describe('', () => {
wrapper.unmount()
})
+ test('image preview close-on-press-escape', async () => {
+ const onClose = vi.fn()
+ const wrapper = mount(
+
+ )
+
+ await doubleWait()
+
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+ expect(document.querySelector('.el-image-viewer__wrapper')).toBeDefined()
+
+ await wrapper.setProps({ closeOnPressEscape: true })
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+
+ expect(document.querySelector('.el-image-viewer__wrapper')).toBeNull()
+ expect(onClose).toHaveBeenCalledTimes(1)
+ })
+
test('manually switch image', async () => {
const wrapper = mount(
diff --git a/packages/components/image/__tests__/image.test.tsx b/packages/components/image/__tests__/image.test.tsx
index 616ad3c563..99e238b27f 100644
--- a/packages/components/image/__tests__/image.test.tsx
+++ b/packages/components/image/__tests__/image.test.tsx
@@ -7,6 +7,8 @@ import {
mockImageEvent,
} from '@element-plus/test-utils/mock'
import Image from '../src/image.vue'
+import triggerEvent from '@element-plus/test-utils/trigger-event'
+import { EVENT_CODE } from '@element-plus/constants'
import type { AnchorHTMLAttributes, ImgHTMLAttributes } from 'vue'
import type { ImageProps } from '../src/image'
@@ -116,6 +118,31 @@ describe('Image.vue', () => {
expect(result).toBeTruthy()
})
+ test('image preview close-on-press-escape', async () => {
+ const onClose = vi.fn()
+ const wrapper = mount(
+ ({ length: 3 }).fill(IMAGE_SUCCESS)}
+ onClose={onClose}
+ closeOnPressEscape={false}
+ />
+ )
+
+ await doubleWait()
+ wrapper.getCurrentComponent().exposed!.showPreview()
+
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+ expect(wrapper.vm.showViewer).toBeTruthy()
+
+ await wrapper.setProps({ closeOnPressEscape: true })
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+
+ expect(wrapper.vm.showViewer).toBeFalsy()
+ expect(onClose).toHaveBeenCalledTimes(1)
+ })
+
test('manually open preview', async () => {
const url = IMAGE_SUCCESS
const srcList = Array.from({ length: 3 }).map(
diff --git a/packages/components/tour/__tests__/tour.test.tsx b/packages/components/tour/__tests__/tour.test.tsx
index 273d38ecf5..841856962e 100644
--- a/packages/components/tour/__tests__/tour.test.tsx
+++ b/packages/components/tour/__tests__/tour.test.tsx
@@ -1,8 +1,10 @@
import { nextTick, ref } from 'vue'
import { mount } from '@vue/test-utils'
-import { afterEach, describe, expect, test } from 'vitest'
+import { afterEach, describe, expect, test, vi } from 'vitest'
import Tour from '../src/tour.vue'
import TourStep from '../src/step.vue'
+import { EVENT_CODE } from '@element-plus/constants'
+import triggerEvent from '@element-plus/test-utils/trigger-event'
describe('Tour.vue', () => {
afterEach(() => {
@@ -190,4 +192,36 @@ describe('Tour.vue', () => {
expect(document.querySelector('.prev-btn span')?.innerHTML).toBe('上一步')
expect(document.querySelector('.next-btn span')?.innerHTML).toBe('下一步')
})
+
+ test('close-on-press-escape', async () => {
+ const onClose = vi.fn()
+ const modelValue = ref(true)
+ const wrapper = mount({
+ setup() {
+ return () => (
+
+
+
+
+ )
+ },
+ })
+
+ await nextTick()
+
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+ expect(modelValue.value).toBeTruthy()
+
+ await wrapper.setProps({ closeOnPressEscape: true })
+ triggerEvent(document.body, 'keydown', EVENT_CODE.esc)
+ await nextTick()
+
+ expect(modelValue.value).toBeFalsy()
+ expect(onClose).toHaveBeenCalledTimes(1)
+ })
})