diff --git a/package.json b/package.json
index 174cbf6..5793de5 100644
--- a/package.json
+++ b/package.json
@@ -68,6 +68,7 @@
     "msw": "^0.21.3",
     "tsd": "^0.19.1",
     "typescript": "^4.4.3",
+    "vant": "^3.6.4",
     "vee-validate": "^4.3.5",
     "vue": "^3.2.12",
     "vue-apollo": "^3.0.5",
diff --git a/src/__tests__/components/VantValidate.vue b/src/__tests__/components/VantValidate.vue
new file mode 100644
index 0000000..ed56080
--- /dev/null
+++ b/src/__tests__/components/VantValidate.vue
@@ -0,0 +1,44 @@
+<script setup>
+import { ref, reactive } from 'vue';
+
+const loginForm = reactive({
+  username: '',
+  password: '',
+});
+
+const msg = ref('empty')
+
+const submitLogin = async () => {
+  msg.value = 'validation passed';
+}
+</script>
+
+<template>
+  <div>
+    <van-form data-testid="form" @submit="submitLogin">
+      <van-cell-group inset>
+        <van-field
+          v-model="loginForm.username"
+          label="username"
+          placeholder="username"
+          :rules="[{ required: true, message: 'please input username' }]"
+        />
+        <van-field
+          v-model="loginForm.password"
+          type="password"
+          label="password"
+          placeholder="password"
+          :rules="[{ required: true, message: 'please input password' }]"
+        />
+      </van-cell-group>
+      <div>
+        <van-button
+          native-type="submit"
+        >
+          login
+        </van-button>
+      </div>
+    </van-form>
+  </div>
+  <span>{{ msg }}</span>
+</template>
\ No newline at end of file
diff --git a/src/__tests__/fire-event.js b/src/__tests__/fire-event.js
index e51d8ab..ae0ed15 100644
--- a/src/__tests__/fire-event.js
+++ b/src/__tests__/fire-event.js
@@ -1,6 +1,9 @@
 import {h} from 'vue'
+import Vant from 'vant'
 import {render, fireEvent} from '..'
 import Button from './components/Button'
+import VantValidate from './components/VantValidate'
+import '@testing-library/jest-dom'
 
 const eventTypes = [
   {
@@ -274,3 +277,18 @@ test('fireEvent.update handles input file', async () => {
 
   expect(console.warn).not.toHaveBeenCalled()
 })
+
+test('triggers form validation', async () => {
+  const { getByPlaceholderText, getByTestId, getByText } = render(VantValidate, {
+    global: {
+      plugins: [Vant]
+    }
+  });
+  expect(getByText('empty')).toBeInTheDocument();
+
+  await fireEvent.update(getByPlaceholderText('username'), 'user');
+  await fireEvent.update(getByPlaceholderText('password'), 'psw');
+  await fireEvent.submit(getByTestId('form'));
+  
+  expect(getByText('validation passed')).toBeInTheDocument();
+})
diff --git a/src/fire-event.js b/src/fire-event.js
index eca4438..80b14da 100644
--- a/src/fire-event.js
+++ b/src/fire-event.js
@@ -1,5 +1,5 @@
-/* eslint-disable testing-library/no-wait-for-empty-callback */
-import {waitFor, fireEvent as dtlFireEvent} from '@testing-library/dom'
+import {fireEvent as dtlFireEvent} from '@testing-library/dom'
+import {flushPromises} from '@vue/test-utils'
 
 // Vue Testing Lib's version of fireEvent will call DOM Testing Lib's
 // version of fireEvent. The reason is because we need to wait another
@@ -8,7 +8,7 @@ import {waitFor, fireEvent as dtlFireEvent} from '@testing-library/dom'
 
 async function fireEvent(...args) {
   dtlFireEvent(...args)
-  await waitFor(() => {})
+  await flushPromises()
 }
 
 Object.keys(dtlFireEvent).forEach(key => {
@@ -16,7 +16,7 @@ Object.keys(dtlFireEvent).forEach(key => {
     warnOnChangeOrInputEventCalledDirectly(args[1], key)
 
     dtlFireEvent[key](...args)
-    await waitFor(() => {})
+    await flushPromises()
   }
 })