Skip to content

Problems with multi-root components utilizing <script setup> #550

@AndreasNasman

Description

@AndreasNasman

Hi!

I tried creating some snapshot tests based on the example test file merged in #264.

<!-- Hello.vue -->
<template>
  <div>{{ msg }}</div>
  <div>
    <button @click="incrementCount">{{ count }}</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";

export default defineComponent({
  name: "Hello",
  setup() {
    const msg = ref("Hello world");
    const count = ref(0);
    const incrementCount = () => {
      count.value++;
    };

    return {
      count,
      incrementCount,
      msg,
    };
  },
});
</script>

Same as Hello.vue using <script setup>.

<!-- ScriptSetup.vue -->
<template>
  <div>{{ msg }}</div>
  <div>
    <button @click="incrementCount">{{ count }}</button>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const msg = ref("Hello world");
const count = ref(0);
const incrementCount = () => {
  count.value++;
};
</script>
// sfc.spec.js
import Hello from "@/components/Hello.vue";
import ScriptSetup from "@/components/ScriptSetup.vue";
import { mount } from "@vue/test-utils";

describe("sfc", () => {
  it("mounts an sfc via vue-test-transformer", async () => {
    const wrapper = mount(Hello);

    expect(wrapper.text()).toContain("Hello world");

    await wrapper.find("button").trigger("click");
    expect(wrapper.html()).toContain("1");

    expect(wrapper.html()).toMatchSnapshot();
    expect(wrapper.element).toMatchSnapshot();
  });

  // rfc: https://github.com/vuejs/rfcs/pull/228
  it("works with <script setup> (as of Vue 3.0.3)", async () => {
    const wrapper = mount(ScriptSetup);

    // This `expect` fails since `.text()` return an empty string!
    // expect(wrapper.text()).toContain("Hello world");

    await wrapper.find("button").trigger("click");
    expect(wrapper.html()).toContain("1");

    // Why does `.html()` produce a snapshot with content
    expect(wrapper.html()).toMatchSnapshot();
    // ...while `.element` result in an empty one?
    expect(wrapper.element).toMatchSnapshot();
  });
});
// sfc.spec.ts.snap
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`sfc mounts an sfc via vue-test-transformer 1`] = `"<div>Hello world</div><div><button>1</button></div>"`;

exports[`sfc mounts an sfc via vue-test-transformer 2`] = `
<div
  data-v-app=""
>
  
  <div>
    Hello world
  </div>
  <div>
    <button>
      1
    </button>
  </div>
  
</div>
`;

exports[`sfc works with <script setup> (as of Vue 3.0.3) 1`] = `"<div>Hello world</div><div><button>1</button></div>"`;

exports[`sfc works with <script setup> (as of Vue 3.0.3) 2`] = ``;

My questions are

  1. Same as in the code comments: Why does calling .html() on the wrapper produce content while .element and .text() are empty in the test case with <script setup>? I think it's related to having multiple roots; if I wrap all the elements in the template of ScriptSetup in e.g. a div, both .html() and .element have content, also .text(). Could also be related to the issues mentioned in Not working with Vue 3.0.3 and latest <script setup> #263.
  2. A more general question: Should .html() or .element be used for snapshot testing? I've seen both and don't really know if one is better than the other or if they're more or less interchangeable.

Thanks!
– Andreas

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions