Giter VIP home page Giter VIP logo

vue-testing-library's Introduction

@testing-library/angular

Octopus with the Angular logo

Simple and complete Angular testing utilities that encourage good testing practices.


Read The Docs | Edit the docs



Build Status version downloads MIT License

All Contributors PRs Welcome Code of Conduct Discord

Watch on GitHub Star on GitHub Tweet

Open in GitHub Codespaces

Table of Contents

The problem

You want to write maintainable tests for your Angular components. As a part of this goal, you want your tests to avoid including implementation details of your components and rather focus on making your tests give you the confidence for which they are intended. As part of this, you want your testbase to be maintainable in the long run so refactors of your components (changes to implementation but not functionality) don't break your tests and slow you and your team down.

This solution

The @testing-library/angular is a very lightweight solution for testing Angular components. It provides light utility functions on top of Angular and @testing-library/dom, in a way that encourages better testing practices. Its primary guiding principle is:

The more your tests resemble the way your software is used, the more confidence they can give you.

Example

counter.component.ts

@Component({
  selector: 'app-counter',
  template: `
    <button (click)="decrement()">-</button>
    <span>Current Count: {{ counter }}</span>
    <button (click)="increment()">+</button>
  `,
})
export class CounterComponent {
  @Input() counter = 0;

  increment() {
    this.counter += 1;
  }

  decrement() {
    this.counter -= 1;
  }
}

counter.component.spec.ts

import { render, screen, fireEvent } from '@testing-library/angular';
import { CounterComponent } from './counter.component';

describe('Counter', () => {
  test('should render counter', async () => {
    await render(CounterComponent, { componentProperties: { counter: 5 } });

    expect(screen.getByText('Current Count: 5'));
  });

  test('should increment the counter on click', async () => {
    await render(CounterComponent, { componentProperties: { counter: 5 } });

    const incrementButton = screen.getByRole('button', { name: '+' });
    fireEvent.click(incrementButton);

    expect(screen.getByText('Current Count: 6'));
  });
});

See more examples

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's devDependencies:

npm install @testing-library/angular --save-dev

You may also be interested in installing jest-dom so you can use the custom jest matchers.

Docs

Version compatibility

Angular Angular Testing Library
17.x 15.x, 14.x, 13.x
16.x 14.x, 13.x
>= 15.1 14.x, 13.x
< 15.1 12.x, 11.x
14.x 12.x, 11.x

Guiding Principles

The more your tests resemble the way your software is used, the more confidence they can give you.

We try to only expose methods and utilities that encourage you to write tests that closely resemble how your Angular components are used.

Utilities are included in this project based on the following guiding principles:

  1. If it relates to rendering components, it deals with DOM nodes rather than component instances, nor should it encourage dealing with component instances.
  2. It should be generally useful for testing individual Angular components or full Angular applications.
  3. Utility implementations and APIs should be simple and flexible.

At the end of the day, what we want is for this library to be pretty light-weight, simple, and understandable.

Contributors

Thanks goes to these people (emoji key):

Tim Deschryver
Tim Deschryver

πŸ’» πŸ“– πŸš‡ ⚠️
MichaΓ«l De Boey
MichaΓ«l De Boey

πŸ“–
Ignacio Le Fluk
Ignacio Le Fluk

πŸ’» ⚠️
TamΓ‘s SzabΓ³
TamΓ‘s SzabΓ³

πŸ’»
Gregor Woiwode
Gregor Woiwode

πŸ’»
Toni Villena
Toni Villena

πŸ› πŸ’» πŸ“– ⚠️
ShPelles
ShPelles

πŸ“–
Miluoshi
Miluoshi

πŸ’» ⚠️
Nick McCurdy
Nick McCurdy

πŸ“–
Srinivasan Sekar
Srinivasan Sekar

πŸ“–
Bitcollage
Bitcollage

πŸ“–
Emil Sundin
Emil Sundin

πŸ’»
Ombrax
Ombrax

πŸ’»
Rafael Santana
Rafael Santana

πŸ’» ⚠️ πŸ›
Benjamin Blackwood
Benjamin Blackwood

πŸ“– ⚠️
Gustavo Porto
Gustavo Porto

πŸ“–
Bo Vandersteene
Bo Vandersteene

πŸ’»
Janek
Janek

πŸ’» ⚠️
Gleb Irovich
Gleb Irovich

πŸ’» ⚠️
Arjen
Arjen

πŸ’» 🚧
Suguru Inatomi
Suguru Inatomi

πŸ’» πŸ€”
Amit Miran
Amit Miran

πŸš‡
Jan-Willem Willebrands
Jan-Willem Willebrands

πŸ’»
Sandro
Sandro

πŸ’» πŸ›
Michael Westphal
Michael Westphal

πŸ’» ⚠️
Lukas
Lukas

πŸ’»
Matan Borenkraout
Matan Borenkraout

🚧
mleimer
mleimer

πŸ“– ⚠️
MeIr
MeIr

πŸ› ⚠️
John Dengis
John Dengis

πŸ’» ⚠️
Rokas BrazdΕΎionis
Rokas BrazdΕΎionis

πŸ’»
Mateus Duraes
Mateus Duraes

πŸ’»
Josh Joseph
Josh Joseph

πŸ’» ⚠️
Torsten Knauf
Torsten Knauf

🚧
antischematic
antischematic

πŸ› πŸ€”
Florian Pabst
Florian Pabst

πŸ’»
Mark Goho
Mark Goho

🚧 πŸ“–
Jan-Willem Baart
Jan-Willem Baart

πŸ’» ⚠️

This project follows the all-contributors specification. Contributions of any kind welcome!

Docs

Read The Docs | Edit the docs

FAQ

I am using Reactive Forms and the jest-dom matcher toHaveFormValues always returns an empty object or there are missing fields. Why?

Only form elements with a name attribute will have their values passed to toHaveFormsValues.

Issues

Looking to contribute? Look for the Good First Issue label.

πŸ› Bugs

Please file an issue for bugs, missing documentation, or unexpected behavior.

See Bugs

πŸ’‘ Feature Requests

Please file an issue to suggest new features. Vote on feature requests by adding a πŸ‘. This helps maintainers prioritize what to work on.

See Feature Requests

❓ Questions

For questions related to using the library, please visit a support community instead of filing an issue on GitHub.

Getting started with GitHub Codespaces

To get started, create a codespace for this repository by clicking this πŸ‘‡

Open in GitHub Codespaces

A codespace will open in a web-based version of Visual Studio Code. The dev container is fully configured with software needed for this project.

Note: Dev containers is an open spec which is supported by GitHub Codespaces and other tools.

LICENSE

MIT

vue-testing-library's People

Contributors

afontcu avatar agualis avatar ankitsinghaniyaz avatar arnaublanche avatar bennettdams avatar blimmer avatar cilice avatar dependabot[bot] avatar dfcook avatar edufarre avatar esyw avatar eunjae-lee avatar g1eny0ung avatar imgbot[bot] avatar itenthusiasm avatar jeromedeleon avatar kingyue737 avatar makeupsomething avatar matanbobi avatar mediafreakch avatar michaeldeboey avatar nickmccurdy avatar ryotah avatar sahbi-ktifa avatar sand4rt avatar sangilyun avatar thunderer199 avatar tim-maguire avatar vdsabev avatar wilf312 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-testing-library's Issues

Route not updating on fireEvent

I am trying to test navigation in my app. It is a very simple setup but when I test fireEvent clicking the <router-link> the first component is still shown in the debug. I feel like I must be missing something simple here.

  "devDependencies": {
    "@testing-library/vue": "^1.1.0",
    "@vue/cli-plugin-babel": "^3.8.0",
    "@vue/cli-plugin-e2e-cypress": "^3.9.0",
    "@vue/cli-plugin-eslint": "^3.8.0",
    "@vue/cli-plugin-unit-jest": "^3.9.0",
    "@vue/cli-service": "^3.8.0",
    "@vue/test-utils": "1.0.0-beta.29",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "babel-jest": "^24.8.0",
    "eslint": "^5.16.0",
    "eslint-config-prettier": "^6.0.0",
    "eslint-plugin-prettier": "^3.1.0",
    "eslint-plugin-vue": "^5.0.0",
    "jest": "^24.8.0",
    "jest-dom": "^3.4.0",
    "jest-in-case": "^1.0.2",
    "jest-serializer-vue": "^2.0.2",
    "prettier": "^1.18.2",
    "vue-jest": "^3.0.4",
    "vue-template-compiler": "^2.6.10"
  },
