Code Monkey home page Code Monkey logo

vue-test-utils's Introduction

Vue Test Utils Build Status

Component testing utils for Vue 2.

Packages

This repository provides the following two packages:

You can install these packages by the following command.

npm install --save-dev @vue/test-utils@1
npm install --save-dev @vue/server-test-utils@1

Peer Dependencies

You need to install vue-template-compiler which is used to compile components. It should be the same version as the version of Vue you are using.

npm install --save-dev vue-template-compiler

Documentation

Refer to the documentation

Questions

For questions and support please use the Discord chat room or the official forum. The issue list of this repo is exclusively for bug reports and feature requests.

Issues

Please make sure to read the issue reporting requirements before opening an issue. Issues not conforming to the guidelines may be closed immediately.

Contribution

Please make sure to read the Contributing Guide before making a pull request.

Changelog

Changes for each release are documented in the release notes.

Stay In Touch

For the latest releases and announcements, follow on Twitter: @vuejs

License

MIT

vue-test-utils's People

Contributors

38elements avatar afontcu avatar alex-sokolov avatar atofstryker avatar austio avatar blake-newman avatar codebryo avatar dependabot[bot] avatar dobromir-hristov avatar earnubs avatar eddyerburgh avatar hiendv avatar jessicasachs avatar jinjiang avatar kazupon avatar kellym avatar ktsn avatar kuitos avatar leon-win avatar lex111 avatar lmiller1990 avatar lusarz avatar numb86 avatar simon-he95 avatar th3un1q3 avatar tomasbjerre avatar vvanpo avatar winniehell avatar xanf avatar yyx990803 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  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

vue-test-utils's Issues

`Vue.nextTick()` required with transitions.

Version

1.0.0-beta

Reproduction link

https://github.com/autumnwoodberry/vtu

Steps to reproduce

Nest some v-if:

<transition>
  <div v-if="a">
    <transition v-if="b"></transition>
    <transition v-if="!b"></transition>
  </div>
</transition>
test('output', () => {
    wrapper.setData({
      a: true,
      b: true
    });

    expect(wrapper.vm.a).toBe(true)
    expect(wrapper.vm.b).toBe(true)
    expect(wrapper.html()).toMatchSnapshot()
})

What is expected?

wrapper.html() returns the updated markup.

What is actually happening?

wrapper.html() returns outdated markup unless the test is changed to:

test('output', () => {
    wrapper.setData({
      a: true,
      b: true
    });

    expect(wrapper.vm.a).toBe(true)
    expect(wrapper.vm.b).toBe(true)
    Vue.nextTick(() => {
      expect(wrapper.html()).toMatchSnapshot()
    })
})

API for testing emitted events

Related to TODO in #4

Some ideas

// Creates listener on the component
wrapper.listenTo('event', spy) 

//  returns array of events that have been emitted
wrapper.events

Add a getProp and getAttribute methods

Currently we have a hasAttribute, hasProp and hasStyle methods. These aren't great for assertions, as they return booleans. If tests fail, they will fail because they were expecting true but received false.

For example, when asserting attributes with hasAttribute:

expect(wrapper.hasAttribute('attribute', 'value')).toBe(true) // expected false to be true

An alternative would be to have a getAttribute function:

expect(wrapper.getAttribute('attribute')).toEqual('value') // expected 'wrong value' to equal 'value'

This makes debugging a lot easier, and provides a better testing experience.

I think we should add get methods for props and attributes. We could do the same with style, but this won't be ideal - because the styles we return will be the computed styles:

expect(wrapper.getStyle('background')).toEqual('red') // expected 'rgb(250, 251, 252) none repeat scroll 0% 0% / auto padding-box border-box' to equal 'red'

I think we should keep hasAttribute, hasProp and hasStyle, but add getAttribute and getProp

code puzzles

I do not understand the code

const consoleWarnSave = console.error
  console.error = () => {}
  if (attrs) {
    vm.$attrs = attrs
  } else {
    vm.$attrs = {}
  }
  console.error = consoleWarnSave

