question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] Vue 3 Component Reactivity not working

See original GitHub issue

Context:

  • Playwright Version: 1.27.1
  • Operating System: Windows
  • Node.js version: 16.17.0, 18.8.0
  • Browser: All
  • Extra: Vite, Vue 3

playwright test -c playwright-ct.config.ts

When creating ref with some mock data in ‘*.spec.tsx’ test file and passing it to the tested component in mount, initial render works. However, upon updating the ref value with a new value, the component doesn’t automatically rerender.

This is, for example, working in Cypress component testing (mentioning it since I just migrated to Playwright).

I understand one can use Playwright’s await component.rerender({ props: { *somepropname*: *someref.value* }})

But that has a few significant drawbacks:

  • It is not type safe, so upon refactoring component prop names, changing types etc., I will realize at best only after running the test. With reactivity, everything would be beautifully type safe and automatic.
  • It doesn’t really allow you to test deep reactivity (list item property changes etc.). Only shallowRef at best. You can force the rerender, yes, but that destroys the purpose of deep reactivity testing.

I admit that reactivity testing is not always useful, but I have some use for it in my more complex components. More importantly, the type safety is just really really nice to have. It is also part of a reason why I use tsx tests instead of ts tests; because only mount(<ItemList items={...} />)) is type safe while also forcing you to provide values for all required props and warning you when providing values for non-existent props.

Full repro project. Steps to reproduce:

  • Download repro-project.zip
  • Install Volar extension (official Vue 3 support extension)
  • Enable Take Over mode for workspace (guide is in README.md if needed)
  • npm install
  • npm run dev to see a glorious ItemList.vue component drawing ten items
  • Check the ‘ItemList.vue’ component code
  • Check the ‘ItemList.spec.tsx’ test code
  • Try running the test from previous bullet. The test fails. There are a few exaplanatory comments in the test file with additional info.

Minor additional issue also demonstrated in the repro project: interface MountResult from @playwright/experimental-ct-vue is not exported. This is a little annoying since I can only pass the component reference as Locator from beforeEach where I’m mounting the actual component. Then, in the aforementioned test file I have to do this await (component as any).rerender(...).

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
StepanMynarikcommented, Oct 31, 2022

In my opinion, exposing the MountResult will lead to overly complicated tests. There are several other ways to reduce duplicate setup code. If you are interested see:

Looks cool, fair point. I will definitely give this a try.

Yeah for sure. You are able to use classes, types and interfaces. The limitation as of now is that you can’t import it from the component file. I’ve just suggested some ideas to get around that for now.

If it’s considered a temporary limitation that should be alleviated in the future, then I’m absolutely happy 😃 I was just reluctant to accept it as an intended permanent state of things.

See line: const { items = [] } = defineProps<{ items?: Item[] }>(); to fix this

This is what I was talking about - I don’t want to make workarounds in my “business logic” to make way for testing. This parameter should stay required. And generally I just use required parameters a lot. It is a great way to let users of your components know which parameters they must provide values for at minimum to render properly.

That is alright! Glad to see someone sharing their thoughts and having an open discussion to see where things (on all sides) could improve! You certainly made some valid arguments.

It is a pleasure communicating with you 😃

0reactions
StepanMynarikcommented, Nov 14, 2022

I guess so, yes. Just waiting for component.rerender to become type safe 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why Your Vue Component Isn't Updating (and how to fix it)
1. Check that variables are reactive · 2. Make sure to update Arrays and Objects correctly (only in Vue 2) · 3. Use...
Read more >
Props gotten directly from vue 3 setup are not reactive
All it says is that your trainingCourseId is not reactive, meaning if the parent component passes in a different courseId ...
Read more >
Reactivity in Depth - Vue.js
Component state consists of reactive JavaScript objects. When you modify them, the view updates. It makes state management simple and intuitive, but it's...
Read more >
Understanding the New Reactivity System in Vue 3 - SitePoint
For each component instance, Vue creates a dependencies watcher instance. Any properties collected/tracked as dependencies during the ...
Read more >
On-demand Reactivity in Vue 3 - Toptal
Thus, in this case, jumping between the sections is not really a problem. This issue of code fragmentation becomes relevant when we deal...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found