<template>
    <section class="card">
        <h2 data-testid="section-header">Welcome!</h2>
        <div class="card__content--welcome">
            <div>
                <span class="text">
                    It looks like you don't have an account yet
                </span>
                <span class="text">
                    Let's get you set up!
                </span>
            </div>
            <router-link
                data-testid="signup-link"
                to="/signup"
                class="btn btn--green"
            >
                get started!
            </router-link>
        </div>
    </section>
</template>

<script>
export default {
    name: 'Welcome',

    created() {
        if (localStorage.getItem('userDetails')) {
            this.$store.commit(
                'setUser',
                JSON.parse(localStorage.getItem('userDetails')),
            )
            this.$router.push({name: 'profile-details'})
        }
    },
}
</script>
import {render, fireEvent, cleanup} from '@testing-library/vue'
import Welcome from '@/views/Welcome'
import Signup from '@/views/Signup'
import 'jest-dom/extend-expect'

const routes = [
    {path: '/', name: 'user-setup', component: Welcome},
    {path: '/signup', name: 'signup', component: Signup},
]

test('full app rendering/navigating', async () => {
    const {getByTestId, getByText, debug} = render(Welcome, {routes, store})

    await fireEvent.click(getByTestId('signup-link'))

    debug() //when i debug here it still shows the welcome component
})

Warn about v-model components not handled with fireEvent.change

More often than not people relies on fireEvent.input or fireEvent.change to handle v-model powered inputs, thus running into issues with input value not being properly updated.

I'm wondering if we should provide some kind of warning when that happens.

Does it make sense?

VTL needs an emoji :)

VTL is the only Testing Library member without an emoji of an animal :)

Suggestions? I'd go with any of the greenish ones πŸ¦ŽπŸΈπŸŠπŸ¦–

imatge

Provide options to adapt the document before mount

Describe the feature
We are using Vuetify as component library in one of our projects. I would like to introduce vue-testing-library and came up with some setup troubles on the way. Vuetify requires a wrapper element containing the attribute data-app. This element is used to append components like dialog to the root DOM level. The required setup can be done using jest setup files. Thought, the dialog content can not be found when using the exposed queries of the vue-testing-libraries render() method.

To Reproduce
Steps to reproduce the behavior:

  • Init a vue app with vuetify
  • Create a basic dialog
  • write a test which should validate that the dialog content is visible when a button is clicked
  • Add Vuetify and <div data-app></div> to your test DOM instance before mount

=> queries like getByText will not query the dialog content

I tried to create a codesandbox, but failed. Is there a working example for vue-testing-library?
https://codesandbox.io/s/vuetify-with-vue-testing-library-bhu8f?previewwindow=tests

Expected behavior
I expect a configuration option like it exists for react:

  • baseElement: Specify the base element for the queries.
  • container: Specify the surrounding DOM node

Related information:

  • @testing-library/vue version: 3.0.0
  • Vue version: 2.5.18
  • node version: 8.12.0
  • yarn version: 1.17.3
  • Vuetify version: 1.2.10

Relevant code or config (if any)

import CreateLorem from "./CreateLorem";
import { render } from "@testing-library/vue";
import Vuetify from "vuetify";
import Vue from "vue";

var app = document.createElement("div");
app.setAttribute("data-app", true);
document.body.appendChild(app);
Vue.use(Vuetify);

it("should create a lorem", () => {
  const { getByText } = render(CreateLorem);
  getByText("open");
});

Provide a cleanup-after-each file?

Hi! react-testing-library is providing a cleanup-after-each file that comes in handy to avoid repeating afterEach(cleanup) on every test file. They even load it using a setup file, so you load it once and forget about dirty DOM nodes once for all.

Would it make sense to port this feature to vue-testing-library? If so, I'd happily submit a PR with both the file and the required documentation πŸ€—

πŸ‘‹

Invitation to move to testing-library org

It's up to you, but if you'd like, you're welcome to transfer this repository to the testing-library organization on GitHub. This will give your project more credibility as part of the testing-library family of projects with a unified mission of tools which help people avoid testing implementation details.

Again, totally up to you. I just want you to know we appreciate all you've done and you're welcome to join us if you like.

Pull request #8 is not published

When I install the latest version of vue-testing-library, it does not contain pull request #8 .

Strangely enough, the version is 0.10 although the repository says it's 0.9.

Also the Travis build is failing, stating that it cannot find @babel/runtime/helpers/interopRequireDefault when executing the tests. If I remember correctly, this has something to do with the fact that the Babel helper functions were moved in version 7-beta.56. But I don't know if this is actually the source of this issue.

