https://cypress.io logo
Calling vue component method
# i-need-help
m
Hello! I'm trying to use Cypress Component Testing inside my Vue project, but I can't make it call an exposed method from the test. I created a repo with the issue: https://github.com/Ericlm/cypress-vue-ref. I have a
CustomDialog
component with an exposed
showDialog
method, but I can't call it from the test. I tried using the vue test-utils wrapper https://docs.cypress.io/guides/component-testing/vue/examples#Customizing-cymount but I can't get it working. Any help would be appreciated! 🙂
w
In this case you have another option:
Copy code
js
describe('<CustomDialog />', () => {
  it('renders', () => {
    cy.mount(CustomDialog).then(({component}) => {
      component.$refs.customDialog.showModal()
    })
  })
})
Since you can call the showModal() method on the native HTML dialog element, you can avoid going through the vm and just grab the template ref. Or you could avoid even caring about the component and do something like
Copy code
js
cy.get('dialog').then(([el]) => el.showModal())
I think things made available with
defineExpose
work a little differently than, say, the same function defined under
methods
in the options API. After tinkering for a bit I haven't quite figured out how to access those from the Cy component test, but there's likely a way, and we should document the pattern.
m
I wanted to validate that the modal would open via the exposed method, but I'm pretty sure that I could access the dialog as you specified if needed 🙂 It would be great to see Cypress having a way to access and call these exposed methods ; component testing with Composition API would cover even more cases. Thank you for your help! (and for Cypress, which is fantastic ❤️ )
w
Thanks! And I agree it's good to have escape hatches, I think it's just a matter of understanding where it's exposed. I wonder if we are hitting something that is fixed in a later VTU version https://github.com/vuejs/test-utils/issues/1855#issuecomment-1312685121 - Cypress is on 2.0.2, I might try bumping it and see if defineExpose behaves any better then. That said, for a practical recommendation I would suggest not testing internal component methods by name, instead test that a user can tigger the functionality through a parent component. Then your tests won't ever care if this method name changes. Another bandaid would be to declare this kind of thing with the options api under
methods
, you can have both
<script>
and
<script setup>
in the same SFC if you want.
m
Well I'll be in the starting blocks to try it out! 😄 But for sure, on my first journey through e2e testing, I'm progressively convinced that it's much more practical, efficient, and powerful to only watch the effects of calling such methods, just like final users do 🙂 Thank you again for taking the time to investigate this issue