why save the console.error and reset to it at the last ???

Synchronous updates don't work on $slots

Version

1.0.0-beta

Steps to reproduce

Create a component that uses slots:

// SlotComponent.vue
<template>
  <div>
    <slot></slot>
  </div>
</template>

Use this component in some Parent.vue:

<template>
  <SlotComponent>
    <div :class="[{ 'is-on': on }, 'inner']"></div>
  </SlotComponent>
</template>

<script>
//...
export default {
  //...
  props: {
    on: {
      default: false,
      type: Boolean
    }
  },
  // ...
}
</script>

What is expected?

Setting props should synchronously update the template, but this test fails:

const parentWrapper = mount(Parent)
const innerEl = parentWrapper.find('.inner')

expect(innerEl.hasClass('is-on')).to.equal(false)

parentWrapper.setProps({
  on: true
})

expect(innerEl.hasClass('is-on')).to.equal(true)

What is actually happening?
nextTick is still required to update slot content.

Solution
Looks like Vue's vm._update function clones existing slots and does not update them unless the parent has updated. To fix this in our test we can trigger an update on our SlotComponent.vue:

parentWrapper.setProps({
  on: true
}) // calls parentWrapper.update

childWrapper = parentWrapper.find(SlotComponent)
childWrapper.update() // no nextTick required with this

Testing properties validation

How's it possible to test when a property doesn't match a validation rule? So far, I've managed to do it as so, but it feels a bit hacky (jest in the example):

const createCmp = propsData => mount(Message, { propsData })
...
    it('message is of type string', () => {
      let spy = spyOn(console, 'error')
      cmp = createCmp({ message: 1 })
      expect(spy.calls.mostRecent().args[0]).toEqual(expect.stringContaining('Invalid prop'))
    })

Does vue-test-utils provide a better way for this?

Discussion: Best API for stubbing methods?

Currently, to stub methods on a component you need to do this:

const wrapper = mount(TestComponent)
wrapper.vm.clickHandler = sinon.stub() // Stub the method
wrapper.update() // Force the vm to update
wrapper.find('button').trigger('click')
expect(wrapper.vm.clickHandler.called).to.equal(true)

I think we should either add a method, or an option that stubs component methods:

// Method
const wrapper = mount(TestComponent)
wrapper.stubMethod(clickHandler, sinon.stub()) // Stubs the method and forces update
wrapper.find('button').trigger('click')
expect(wrapper.vm.clickHandler.called).to.equal(true)

It could also be called setMethods, like the setData and setProps methods, and take an object.

// Option
const wrapper = mount(TestComponent, {
    stubMethods: { // stubs methods before mount
        clickHandler: clickHandlerStub
    }
})
wrapper.find('button').trigger('click')
expect(wrapper.vm.clickHandler.called).to.equal(true)

Personally I prefer the stubMethod/ setMethods approach, but I'd like to hear peoples thoughts ๐Ÿ™‚

Problem with stubbing global properties

When I try to do:

const $route = { path: 'http://localhost/some/internal/path' } 
wrapper = mount(Component, {
  intercept: {
    $route
  }
})
expect(wrapper.vm.$route.path).to.equal($route.path)

I get error:

setting a property that has only a getter
webpack:///~/vue-test-utils/dist/vue-test-utils.js:861:0 <- index.js:71637:25
forEach@[native code]
install@webpack:///~/vue-test-utils/dist/vue-test-utils.js:860:0 <- index.js:71636:49
use@webpack:///~/vue/dist/vue.esm.js:4314:0 <- index.js:9612:27
createConstructor@webpack:///~/vue-test-utils/dist/vue-test-utils.js:916:0 <- index.js:71692:20
mount@webpack:///~/vue-test-utils/dist/vue-test-utils.js:971:0 <- index.js:71747:29

How to read input value

I want to read input value in my tests. I can do it easily with querySelector:
const value = wrapper.vm.$el.querySelector('input').value

but I would like to use wrapper method, something like:
const value = wrapper.find('input').getInputValue()

Is it possible with current wrapper API ?