Add additionalOptions test example

Adding a test example for additionalOptions feature (#48 #47) would both (1) show how to use it and (2) increase code coverage.

I guess using vue-i18n as a example would be great.

FireEvent not getting resolved

I just installed the library

devDependencies": {
    "@testing-library/vue": "^1.0.3",
    "@vue/cli-plugin-babel": "^3.0.3",
    "@vue/cli-plugin-e2e-cypress": "^3.0.3",
    "@vue/cli-plugin-eslint": "^3.0.3",
    "@vue/cli-plugin-pwa": "^3.8.0",
    "@vue/cli-plugin-unit-jest": "^3.0.3",
    "@vue/cli-service": "^3.0.3",
    "@vue/test-utils": "1.0.0-beta.29",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "babel-jest": "^23.6.0",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "node-sass": "^4.9.0",
    "sass-loader": "^7.1.0",
    "tailwindcss": "^1.0.4",
    "vue-template-compiler": "^2.6.10"
  }

But when i do import { render, fireEvent, cleanup } from '@testing-library/vue' and use it my test

import { render, fireEvent, cleanup } from '@testing-library/vue'
import Input from '../input.vue';
import VTooltip from 'v-tooltip'

describe('Test the Input component function', () => {
	afterEach(cleanup)
	const props = {
		loginMethod: 'phone'
	}
	test('input toggle when icon is clicked', () => {
		const {getByPlaceholderText, getByTestId} = render(Input, {props}, vue => {
			vue.use(VTooltip)
		})

		getByPlaceholderText('Enter a phone number')
		fireEvent.click(getByTestId('toggle-icon'))
		getByPlaceholderText('Email')

	})
})

I get this
Screen Shot 2019-06-21 at 11 27 13 AM

And even my IDE (webstorm) cannot resolve fireEvent

Please what am i doing wrong ?

How to use with Nuxt.js

Hello!

I'm trying to use vue-testing-library with Nuxt.js and I'm facing a problem with asyncData not being called.

I've been reading for a while, and some people call wrapper.vm.$options.asyncData() manually, but that feels super dirty to me, also I don't think vm is available in vue-testing-library

Any idea of how can I do it? I ran out of ideas to be honest.

I've seen @afontcu post about testing api calls but it uses the created life cycle method

Thank you!

store not available in child components

Describe the bug
store is undefined in child components.

To Reproduce
Steps to reproduce the behavior:

  1. Clone https://github.com/mediafreakch/vue-testing-library-bug
  2. run npm install
  3. run npm test

The second test fails.

Expected behavior

Second test passes.

Screenshots

Related information:

  • @testing-library/vue version: 4.1.0
  • Vue version: 2.6.11
  • node version: 12.13.1
  • npm (or yarn) version: npm 6.12.1

Relevant code or config (if any)

Additional context

Unfortunately the example doesn't run in Codesandbox. There is an issue with they're bundler.
You need to clone the repo and run it locally to reproduce the bug.

I managed to get the same app tested using pure @vue/test-utils. I will link the corresponding codesandbox example as soon as I have recovered it. Codesandbox example of @vue/test-utils

Issues rendering functional components

Given the following test:

import { render } from '@testing-library/vue'

const Functional = {
  functional: true,
  template: `<p>Hi!</p>`,
}

it('renders functional comp', () => {
  const { getByText } = render(Functional)

  getByText('Hi!')
})

Running tests output the following error:

imatge

The error is obviously gone when removing the functional: true attribute.


However, creating a SFC component and setting the functional tag on <template> works:

<template functional>
  <p>Hi!</p>
</template>

Then, tests don't break.

On the other hand, using SFC then throws when trying to use afterEach(cleanup):

[vue-test-utils]: wrapper.destroy() can only be called on a Vue instance

In this case, setting a wrapper component to render the functional one solves the issue. I was hoping I could fix the other issue the same way, but didn't work πŸ˜• I'm guessing internal implementation for creating a functional component changes due to SFC.

I could submit a PR to provide a wrapper element if the rendered component is functional, but that won't solve all problems (probably). Is still worth the effort? Can you think of any other possible solution?

Rendering an imported component in slot

I'm rendering a component like this:

 const { baseElement } = render(MyForm, {
      components: { MyInput },
      propsData: {
        onSuccess
      },
      slots: {
        default: `<MyInput label="firstName" name="firstName" />`
      }
    });

