JSDOM : Uncaught TypeError: window.document.getElementByTagName is not a function - jsdom

I am using the JSDOM library for testing my application. Below is my code which I use to test my index.html file
import { expect } from 'chai';
import jsdom from 'jsdom';
import fs from 'fs';
describe('Our first test', () => {
it('should pass', () => {
expect(true).to.equal(true);
});
});
describe('index.html', () => {
it('should have h1 that says Users', (done) => {
const index = fs.readFileSync('./src/index.html', "utf-8");
jsdom.env(index, function (err, window) {
const h1 = window.document.getElementsByTagName('h1')[0];
expect(h1.innerHTML).to.equal("Hello World!..");
done();
window.close();
});
})
})
When I run npm test command I am getting the below error
Uncaught TypeError: window.document.getElementByTagName is not a function
could anyone please assist me

Related

Uncaught TypeError: require. is not a function

I'm using react-quill in next.js.
Occurs an intermittent type error.
This is error message
and my code
import dynamic from "next/dynamic";
import "react-quill/dist/quill.snow.css";
const ReactQuill = dynamic(async () => await import("react-quill"), {
ssr: false,
loading: () => <p>Loading ...</p>,
});
export default function EditorComponent() {
...modules...
return (
<>
<ReactQuill theme="snow" modules={modules} />
</>
);
}
I referred to the error message and found it in .next/static/chunks/webpack.js
/******/ fn.e = function (chunkId) {
/******/ return trackBlockingPromise(require.e(chunkId));
/******/ };
/******/ return fn;
I don't know how I can fix this part and prevent the error from occurring.
Or is there another way?
Is the React-Quill Code wrong?

How to unit test gutenberg class/component method that uses wp.apiFetch

I am trying to unit test a method on a class/component that calls the wp.apiFetch method but when I run the test it always says TypeError: apiFetch is not a function the below structure has worked for other test cases, all be it they don't make any api calls.
Stripped down test setup
global.wp = {};
// some other packages
Object.defineProperty(global.wp, 'apiFetch', { get: () => require('#wordpress/api-fetch') });
Stripped down test
Shallow render the component
Call the method in question on the component instance - at this point here the tests error because of the error mentioned at the top.
Check that the method was called
it('createAuthor valid', () => {
// may have to mock window.fetch as wp.apiFetch uses it but that's currently not the issue
const componentProps = {
someFunc: jest.fn(),
};
const component = shallow(<NewAuthor {...componentProps} />);
component.setState({ name: 'john smith' });
component.instance().createAuthor();
expect(componentProps.someFunc).toHaveBeenCalledTimes(1);
});
Stripped down component
const { apiFetch } = wp;
// some more constants from window
class NewAuthor extends Component {
// constructor
// method to test
createAuthor = () => {
const { someFunc, someErrorFunc } = this.props;
const authorObject = {
name,
} = this.state;
const createPath = '/wp/v2/users';
apiFetch({
path: createPath,
data: authorObject,
method: 'POST',
})
.then((user) => {
console.log('success', user);
someFunc();
})
.catch((error) => {
console.log('error', error);
someErrorFunc();
});
};
// some more methods
// render
}
export default NewAuthor;

CSS import in React Component not working in Electron app

First of all, I want to say sorry because I feel like I lack some theorical background for this problem, but right now I am stuck so here I am.
I want to set up an Electron app with just the usual main.js entry point which handles BrowserWindow creation. I want to create multiple, different windows, so the boilerplates I found on the Internet are no good for me.
So, my main.js creates a window by using an .html file that uses a script tag to add its renderer, that just sets up a React component like this:
const React = require('react');
const ReactDOM = require("react-dom");
const ReactComponent = require('path/to/component').default;
window.onload = () => {
ReactDOM.render(<ReactComponent />, document.getElementById('my-component'));
};
My component is very basic so far:
import React from 'react';
import './ReactComponent.css';
class ReactComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="ReactComponent">
some text
</div>
);
}
}
export default ReactComponent;
And the .css is even simpler:
.ReactComponent {background-color: red;}
I used Gulp + Babel to compile my code, and everything works well until I add that
import './ReactComponent.css';
Which throws this error:
Uncaught SyntaxError: Unexpected token .
Reading the .css file.
Here is my .babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
And my gulpfile.js:
const spawn = require('child_process').spawn;
const gulp = require('gulp');
const maps = require('gulp-sourcemaps');
const babel = require('gulp-babel');
const css = require('gulp-css');
const path = require('path');
/* Build */
gulp.task('build-css', function () {
return gulp.src('src/**/*.css')
.pipe(maps.init())
.pipe(css())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/src'));
});
gulp.task('build-js', () => {
return gulp.src(['src/**/*.js', 'src/**/*.jsx', '!src/**/*.test.js'])
.pipe(maps.init())
.pipe(babel())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/src'));
});
gulp.task('build-main-js', () => {
return gulp.src('main.js')
.pipe(maps.init())
.pipe(babel())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/'));
});
gulp.task('build', gulp.series('build-css', 'build-js', 'build-main-js'));
/* Copy */
gulp.task('copy-html', () => {
return gulp.src('src/**/*.html')
.pipe(maps.init())
.pipe(maps.write('.'))
.pipe(gulp.dest('dist/src'));
});
gulp.task('copy-assets', () => {
return gulp.src('assets/**/*').pipe(gulp.dest('dist/assets'));
});
gulp.task('copy', gulp.parallel('copy-html', 'copy-assets'));
/* Execute */
const cmd = (name) => path.resolve(__dirname) + '\\node_modules\\.bin\\' + name + '.cmd';
const args = (more) => Array.isArray(more) ? ['.'].concat(more) : ['.'];
const exit = () => process.exit();
gulp.task('start', gulp.series('copy', 'build', () => {
return spawn(cmd('electron'), args(), { stdio: 'inherit' }).on('close', exit);
}));
gulp.task('release', gulp.series('copy', 'build', () => {
return spawn(cmd('electron-builder'), args(), { stdio: 'inherit' }).on('close', exit);
}));
gulp.task('test', gulp.series('copy', 'build', () => {
return spawn(cmd('jest'), args(), { stdio: 'inherit' }).on('close', exit);
}));
At this point I don't even know anymore what the problem is... Please send help!
Many thanks!