Handling promise resolution

Sorry if this should go in the forums or chat, but I was a little confused about this section in the docs: https://vue-test-utils.vuejs.org/en/guides/getting-started.html#what-about-nexttick

It states

To simplify usage, vue-test-utils applies all updates synchronously so you don't need to use Vue.nextTick in your tests.

This is true if you are only doing DOM manipulation, but as soon as you are waiting for Promise resolution, I do not believe the statement holds.

I have what I think is a pretty common pattern in a component that I am trying to test, where it loads data from an API when it is created, and presents it in a list. Simply calling wrapper.update(), as far as I can tell, only re-renders the DOM, but does not push forward the event loop like Vue.$nextTick() does.

Explicitly calling wrapper.vm.$nextTick() does still push the event loop forward, and I get my data rendered in the DOM.

Is that the expected way to handle things in vue-test-utils? If so, I think it might be helpful to amend the What about nextTick section to clarify that nextTick is still needed for things like resolving asynchronous data retrieval.

[Feature Request] Better Documentation for Unit Testing

Current unit-testing resource for Vue is pretty scarce.
The documentations in avoriaz (thank you! @eddyerburgh for bringing this framework up) are great and really helpful, but not all developers aware of the better way to approach unit testing in Vue. Currently, I'm trying to introduce avoriaz to the js devs in my company and most of them not doing vue unit test the right way (in my opinion).

Take example of this issue where we have to wrap the unit test in extended Vue instance, which
I believe most people not aware of #2

My proposal is that to document the "right" way to unit testing in Vue's documentation in order to create a standard way. Which I believe, will be using vue-test-utils as the unit-test framework.

Is this request can be categorized as feature-request?
Thanks! ๐Ÿ˜„

p.s.: I don't intend to push developers to use one specific unit-testing framework. Every developer has the freedom to use / create something better, else we won't be using webpack or rollup now

`is` returning undefined when using a Component as the Selector

If you run this test, by cloning the repo and running npm i && npm t you'll see that

expect(cmp.is(MessageList)).toBe(true)

fails because it returns undefined. As I've been debugging, in vmCtorMatchesName, vm.$vnode is undefined, vm._vnode.componentOptions is undefined and there is no vm._node.functionalOptions. Although, there is a vm.$options.name with the right value... maybe is this the property to assert?

vue-class-component use causes html() to return empty html comment

Hello,

I noticed that my single file component which uses Component from vue-class-component is returning an empty html comment ('<!---->') when I print wrapper.html().

Component:

<template>
  <div id="test">
    Test
  </div>
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';

@Component({})

export default class Test extends Vue {
}
</script>

Mounting in test file:
const wrapper = mount(Test);

When not using vue-test-utils, I see the same problem of the empty html comment being returned in vm.$el when I mount the component like so: vm = new Vue(Test).$mount() However I get the expected vm.$el content when I mount the component like this instead:

const vm = new Test();
vm.$mount()

Which I saw in this issue vuejs/vue-class-component#75

Not sure if this issue should be filed to vue-class-component instead.

Thanks in advance,
Kevin

Render component names/ids when shallow

Is it possible/a good idea for shallow() output to included the component names?

Right now shallow(component).html() gives me:

<div data-v-1d62245a="" id="app"><!----> <!----></div>

It would be great if included the name of the component, or similar. For example:

<div data-v-1d62245a="" id="app"><!--Login--> <!--SignUp--></div>

This would me a I could make basic assertions about what components would have been included, based on conditional logic of the component under test.

Let me know if the current behaviour is a deliberate design decision, or if you're interested in a PR.

Behavior of find and findAll

Should find and findAll return all nodes including the root node, or excluding the root node

Including root node:

const compiled = compileToFunctions('<div><div /></div>')
const wrapper = mount(compiled).findAll('div').length // 2

excluding root node:

const compiled = compileToFunctions('<div><div /></div>')
const wrapper = mount(compiled).findAll('div').length // 1

I think it should exclude the root node, but would be interested to hear others thoughts

Find / FindRef: wrapper function to find element based on ref

Suggestion for additional functionality

Currently, there is no functionality built into vue-test-utils to select elements within a component based on $refs and return them within a Wrapper. Our test suite is built around the idea that we can easily tag elements we need to hook onto within tests using $ref rather than some arbitrary "marker class."

I think it might be helpful to include a specific method on the wrapper like findRefs

I'm not sure if this is a widely used strategy but we've found it helpful. Template structures change often and class selectors can easily break or target the wrong element when these changes happen.

Method that return parent

In one of my test scenario I need to get parent of element, something like:

wrapper.find(selector).parent().hasClass('disabled')

What do you think about adding parent method to wrapper ?

Sub-component is undefined

Hi.

When mounting a component including a sub-component I get this error:

TypeError: Cannot convert undefined or null to object

      at node_modules/vue-test-utils/dist/vue-test-utils.js:117:33
          at Array.forEach (<anonymous>)
      at stubAllComponents (node_modules/vue-test-utils/dist/vue-test-utils.js:115:37)
      at shallow (node_modules/vue-test-utils/dist/vue-test-utils.js:991:5)

When stubbing, it happens the component is undefined.

I'm using vue-test-utils 0.1.0
The lib might be loaded by ts-jest.

I'm still investigating but maybe you've got an idea.

Discussion: find(), is() and contains() are inconsistent

I spent some more time in thinking about the consistency of the functions used to interact with the DOM.

So here's the example. The markup looks like this.

<div class="my-wrapper">
  <button>Action</button>
</div>

and assume it's inside the mounted wrapper.

wrapper.find('div') returns the wrapping element
wrapper.findAll('div') returns the wrapping element
wrapper.contains('div') returns false
wrapper.is('div') returns true

That's how it behaves currently. For me this though sparks the questions why find would include the whole markup and contains will start inside the root element. The explanation I found, is that the is function kind of messes up the logic. We treat the wrapper as the wrapping DOM tag, though it's actually a wrapper for the whole Vue component.

I would expect that contains would also include the root element of the markup, as pretty much the Vue wrapper actually contains a div element.
So maybe is should be used in a different way like wrapper.find('.my-wrapper').is('div').
That would make sense to me in verifying the returned element is actually the one I'd expect.
So to get the root element, as it is useful for some tests I'd recommend a new method like node that will return the root DOM node of the markup.

Example:
wrapper.node().is('div') should return true
If we then decide, calling is on the wrapper directly should do the same as a shortcut, I would totally agree. But Then I'd also expect that the wrapper.contains('div') should also return true in our current case.

wdyt?

data() is not available

Not sure this is on purpose, but it seems that
wrapper.data() is no longer valid.

Is it preferred to use the vm object directly?
It's still in the API docs of setData() that's why I'm asking.

I checked, and it's no longer in the source code, so I guess it was removed.
Should I update the documentation accordingly?

When mount the component, will error!

I found when I mount a component, it will render a commend node.But if I change the source of mount function like this:

export function mount (component, options) {
  if ( options === void 0 ) options = {};

  if (!window) {
    throwError('window is undefined, vue-test-utils needs to be run in a browser environment.\n You can run the tests in node using JSDOM');
  }

  var componentToMount = options.clone === false ? component : lodash.cloneDeep(component);
  // Remove cached constructor
  // delete componentToMount._Ctor;
  var vm = createConstructor(componentToMount, options);

  if (options.attachToDocument) {
    vm.$mount(createElement());
  } else {
    vm.$mount();
  }

  return new VueWrapper(vm, { attachedToDocument: !!options.attachToDocument })
}

I remove the statement delete componentToMount._Ctor, it will work!

Code splitting support

Theoretically we should be able to support async components imported by the tested component when using mocha-webpack with the following config:

  • target: 'node' for webpack
  • optimizeSSR: false for vue-loader

But there are still some issues right now that prevents it from working. Need to investigate a bit further.

Most of the time splitting is done at route level so this is not a high priority concern, but would be nice to figure it out down the road.