Unfortunately, I'm still getting

 [Vue warn]: Unknown custom element: <MyInput> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Is there a solution to this? Thanks!

Cannot access router/history for assertions in test.

The goal

I want to be able to have access to my vue router instance post render so that I can keep track of where the current location is, so that I may do assertions about my router and ensure the current path is correct. I may also want to do manual triggers of URL changes after the component is mounted.

This could also be an extended idea for the store, so that I may check the internal state, or push actions to post mount.

The issue

The way I tried to get around this was to capture the router in the third parameter of the render function, since it is returned as an argument. This is along with the store and vue instance. But this didn't seem to work without causing my test to go a bit nuts.

Heres what I would expect:

it('Should go home when cancel button clicked', async () => {
  const { router, getByText } = render(MyVueComponent);
  await fireEvent.click(getByText(/cancel/i));
  expect(router.currentRoute.path).toBe('/home');
})

Is there a better way of handling v-model?

Hi! I know that #16 has been closed and that there's an answer to the original question, but I was wondering if there's any advance in the idea of a fireEvent.update method.

I guess it'd make sense to come up with a way of handling input data consistently, without depending on v-model being there... am I right? For that to happen, should the issue mentioned here be fixed? By the way, is there an open issue in the official library repo? Failed to find any reference.

Thanks, and thank you for your work with this library. Testing is pleasant again.

Set Vue as a peerDependency?

And same think with vue-template-compiler (required by vue-test-utils).

We should be using Vue's version provided by the project where VTL is running. Both libraries should be added as a devDependency too.

I guess that'd could be considered a breaking change..?

Any thoughts? Am I missing something? RTL is doing the same thing.

Where should docs live?

Hi! So, right now, there are two similar (but no exactly equal) versions of Vue Testing Library docs: in the README of this repo, and also in https://testing-library.com/vue.

Kent suggested here to keep the docs in the official website, and just point there from the repository README. How would you feel about that? Having a website seems more useful, as the docs could have several pages (intro, examples, setup, etc as other libraries) instead of having a single file.

I'll happily submit a PR for the README if you think that's the right approach!

this.$router is undefined

🐞 bug report

Description

Tests are failing when a component uses router instance to redirect.
The component does call a callback that makes a redirect programmatically.

 onSuccess() {      
   this.$router.push('/')
 }

πŸ”₯ Exception or Error


TypeError: Cannot read property 'push' of undefined

🌍 Your Environment


    "jest": "^24.7.1",
    "jest-dom": "^3.1.4",
    "jest-mock-axios": "^3.0.0",
    "vue-jest": "^3.0.4",
    "vue-template-compiler": "^2.5.21",
    "vue-testing-library": "^0.16.0"

Automatically cleanup if afterEach is detected

Right now, users need to call afterEach(cleanup) or configure Jest to do so. This makes sure test run in isolation, but requires manual action.


As React Testing Library just did, we should probably automatically call cleanup if afterEach method exists.

RTL ended up offering two opt-out mechanisms (via custom import or using an env variable), but I'm not sure this is totally needed. I would keep the env variable (VTL_SKIP_AUTO_CLEANUP), but still have a single import point (instead of creating that "pure" version on VTL). Not a big deal, though.

So a PR (or several PRs) should:

  • Automatically call afterEach(cleanup) if afterEach exists.
  • Add an opt-out mechanism by using VTL_SKIP_AUTO_CLEANUP.
  • Add tests asserting the behavior outlined above.
  • Remove cleanup references from tests and docs.
  • Replace cleanup-after-each with a warning (reference).
  • State that the change is a breaking change (so that we take it into account when merging!).

After that, we'd need to update the official docs.

I'm marking this as a good first issue since details are outlined and the referenced PR from RTL makes a great starting point :)

Vue router configuration not working with mocha-chai

Describe the bug

When trying to use the router option in a mocha + chai project, it fails with TypeError: VueRouter is not a constructor

To Reproduce

Run unit tests:

https://github.com/FCalabria/testing-library-mocha

The same project with jest, works perfectly.

Related information:

  • @testing-library/vue version: 4.1.0
  • Vue version: 2.6.10

Changing the way to import the library fixes the bug, but breaks it for jest

const VueRouter = require('vue-router') // current code, works with jest
const VueRouter = require('vue-router').default // fix for mocha, breaks jest

How to test methods in the component?

