Laravel VueJS testing TypeError: _vm._ssrEscape is not a function - node.js

I’ve been piecing together a few different tutorials to try and get Mocha tests working for Laravel 7 Vue Components.
I can successfully run a basic test
expect(0).toBe(0);
But as soon as I try and mount a component I get the following error
TypeError: _vm._ssrEscape is not a function
at Proxy.render (public/main.js:154:13)
at VueComponent.Vue._render (node_modules/vue/dist/vue.runtime.common.dev.js:3538:22)
at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4054:21)
at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4465:25)
at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4454:12)
at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4061:3)
at VueComponent.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8392:10)
at init (node_modules/vue/dist/vue.runtime.common.dev.js:3112:13)
at createComponent (node_modules/vue/dist/vue.runtime.common.dev.js:5958:9)
at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5905:9)
at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.runtime.common.dev.js:6455:7)
at VueComponent.Vue._update (node_modules/vue/dist/vue.runtime.common.dev.js:3933:19)
at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4054:10)
at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4465:25)
at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4454:12)
at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4061:3)
I’m running Node 12.18.2.
My test file contains
import { mount } from '#vue/test-utils';
import Counter from '../../resources/js/components/Counter';
describe ('Counter', () => {
it ('defaults to a count of 0', () => {
const wrapper = mount(Counter);
});
});
And my component contains
<template>
<div>
<span class="count" v-text="count"></span>
<button #click="count++"></button>
</div>
</template>
<script>
export default {
name: "Counter",
data () {
return {
count: 0
};
}
}
</script>
The test command is
mochapack --webpack-config node_modules/laravel-mix/setup/webpack.config.js --require tests/Vue/setup.js tests/Vue/**/*.spec.js
And the setup.js file contains
require('jsdom-global')()
global.expect = require('expect');
Thanks for any help

I’ve got this working now.
Using parts of this https://dev.to/tuandm/how-to-test-vue-components-with-laravel-mix-and-mocha-3kgc/
Rather than install mcocha-webpack then uninstalling I went straight to installing mochapack
npm install --save-dev webpack vue-template-compiler #vue/test-utils mocha mochapack jsdom jsdom-global expect

Related

Module not found: Error: Can't resolve '../../../vue-temp/vue-editor-bridge' in 'D:\laravel projects\codeGram\resources\js\components'

i am using laravel + vuejs to do the follow and unfollow button of instagram clone , but i get this error i did everything i could, checked the config.js , deleted the module package and again run the npm install but it didnt work here is my code
<template>
<div>
<button class="btn btn-primary ml-4" #click="followUser" v-text="buttonText">Folloq</button>
</div>
</template>
<script>
import func from '../../../vue-temp/vue-editor-bridge';
export default {
props: ['userId', 'follows'],
watch: {
status: function() {
this.buttonText = (this.status) ? 'Unfollow' : 'Follow';
}
},
data: function () {
return {
status: this.follows,
buttonText: this.follows ? 'Unfollow' : 'Follow'
}
},
methods: {
followUser() {
axios.post('/follow/' + this.userId)
.then(response => {
this.status = ! this.status;
console.log(response.data);
})
.catch(errors => {
if (errors.response.status == 401){
window.location = '/login';
}
});
}
},
}
</script>
my code in the view in index.blade.php for the button is
<follow-button user-id="{{$user->id}}" follows="{{ $follows }}"></follow-button>
route is
Route::post('follow/{user}','App\Http\Controllers\FollowsController#store');
full error
ERROR in ./resources/js/components/FollowButton.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib/index.js??clonedRuleSet-5[0].rules[0].use[0]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./resources/js/components/FollowButton.vue?vue&type=script&lang=js&) 7:0-55
Module not found: Error: Can't resolve '../../../vue-temp/vue-editor-bridge' in 'D:\laravel projects\codeGram\resources\js\components'
I assume you don't want to use this at all:
import func from '../../../vue-temp/vue-editor-bridge';
Vscode imports this 'func' from a module when you want to autocomplete while writing function. This is totally annoying and if anybody knows how to turn it off, you would be my personal hero!
VS Code automatically added in your code line like:
import func from 'vue-editor-bridge'
Find it in your code and remove it. Done!
I faced this problem too, and it happens because, instead of typing complete function in the code, I used the autocomplete version of function which was func and as func is a totally different thing in Vue, as compared to function, Vue just put import func from 'vue-editor-bridge'.
Just change the word func to function and remove this import inside the script tag and it will be ok.
That's how it works for me.
If you are in vue and your error starts like this 'Module not found: Error: Can't resolve 'http' ...' installing url-loader will do the trick. Just install it using npm.
npm install --save-dev url-loader

Cannot import custom NodeJs module in Vue component

I am building a webservice with Node and Vue. I built backend Node modules which are all working as expected. But when I try to import those in my Vue SFC script, I am getting 'stream undefined' error.
My hunch is that I am mixing CommonJS and ES6 styles of exporting and importing and that is causing the issue because when I created a temporary module with just one function and no require or import statements and use module.exports to expose that function and then call import in Vue SFC, it is working. But when I use require statements in the module, I am getting the stream undefined error again. I tried multiple solutions I found online but I am not able to get it to work.
My (temporary) node module, temp.js. This doesn't work:
require('./auth.js');
function test(){
console.log('Test method');
}
module.exports = {test};
This works:
function test(){
console.log('Test method');
}
module.exports = {test};
My SFC script:
<script>
import * as temp from './temp.js';
export default {
name: 'Dashboard'
}
</script>

How to add git hash to Vue.js Component

I want to create a vue.js component which will display the package.json version number and hash of most recent git commit. Here is the code so far:
<template>
<div class="versionLabel">Version: {{version}} (HASH)</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { version } from '../../package.json';
#Component
export default class VersionLabel extends Vue {
get version() {
return version;
}
}
</script>
<style scoped lang="scss">
div {
background-color: rgb(60, 172, 60);
color: lightgray;
}
</style>
I am deploying to Heroku using the commands
"postinstall": "if test \"$NODE_ENV\" = \"production\" ; then npm run build ; fi ",
"start": "node server.js",
in package.json and this simple server:
const express = require('express');
const serveStatic = require("serve-static")
app = express();
app.use(serveStatic(__dirname + '/dist'));
const port = process.env.PORT || 5000;
app.listen(port);
The version number is working (Although suggestions for improvement are welcome) but how can I add the git hash in place of HASH?
Install git-describe as a dev dependency (e.g. yarn add --dev git-describe).
In vue.config.js add:
const {gitDescribe, gitDescribeSync} = require('git-describe');
process.env.VUE_APP_GIT_HASH = gitDescribeSync().hash
Now, in every component, we have process.env.VUE_APP_GIT_HASH variable.
Here is how I added it to my app: https://github.com/Quantum-Game/quantum-game-2/pull/164 (with some discussion).
Other approaches
There are other approaches, e.g. using git-revision-webpack-plugin (example for the Vue forum):
const GitRevisionPlugin = require('git-revision-webpack-plugin')
module.exports = {
'chainWebpack': config => {
config.plugin('define').tap(args => {
const gitRevisionPlugin = new GitRevisionPlugin()
args[0]['process.env']['VUE_APP_COMMIT_HASH'] = JSON.stringify(gitRevisionPlugin.commithash())
return args
})
}
}
Another way is to use git directly, with child-process.
See also
Including git commit hash and date in webpack build
Get hash of most recent git commit in Node
Git log output to XML, JSON, or YAML?
I'm not familiar with Heroku, however I hope some parts of my solution you'll find useful.
I'm developing a vue application, I use GitLab CI/CD and it's deployed to an S3 bucket on AWS then distributed with cloudfront. Sometimes our client will ask for changes that have already been made. So to prevent confusion I wanted to include a the git hash in the footer of the app so we can quickly check that they are looking at the most up-to-date version of the app.
In my .gitlab-ci.yml file I included the following bash commands:
hash=`git describe --always`
echo "\"$hash\"" > src/assets/hash.json
This creates a hash.json file, and the only contents of this file are the most recent commit hash as a string. e.g. "015d8f1"
I assume when you deploy to Heroku there is a similar way to execute bash commands.
From there you can just read in that file in any component and use it as data. e.g.
<script>
import GitHash from "#/assets/hash.json";
export default {
name: "TheFooter",
data() {
return {
GitHash: GitHash
};
}
};
</script>

Accessing Meteor settings in Mocha

I want to do write some unit tests with mocha but for some tests i need to access the Meteor.settings which are read by meteor from a file: config/settings.json
Normally i import meteor by:
import { Meteor } from 'meteor/meteor'
But when i try to import this in my test, i get the error: ERROR: Cannot find module 'meteor/meteor' (i also tried to do relative path).
I run my test by this:
"wdio-test": "wdio tests/config/wdio.mocha.conf.js"
and
npm run wdio-test
Anyone can help importing Meteor or accessing the settings file (If possible without file IO operations)?
Stub the meteor core and the settings object:
import { MeteorStubs } from 'meteor/velocity:meteor-stubs';
describe('tests', function() {
beforeEach(function() {
MeteorStubs.install();
Meteor.settings.public.foo = 'bar';
});
afterEach(function() {
MeteorStubs.uninstall();
});
it('gets setting', function() {
chai.assert.equal(Meteor.settings.public.foo, 'bar');
});
});

Jest can not deal with insertAdjacentElement?

I want to test a quite simple JS function
export function displaySpinner() {
const loadingOverlayDOM = document.createElement('DIV');
const spinner = document.createElement('IMG');
loadingOverlayDOM.id = 'overlay-spinner';
loadingOverlayDOM.className = 'content-overlay';
spinner.className = 'is-spinning';
spinner.setAttribute('src', '/assets/img/svg/icons/spinner.svg');
l loadingOverlayDOM.insertAdjacentElement('beforeend', spinner);
document.body.insertAdjacentElement('beforeend', loadingOverlayDOM);
}
with this (for the purpose of this issue stripped down) Jest test code:
test('displaySpinner displays the spinner overlay in the current page', () => {
utils.displaySpinner();
});
But the test run yells at me:
FAIL app/helper/utils.test.js
● utils › displaySpinner displays the spinner overlay in the current page
TypeError: loadingOverlayDOM.insertAdjacentElement is not a function
at Object.displaySpinner (app/helper/utils.js:185:439)
at Object.<anonymous> (app/helper/utils.test.js:87:15)
at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
at process._tickCallback (internal/process/next_tick.js:109:7)
Is this an error in Jest or am I missing something here?
I finally found the answer myself:
Jest uses jsdom which does not yet support the DOM function insertAdjacentElement (see this issue on GitHub and it's references). So I'll have to wait until jsdom implements it or use another method in my JS.
You can replace the default version of jsdom with an up-to-date version (e.g. 14) by installing the corresponding module:
npm install --save-dev jest-environment-jsdom-fourteen
or using yarn:
yarn add jest-environment-jsdom-fourteen --dev
and then using the jest testEnvironment config parameter:
{
"testEnvironment": "jest-environment-jsdom-fourteen"
}
Note that if you launch jest with the --env=jsdom argument, this will override the config file, so you need to remove it.

Resources