Design / Roadmap

Following the forum thread, using this issue to kick off work on an official unit testing utility lib. We are planning to built on top of @eddyerburgh 's Avoriaz, since it seems to be the most mature one currently, and Edd has kindly offered to work on it. Of course, we would also like to pull in ideas from other community solutions and make this a collaborative effort, so I'm pinging some community members that might also be interested in contributing here: @callumacrae, @asselin, @jackmellis, @codebryo, @BosNaufal.

I think the first step is outlining what feature set we are aiming for - here's some high level goals:

  • Two rendering modes: deep, real DOM vs. shallow, virtual DOM
  • Both modes with ideally the same traversal / event simulation / assertion API
  • Ability to easily stub component assets / router / store
  • Ability to output a serialized snapshot for Jest snapshot testing
  • Test runner agnostic

in the meanwhile, feel free to provide general feedback on some of the needs you've run into while unit testing Vue.

Also @vuejs/collaborators for any potential input.

Add component instances to slots on mount

Is there a way to somehow pass component instances to the slots property of mount? The use case is, say I have a component that has a required property:

export default {
    name: 'Message',
    props: {
      message: {
        type: String,
        required: true,
        validator: value => value.length > 1
      }
  }

Then if in a test I wanna add a list of Message as the default slots, I cannot do it like it's documented: I'll get a "message" property is required error:

mount(MessageList, {
  slots: {
    default: messages
  }
})

I tried using mount and getting the vm out of it, or also extending the component and using new Vue(...) but I get the error [Vue warn]: Failed to mount component: template or render function not defined.:

beforeEach(() => {
  const indexes = [0, 1, 2]
  const messages = indexes.map(i => mount(Message, {
    propsData: { message: `Message ${i}` }
  }).vm)

  cmp = mount(MessageList, {
    slots: {
      default: messages
    }
  })
})

So, how's it possible to accomplish that?

Add Documentation Link to Project Description

๐Ÿ‘‹

I think we should add the link to the documentation in the project descriptions similar to the other vue repos (vue-router, vuex, vue)

Something like

Testing Library for Vue.js.  https://vue-test-utils.vuejs.org/

Example on vuex repo

Centralized State Management for Vue.js. https://vuex.vuejs.org

Passing context to functional components

I propose this API to pass context to functional components:

const context = {
  props: {foo: 'bar'}
}

const wrapper = mount(FunctionalComponent, context)

What are peoples thoughts?

Should shallow rendering stub child lifecycle hooks by default?

I've added shallow to vue-test-utils and avoriaz.

It replaces each childs render function with an empty function, and replaces each child component lifecycle hook with an empty function.

I've already had a user ask if there was a way to bypass the lifecycle hooks stubbing.

I think they should be stubbed by default, but should there be an option to pass that will stop shallow replacing child lifecycle hooks?

What do people think?

Add a getOptions method to Wrapper

As discussed on #34, the idea of having a getOptions method came up, in the same line than #27 for getAttributes and getProps. This would be an abstraction to access the wrapper.vm.$options internal variable. One of the use cases is to test property validation specs, but there might be others.

What notation to use?

  1. Concise: .options(), attributes(), props()...
  2. Verbose .getOptions(), getAttributes(), getProps()...

Let's discuss it

Mocha-webpack setup, can't suppress Vue logging

Using the mocha-webpack setup, I have a required file start.js with the following code:

require('jsdom-global')();
const Vue = require('vue');

// disable Vue logging
Vue.config.productionTip = false;
Vue.config.devtools = false;
Vue.config.silent = true;

global.assert = require('chai').assert;
global.expect = require('chai').expect;

However, Vue is still logging out to the console,

image

Have I missed something?

Missing API doc links

It seems not to be linked existed API docs like findAll on SUMMARY.md.
Is it intentionally?
If not so, I'll create a pull request๐Ÿ˜ƒ

Not working in Browser

Wanted to use this in browser testing using Mocha, chai, sinon, expect... but it seems like this is only meant to be used in Node or at least after building it. I did that using browserify, but it is throwing this error:

VM1397:27 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

This implies that I have to change it's source for it work properly for my case, which is something I think shouldn't happen. I thought maybe I am missing something or maybe that scenario wasn't thought through enough.

Is there a clear proper way of using these utilities in the browser without any complicated setup processes. Simply getting the script using the script tag and start using it right away.

Testing globally registered components props

If you stub a component, the stub copies component props to the stub. This means you can check a stubbed component is passed the correct prop:

const wrapper = shallow(Component)
wrapper.find(StubbedComponent).hasProp('some', 'prop') // true

If you need to stub a globally registered component, like router-link, the props cannot be copied. So you can't check a stubbed component is passed a correct prop, you need to check using $attrs.

const wrapper = shallow(Component, {
  stubs: ['router-link']
})
wrapper.find(StubbedComponent).hasProp('to', 'value') // false
wrapper.find(StubbedComponent).vm.$attrs.to === value // true

One solution is create a stub using props:

const RouterLinkStub = {
  name: 'router-link-stub',
  render: () => {},
  props: ['to']
}

const wrapper = shallow(Component, {
  stubs: { 'router-link': RouterLinkStub }
})

wrapper.find(RouterLinkStub).hasProp('to', 'value') // true
wrapper.find(RouterLinkStub).vm.$attrs.to === value // false

Which isn't ideal.

Solution

A potential solution would be to have a stub factory that took props as an argument.

const RouterLinkStub = createStub({ 
  props: ['to']
})

const wrapper = shallow(Component, {
  stubs: { 'router-link': RouterLinkStub }
})

wrapper.find(StubbedComponent).hasProp('to', 'value') // true

Does anyone have any other suggestions?

Initial TODOs

I copied over the TODOs from #1 (comment) so it's not necessary to hunt them down in the long thread.

TODOs

  • Add shallow method
  • Add emit method? In the proposal this is included in trigger, but it's difficult(impossible?) to implement. Not sure if this is needed, as it will be a thin wrapper around vm.$emit. Won't be added in first version,See #6
  • Add option to stub components
  • Finalize VueWrapper interface. Should it call methods on all wrappers, or default to first wrapper? Using find and findAll
  • Add context option to support functional components see #12
  • Test find and findAll using functional component with context
  • Add flow
  • Add typescript types
  • Handle empty WrapperArray method calls
  • Handle ErrorWrapper method calls
  • Fix some skipped tests copied from avoriaz
  • Link docs to gitbook
  • add deploy script
  • Update docs format to follow Vue docs style
  • Improve docs, especially info on WrapperArray
  • Improve build pipeline. Should dist be included in the source repo?
  • Add CI tool - travis/ circle
  • Add provide option to mount
  • Add way to add global mixins/plugins/components without polluting global Vue. See #2
  • Add ability to test emitted events - although this can be acheived with wrapper.vm.$on('event', spy). Won't be added in first version, See #6
  • Add a README
  • Link to Documentation in README
  • Add option to pass component as stub, see #11
  • Add release script
  • Stub registered global components when running shallow
  • Throw an error about running in a browser if window is undefined
  • Add git pre commit hooks to check commit message matches guidelines
  • Improve error messages (errors should have format - [vue-test-utils]: error message)
  • Handle options.instance when stubbing global components in shallow
  • Add option to pass array to options.stub
  • Add children option to pass children to functional components
  • Set default branch to dev
  • Remove npm postinstall from master/ release branches
  • Create example projects and link in README
  • Add guides on setting up vue-test-utils
  • Update mount and shallow arguments in documentation

Shallow

I've been playing around with shallow and I think it'll be very difficult to add support for all CSS selectors in find, contains and is.

I just did a speed test of shallow in it's current state vs mount using this test:

it('toggles class when div is clicked', () => {
    const wrapper = shallow(SpeedTestComponent)
    expect(wrapper.hasClass('active')).to.equal(false)
    wrapper.trigger('click')
    expect(wrapper.hasClass('active')).to.equal(true)
    wrapper.trigger('click')
    expect(wrapper.hasClass('active')).to.equal(false)
})

Results

Tests shallow (render in s) mount (render in s)
1 2.6 3.8
10 2. 7 3.6
100 3.7 5.4
1000 86 88

The setup was using mocha-webpack with jsdom in the mount tests.

I ran each test 5 times and took the average.

As you can see, there's a small constant difference between shallow and mount. (also running 1000 tests in 1 file with my setup took a very long time!)

Maybe we should not develop shallow.

Or have a shallow method that stubs all child components and then calls mount.

What do you guys think?

shallow components throwing unknown custom element error

Version

1.0.0-beta.1

Reproduction link

https://jsfiddle.net/Sabazou/uu91qb4w/

Steps to reproduce

Create a component that utilizes another component.
Create a test that shallow mounts the parent component
Run the test

What is expected?

For all unregistered components to be stubbed and the test to pass

What is actually happening?

Vue runtime throws an error.

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


Adding { stubs: ['bButton'] } suppresses the error but seems to defeat the purpose of calling shallow in the first place which seems to be convenience

Pass $listeners with listeners option?

There should be a way to pass values to $listeners.

Currently you can pass $attrs using the attrs option:

mount(Component, { attrs :  { someProp: 'value' } })

Do people agree on adding a listeners options, for $listeners:

const listeners = { someListener: () => {} } }
const wrapper = mount(Component, { listeners })
expect(wrapper.vm.$listeners).toBe(listeners)

Other suggestions for the name are on, and $listeners. I think it should be listeners, to match attrs.

Problem with this.element

I wanted to use hasClass method this way:
expect(wrapper.hasClass('some-class')).to.be.true
but I've got error:
undefined is not an object (evaluating 'this.element.classList.contains')
while this one:
expect(wrapper.vm.$el.classList.contains('some-class')).to.be.true
works.

I've tried to debug it a bit, and added these lines into hasClass method:
console.log(this.element);
console.log(this.vm.$el);

and I've got output:
LOG: <!---->
LOG: <div class="some-class">...</div>

What do you think? It's ok that element and vm.$el are different?

Vuex example correction

Hi,

I used avoriaz previously, now trying this. I notice in this page https://vue-test-utils.vuejs.org/en/guides/using-with-vuex.html

The example says:

it('calls store action actionClick when button is clicked', () => {
    const wrapper = mount(Actions, { store })
    wrapper.find('button')[0].trigger('click')
    expect(actions.actionClick.calledOnce).toBe(true)
  })

I didn't run this example sample, but one very similar - my component also only has one button, and two <input>. I had to go wrapper.find('button').trigger('click'), without the [0] index.

Maybe this is just a slight error - I think avoriaz would use the [0] regardless, but vue-test-utils does it a little different?