I've seen the testing examples like simple-button.js which has :
await fireEvent.click(getByRole('button')) and tests the emitted() function.
But how can I actually test the handleClick method in the Component:
<button @click="handleClick">{{ text }}</button>.
I want to be able to write something like: expect(handleClick).toHaveBeenCalled().
Or for a component with mounted hook:
mounted() { doSmth(x, y, z) }
expect(doSmth).toHaveBeenCalledWith(x,y,z)
I can't find any solution for that problem in the docs https://testing-library.com/docs/vue-testing-library/api or any other examples here.

Feature parity with react-testing-library

I last used react-testing-library and just loved it so I'm trying use vue-testing-library now. I see that there are some features that are missing or not explained.

  1. Not all dom-testing-libarary methods are exposed to the user like done for the react library here.
  2. Ability to create a custom render.

I'm interested in this project and willing to help. Is this something we have on the roadmap?

Cannot set data properties on a component

Describe the bug
From what i've heard this library is a wrapper around @vue/test-utils, one of the most handy functions I find with that library is the wrapper.setData() method. I cannot do that with this library.

Expected behavior

When rendering a component I should be able to set the data attributes on rendering.

const { debug } = render(Component, {props: {}, data: { someProperty: 'string' } } );
debug(); // see string in the template etc.

Related information:

  • @testing-library/vue version: 4.1.0
  • Vue version: 2.6.10
  • node version: 10.16.0
  • npm (or yarn) version: 6.9.0

Simple Button isn't "idiomatic" Vue

I just noticed that some tests, such as the Simple Button one, are using a callback prop approach, which is widely used in React.

However, since Vue suggests emitting events instead of passing callback functions, would it make sense to update the example and show how to test for an event to be emitted? I could help with that.

Thanks!

can't use vuetify before rending a component

Describe the bug
I would like to add vuetify to vue before rending a component that uses vuetify components, so that the render is successful

To Reproduce

  1. create a component that uses <v-btn>Ok</v-btn>, making sure it renders correctly in browser (follow vuetify instructions)
  2. write unit test for it. Classic example using the vue/testing-utils:
import { createLocalVue, mount, shallowMount } from '@vue/test-utils'
import Home from '@/components/Home.vue'
import vuetify from "vuetify"

