Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Typescript - type VueWrapper do not allow access component data #1746

Closed
bonbisu opened this issue Sep 2, 2022 · 1 comment
Closed
Labels
bug Something isn't working

Comments

@bonbisu
Copy link

bonbisu commented Sep 2, 2022

Describe the bug

I'm trying to assert if classes are being applied to my component.

To Reproduce

I have a simple button components that apply some classes if o prop size has passed. BasicButton.vue:

<script setup lang="ts">
export interface Props {
  size?: "small" | "default";
}

const props = withDefaults(defineProps<Props>(), {
  size: "default",
});

const sizes = {
  small: ["py-2 px-4 text-sm"],
  default: ["py-2.5 px-4"],
};
</script>

<template>
  <button
    :class="[...sizes[props.size]]"
    class="font-semibold rounded-lg disabled:opacity-40 bg-blue-600 hover:bg-blue-500 text-white"
  >
    <div class="flex space-x-3 justify-around">
      <div v-if="$slots.default">
        <slot />
      </div>
      <div v-if="$slots.right">
        <slot name="right" />
      </div>
    </div>
  </button>
</template>

The test I write to this component BasicButton.test.ts:

import { expect, describe, it, beforeEach } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import BasicButton from "./BasicButton.vue";

describe("BasicButton", () => {
  expect(BasicButton).toBeTruthy();

  const buttonText = "Test Button";

  // Can be any, but will lost intellisense
  let wrapper: VueWrapper;

  beforeEach(() => {
    // I can also mount the component at root level, but I want to test the component in isolation
    wrapper = mount(BasicButton, {
      slots: {
        default: buttonText,
      },
    });
  });

  it("should render component", () => {
    expect(wrapper.exists()).toBeTruthy();
  });

  it("should change size", async () => {
    await wrapper.setProps({ size: "small" });

    // Next 2 lines, Error at 'wrapper.vw.sizes': Property 'sizes' does not exist on type 'ComponentPublicInstance<...
    console.log("trying access component data", wrapper.vm.sizes);
    expect(wrapper.classes().join(" ")).toContain(wrapper.vm.sizes.small);
  });

  it("should emit click event", () => {
    wrapper.trigger("click");
    expect(wrapper.emitted("click")).toBeTruthy();
  });
});

I've comment on the code above where I tried to do to solve.

I tried a solution proposed at the vue2 version of vue-test-utils vuejs/vue-test-utils#255 (comment) but vue3 seems not export Wrapper anymore but VueWrapper instead, that is not replaceable.

I also tried to declare wrapper as any, but is not ideal. Proposal: vuejs/vue-test-utils#255 (comment)

Expected behavior

I want to pass the right typings to the wrapper and have access to my component static data, following best practices.
By now, wrapper.vm.sizes can be access, but typescript keep screaming: Property 'sizes' does not exist on type 'ComponentPublicInstance<...

Related information:

  • @vue/test-utils version: 2.0.2
  • Vue version: 3.2.37
  • node version: 16.15.1
  • npm version: 8.11.0
  • typescript version: 4.7.4
  • eslint version: 8.23.0
  • @vue/eslint-config-typescript version: 11.0.0

Additional context

image

@bonbisu bonbisu added the bug Something isn't working label Sep 2, 2022
@cexbrayat
Copy link
Member

Just to be clear: you have a TS error, but if you use (wrapper.vm as unknown as { sizes: string }) instead, the test succeeds right?

If so, this is sadly expected: as your component is closed, nothing is exposed, and TypeScript (or Volar) do not know that VTU "cheats" to make sizes available on wrapper.vm.

Sadly, we can't do much on the VTU side, and we need a fix upstream in vuejs/core. We are tracking this in issue #972 , so I'm closing the issue as a duplicate.

@cexbrayat cexbrayat closed this as not planned Won't fix, can't repro, duplicate, stale Sep 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants