[Feature] Component testing Vue/Svelte events/emits
Can the event handling API be changed to that of Vue Test Utils and Testing library? Those seems more user-friendly to me than the current API.
Current API:
test('event should work', async ({ mount }) => {
const messages = []
const component = await mount(Button, {
props: {
title: 'Submit'
},
on: {
submit: data => messages.push(data)
}
})
await component.click()
expect(messages).toEqual(['hello'])
})
VTU API:
test('event should work', async ({ mount, page }) => {
const component = await mount(Button, {
props: {
title: 'Submit'
},
})
await component.click()
expect(component.emitted('submit')).toEqual(['hello'])
})
related to: https://github.com/microsoft/playwright/issues/15919
We would still need something like the existing API so that we could handle the event being fired. How is this handled in VTU? Or do they store events in separate collections at all times and don't allow for checking the relative timing of multiple events on different targets?
Seems like they record and store all events in a collection at any time. Not completely sure but I think VTU does not support checking for relative timing of multiple events on different targets. I don't see why you would want to check for this?
For more info see also the API v1 docs about emitted and the v2 docs about emitted.
Well, they are events, so you might want to know "when" they fire, not just "that" they fire. But I can see how a collection can save time.
Maybe i misunderstood your question. You can still verify when the events are fired because the events are stored in order/sequence. For example:
// Component.vue
<script>
export default {
created() {
this.$emit('greet', 'hello')
this.$emit('greet', 'goodbye')
}
}
</script>
// Component.test.ts
import { mount } from '@vue/test-utils'
import Component from './Component.vue'
test('emitted', () => {
const wrapper = mount(Component)
// wrapper.emitted() equals to { greet: [ ['hello'], ['goodbye'] ] }
expect(wrapper.emitted()).toHaveProperty('greet')
expect(wrapper.emitted().greet).toHaveLength(2)
expect(wrapper.emitted().greet[0]).toEqual(['hello'])
expect(wrapper.emitted().greet[1]).toEqual(['goodbye'])
})
Another inconvenience is that you have to type the messages array in the example below otherwise type errors are thrown:
test('event should work', async ({ mount }) => {
const messages = [] // ERROR: type of any
const component = await mount(Button, {
props: {
title: 'Submit'
},
on: {
submit: data => messages.push(data) // ERROR: Argument of type 'any' is not assignable to parameter of type 'never'.
}
})
await component.click()
expect(messages).toEqual(['hello'])
})
In general, vue test-utils has other goodies as well in it's mount command which can be useful in the context of playwright as well. Currently some of them have to be reimplemented via beforeMount.
P.S. Cypress supports passing event handlers as props: https://docs.cypress.io/guides/component-testing/vue/examples#Testing-Event-Handlers, this might be a feature of @vue/test-utils, which Playwright requires the separate on from as it is not based on it. Also Playwright Test doesn't have builtin spy/stubs to make such testing convenient.
Why was this issue closed?
Thank you for your involvement. This issue was closed due to limited engagement (upvotes/activity), lack of recent activity, and insufficient actionability. To maintain a manageable database, we prioritize issues based on these factors.
If you disagree with this closure, please open a new issue and reference this one. More support or clarity on its necessity may prompt a review. Your understanding and cooperation are appreciated.