hasAttribute

Currently hasAttribute checks for DOM attributes. It doesn't check for $attrs.

I can see this causing confusion.

Should There be a separate hasAttrs method?

Should hasAttribute check $attrs if the wrapper is a component wrapper?

Getting started with the vuejs-templates/webpack (& Karma)

Hi guys, excellent repo and docs thanks a lot!

I was wondering, are there any plans to expand the documentation to cover getting started with the vuejs-templates/webpack since it's probably the most popular official starter out there (4500+ stars)

The starter has a nice out of the box karma / mocha / sinon / chai unit test framework.

Current documentation doesn't mention anything about Karma. I believe it could be helpful to many to embrace the test-utils into their workflow.

What do you think? Can it be done? Would you like help on this?

Cheers

shallow components throwing unknown custom element error

Problem

Trying to test a component that has dependency on some bootstrap-vue components.

component = shallow(Banner, {
  propsData: {
    'text': 'This is a banner'
  }
})

By calling shallow it is stubbing these components but the vue runtime is throwing errors. causing test failure.

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

    (found in <Root>)

Stubbing components

We have discussed adding an option to stub components to mount (shallow does this by default).

Do people agree with this API:

mount(Component, stub: {
  ComponentName: '<div />',
  AnotherComponentName: Component
})

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.