describe('Home.vue', () => {
  let wrapper;
  let title = 'Weather App'
  beforeEach(()=>{
    const localVue = createLocalVue()
    localVue.use(vuetify)

    wrapper = shallowMount(Home, {
      localVue // this is important
    });
  })

vuew/test-utils exposes createLocalVue, which testing library is not using. There is no way to pass localVue to the "render" method of testing-library.

  1. unit test code using the testing-library
import { render, fireEvent } from '@testing-library/vue'
// import { createLocalVue} from '@vue/test-utils'

import UserForm from "@/components/UserForm.vue";
// import vuetify from "vuetify"

test('properly handles v-model', async () => {
  // const localVue = createLocalVue()
  // localVue.use(vuetify)

  const { getByLabelText, getByText } = render(UserForm) // no way to pass "localVue"
..
})

fails with

 console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
    [Vue warn]: Unknown custom element: <v-btn> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Expected behavior
Should be able to load vuetify to the vue before rending a component.

Related information:

  • @testing-library/vue version: 4.1.0
  • Vue version: 2.6.10
  • node version: 11.x
  • npm (or yarn) version:

Vue router example not working as expected

image

As we can see in the screenshot the <router-view /> is not rendered. Instead, a comment block is rendered and the route component is not rendered.

The test just checks for the location so it passes but in actuality, the child elements are not rendered.

some packages are shown as security issues

when running npm install, there are three deps that are giving security issues:
handlebars is fixed with npm audit fix (i'll make a PR), but other two are showing:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Moderate      β”‚ Regular Expression Denial of Service                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ semver                                                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=4.3.2                                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ kcd-scripts [dev]                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ kcd-scripts > rollup-plugin-node-builtins > browserify-fs >  β”‚
β”‚               β”‚ levelup > semver                                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/31                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Moderate      β”‚ Memory Exposure                                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Package       β”‚ bl                                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Patched in    β”‚ >=0.9.5 <1.0.0 || >=1.0.1                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Dependency of β”‚ kcd-scripts [dev]                                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Path          β”‚ kcd-scripts > rollup-plugin-node-builtins > browserify-fs >  β”‚
β”‚               β”‚ levelup > bl                                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ More info     β”‚ https://npmjs.com/advisories/596                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Setting initial route fails when routes have dynamic import

Describe the bug
There is a test which shows that initialising a router can be done by pushing a path. We use dynamic imports to lazy load our routes. In combination, this results that the initial route is not set at all.

const {queryByTestId} = render(App, {routes}, (vue, store, router) => {
router.push('/about')
})

To Reproduce
Change the following line to

{path: '/about', component: () => import('./components/Router/About.vue')},

and run the tests.

{path: '/about', component: About},

Expected behavior
I expected that to work right out of the box or with help of waitFor or something... But I did not manage to get it working.

Coveralls integration is broken

I'mn assuming it has something to do with the relocation of the package under testing-library umbrella. Am I right @dfcook?

Is there anything I could do to fix it other than requesting coverall access to testing-library organization?

Thanks!

Simulating user input

Hey guys

Firstly thanks heaps for the great library :)

Just wondering if there's currently a better way to update an input bound with v-model instead of using updateState? In this example it's mentioned that it's waiting on an issue with @vue/test-utils to be able to update v-model properly, but as far as I'm aware, vue test utils allows you to do something like element.trigger('change', 'newValue') and it will update.

for example, given the below:

  it('tests vmodel', async () => {
    const cmp = Vue.extend({
      data() {
        return {
          foo: 'bar',
        }
      },
      render() {
        return (
           <div>
             <div>{this.foo}</div>
             <input placeholder='test' vModel={this.foo} />
           </div>
        )
      },
    })
    const {getByText, getByPlaceholderText} = render(cmp)
    getByText('bar')
    const input = getByPlaceholderText('test')
    await fireEvent.change(input, {target: {value: 'test'}})
    getByText('test')
  })

what would be the best way to ensure that when users enter data into the input that it's updated. The above test would currently fail at the getByText('test') assertion. However if we used vue test utils and did something like:

const textInput = wrapper.find('input')
textInput.setValue('test')

it would apparently pass ( see here )

updateState does work, but it seems to kind of defeat the purpose if we're not really checking that the input is bound correctly to the model.

Thanks again!

Composition API: rendered instead of a child component

EDIT: This seems to be Composition API related. The button does not get rendered because
I use <component :is="componentType"> and componentType is coming from setup() which does not get called. In vue-test-utils I could pass localVue that would have Vue.use(Composition). Is there a way for this here?

I'm rendering a component that has several child components. My buttons could not be found. At first I thought it's a shallow render by default but that's not the case.

<ProfileImage> gets rendered without a problem
<FileUpload> too

But instead of <Button>s I'm seeing <!----> in the html output.

Is this because it's a one word component that also shares name with an HTML element? Or that shouldn't be an issue?

The tested component and also <ProfileImage> and <Button> use composition API.

Thanks!

Question about (engine property) in the package.json file

Hello
I have a question
Why did you add engine property in the package.json file? I have an issue with this because it makes an error in my ci/cd. that issue is my node engine version is not compatible whit engine that you added in package.json file and pipeline break up.

Add accordion/dropdown test demo

It is a common UI pattern, so it'd be great if VTL provided a simple test example.

It could feature:

  • an accordion/dropdown using v-show
  • asserting visibility (and non-visibility) with .toBeVisible() from jest-dom.

Npm installation error (VueJS/Typescript)

Bug:

On a VueJS project, using the npm install command and basic import statement ( import { render, fireEvent, cleanup } from '@testing-library/vue']) raises an error:

  • Could not find a declaration file '@testing-library/vue'

The error recommends installing @types/testing-library__vue. But attempting to install this provides another error message:

  • @types/testing-library__vue@latest is not in the npm registry.

To reproduce:

  • Spin up a vue app with Jest as the default testing provider and use typescript
  • Open a .spec.ts file
  • Run the npm install for vue testing library
  • Add import { render, fireEvent, cleanup } from '@testing-library/vue';
  • IDE picks out import library as an error, npm run test will no longer run successfully
  • Installing the suggested library @types/testing-library__vue --save-dev is unsuccessful

Related information:

  • @testing-library/vue version: ^1.1.0
  • Vue version: ^2.6.10
  • node version: 10.15.3
  • npm version: 6.9.0

Related code/config:

  • Using typescript

Cannot use vue-i18n plugin with current rendering API

The goal

I want to get i18n capabilities in my test using this library, with the popular community vue solution for i18n: vue-i18n.

The issue

In order to make i18n possible using that package, it is currently not possible as far as I can tell. The idea would be that you could pass it to the mountOptions (i.e. second argument of render function), it will not work because it depends on the localVue/Vue being available.

One may think, why not just use the third callback argument and register it there? Agree with you! But there is the problem that you must create the i18n like so in @vue/test-utils:

const localVue = createLocalVue();
localVue.use(VueI18n);
const i18n = new VueI18n({ locale: "en" });

it("Should translate", () => {
  const wrapper = mount(App, { i18n, localVue });
  expect(wrapper.text()).toEqual("Hello World!");
});

The thing to note is that the i18n variable passed into mount. In the current setup of the function, it is impossible to pass this i18n variable in the second argument of render without having a localVue instance available.

Perhaps the third argument could be changed to return a value that is passed in as additional options so that they fall through to the mountOptions? i.e. I imagine passing it as:

import { render as r } from '@testing-library/vue';
import VueI18n from 'vue-i18n';

const messages = {
  en: {
    permission_groups_add_member: 'Add',
  },
};

export function render(ui, { ...opts } = {}) {
  return r(
    ui,
    {
      ...opts,
    },
    vue => {
      vue.use(VueI18n);
      const i18n = new VueI18n({ locale: 'en', messages });
      return { i18n };
    },
  );
}

Roadmap?

Hi! I was wondering if there's any kind of roadmap for VTL to work on.

Not (only) in terms of adding features (not sure the API surface should grow that much!), but also regarding the repo itself, and even "marketing".

I have some ideas I'd be willing to work on:

  • Add Prettier to the repo.
  • Run checks on every PR - Run tests, code coverage variations.
  • Fix coveralls integration/badge.
  • Add typings (can't really help on that lol).
  • Improve explanations on tests (by adding comments, for instance).
  • Add more examples (it'd be great if we could decide if we are showcasing major use cases, or something big is missing).
  • Explain how to create a Custom Render.
  • Provide guides to integrate VTL with @vue/cli and Nuxt.
  • Allow user-event to work with Vue (some things need fixing: testing-library/user-event#119).
  • Write/Curate content on "VTL 101" or even advanced patterns.
  • ...

Let me know your thoughts on this :) I'm sure you have other interesting ideas that might be more interesting to work on.

Also I'm not sure what's the best way of organizing those ideas - Maybe using the Projects feature from GitHub?

Add <slot> testing demo

Even though there are no differences between VTL and @vue/test-utils regarding slots, I believe having an example would harm noone.

It'd be great if the example file:

  • Used a simple, default slot.
  • Used named slots.
  • Used scopes slots.
  • Stated that there should be no differences between testing slots in VTL and VTU.

fireEvent.click() on <a> tag doesn't work

Describe the bug
Expectation: fireEvent.click() on tag will change window.location.href, but it doesn't. This is "emulating" a user click on an external link on a Vue app.

To Reproduce
Steps to reproduce the behavior:

it('renders url and comment link properly', async () => {
  const fake_data = [
    { title: 'title number 1', url: 'http://title1.com' },
    { title: 'title number 2', url: 'http://title2.com' }
  ]

  const { getByText } = render(HomePage)
  const firstArticle = getByText(fake_data[0].title)
  // FIXME: this doesn't work
  await fireEvent.click(firstArticle)

  // assert the current browser url
  expect(window.location.href).toEqual(fake_data[0].url)
   
})

Expected behavior
I'm expecting the window.location.href to equal http://title1.com, but I got http://localhost/ instead.

Related information:

  • @testing-library/vue version: 3.0.0
  • Vue version: 2.6.5
  • node version: 10.16.3
  • npm (or yarn) version: 6.9.0

Edit: To be honest, I don't really know whether doing this kind of test is a good idea or not. It feels like I'm testing the implementation details of the a tag. I'd be grateful if anyone can correct me and point me in the right direction.

Shallow Render?

Most of the time when testing with vue-test-utils I would be using a shallow mount. Although I know you can manually stub the components out, the method I think is quite helpful. In addition to render Is it possible that perhaps a shallowRender or something equivalent can be exposed to be used?

How to set initial router route?

I want to be able to change the current vue-router route by pushing a new path, but I don't seem to get access to the router with the render() function.

How am I supposed to change routes with this library?

EDIT: changed title from "How to change router route?"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.