vue test utils TypeError: this.$moment(...).format is not a function

I am using moment.js and am having trouble mocking the format function am recieving this error:
TypeError: this.$moment(...).format is not a function
could any one point me in the right direction on this please?
import { mount, createLocalVue, } from '#vue/test-utils'
import { expect } from 'chai'
import sinon from 'sinon'
import Vuex from 'vuex'
import authorisation from '../../src/components/settings/Authorisation.vue'
const localVue = createLocalVue()
localVue.use(Vuex)
const renewAuthStub = sinon.stub()
localVue.filter('translate', () => {})
describe ('settings authorisation', () => {
let wrapper
let store
let state
let getters
let actions
beforeEach(() => {
state = {
authorisation: {
authorised: '2018-03-18',
expiry: '03-04-2019',
canBeExtended: true
}
}
getters = {
fetchAuth: () => '',
isLoading: () => false,
authorisation: () => state.authorisation,
highlightDates: () => {},
disabledDates: () => {},
requestLoading: () => false
}
actions = {
fetchAuth: () => {}
}
store = new Vuex.Store({
state,
getters,
actions
})
wrapper = mount(authorisation, {
localVue,
store,
mocks: {
$moment: () => sinon.stub().resolves()
}
})
})
it('lets user know to reactivate when not authorised', () => {
So I realised that I was using udateLocale('en', English) so as a consequence I needed to also use this within my test so therefore needed to add the following:
import { mount, createLocalVue, } from '#vue/test-utils'
import { expect } from 'chai'
import sinon from 'sinon'
import Moment from 'moment'
import English from '../../src/i18n/moment/en'
import Vuex from 'vuex'
import Vue from 'vue'
import authorisation from '../../src/components/settings/Authorisation.vue'
const localVue = createLocalVue()
localVue.use(Vuex)
const renewAuthStub = sinon.stub()
localVue.filter('translate', () => {})
Vue.prototype.$moment = Moment
Moment.updateLocale('en', English)
describe ('settings authorisation', () => {

How to test router code that contains heavy logic using sinon and stubbing (nodeJS)

I am new to using sinon, so sorry if my question is weird, I looked everywhere but can't find a way to do it.
I have app with express router. I want to write uint test for one of the routes. That route have an inner function that is 'heavy', meaning that it is async with promise, and in reality calls an external api. I want to stub that inner function in the test so that it will not use the api, and will return my own data instead of the original method.
This is the code so far:
routes/setOrder.js:
// the inner function I want to stub
var verifyPayment = function(saleId) {
return new Promise((resolve, reject) => {
logger.info(`verifyPayment: ${saleId}`);
externalAPICall.get( // <==this is the 'heavey part!!
saleId,
function (error, sale) {
if(error) {
return reject(`Error querying sale(${saleId}): ${error}`);
}
resolve(sale);
});
});
}
router.get('/paymentId/:paymentId', setOrderWithGet);
const setOrderWithGet =async function(req, res, next) {
const { paymentId } = req.params;
verifyPayment(paymentId)
.then(async sale => {
try {
console.log(`sale:${sale}`);
res.send(JSON.stringify({"status": "ok!" }));
} catch (err) {
logger.warn(err)
res.send(JSON.stringify({"status": "fail.."}));
}
})
.catch(reason => {
logger.warn(`[] Payment(${paymentId}) is not valid ${reason}`);
res.send(JSON.stringify({"status": "fail.."}));
});
}
module.exports = router;
module.exports.setOrderWithGet = setOrderWithGet;
module.exports.verifyPayment = verifyPayment;
setOrderTest.js:
const setOrderStub = require('../routes/setOrder');
describe("POST /setOrder", () => {
beforeEach(() => {
sinon.stub(setOrderStub, 'verifyPayment').resolves({....});
});
afterEach(() => {
sinon.restore();
});
describe("test1", () => {
it("setOrder first attempt", () => {
let req ={params : {'paymentId' : 'mypamentid1'}};
setOrderStub.setOrderWithGet(req,{});
});
});
});
This line:
sinon.stub(setOrderStub, 'verifyPayment').resolves({....});
...stubs the verifyPayment function on the module exports of the setOrder module.
Right now setOrderWithGet is calling the verifyPayment function directly, so it is unaffected by any changes to the module exports.
Change setOrderWithGet to call verifyPayment using the module exports:
const setOrderWithGet = async function(req, res, next) {
// ...
module.exports.verifyPayment(paymentId) // <= call the module export for verifyPayment
// ...
}
...and your stub will get called.

Resources