Jest testing React component using Electron-Remote in ElectronJS - node.js

I'm currently developing an ElectronJS application using React for the UI. In some React components I'm using nodeJS packages via Electron remote, so I import packages from the main process into the renderer process. Looks like this:
main.js
global.moment = moment;
Component.js
const remote = window.require('electron').remote;
const moment = remote.getGlobal('moment');
Everything is working fine until I've started to implement unit testing with Jest.
I've created the first following test case:
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
});
Running this test gives me the following output:
TypeError: window.require is not a function
I have no idea how to solve this problem, maybe someone has an idea how to fix this. Maybe somebody have an idea how to setup unit tests for React in Electron which allows to use nodeJS packages in the React component.
I'm thankful for any help.

Try to add this in src/setupTest.js
window.require = require;
reference: Jest Testing Electron/React Component using window.require

Related

Use React to build parts of the application features

Consider having a web application that is based on a complex platform, however, you can design HTML Forms using its designer, and insert standard HTML elements, one of which is HTML Component. You can use this component to add HTLM/JavaScript code as usual.
I followed a tutorial to create a react app without using create-react-app. I managed to develop a sample React app using NodeJs, Babel, and Webpack and managed to deploy the final bundled JavaScript main.js on the target application. All worked fine. Below are the main two files with the source code:
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.querySelector("#root"));
App.js
import React, {useState} from "react";
const App = () => {
let [counter, setCounter] = useState(0);
const increment = () => {
counter++;
setCounter(counter);
}
return <div>This was created from React and Hello World!
<h1>This is a test Header</h1>
<button onClick={increment}>Click here to increment</button>
<br/>
<span>{counter}</span>
</div>
}
export default App;
The Form HTML Component in the Target Web Application:
<div id="root">This Text should be replaced by the React App</div>
<script src="./target/app/path/public/main.js"></script>
Mind you that I ran the command npm run build and it generated the final script main.js which is deployed to the target application.
I am planning to start using React to build specific components for example a combination of Drop-Down Fields and Grid elements which are populated using REST APIs.
The problem is that I have to have one entry JavaScript source file that will render the component using ReactDOM.render(<App />, document.querySelector("#root")), and if I develop say 100 components, but not all of them will be rendered when any Application Form is loaded. I think if the React render() function is invoked and the target DOM element is not present, then it will throw an error (I am not sure though).
So the question is how to design the application so that I can follow the above approach and ensure that the intended React Component will kick in only when the related Form is loaded or active.
I am thinking to import all the Components in index.js and develop a method to detect if the Form is active and needs a component, then it will invoke the function ReactDOM.render(<MyComponent />, document.querySelector("#MyComponentId")).
I am not sure how to implement that and I need help. I appreciate your feedback.

How to do Jest testing in Node app with added React components

We have a Node app that we're going to rewrite in React next year so we're building all of our new .jsx components in React and injecting them into ReactDOM like they describe here: https://reactjs.org/docs/add-react-to-a-website.html
We build the .jsx React components with Babel/webpack before we deploy the site and this works pretty well.
But now I'm trying to write Jest tests for these components and I'm getting an error when I import the React component file into my test:
createRoot(...): Target container is not a DOM element.
How do I get my test to see the container as a DOM element? I've tried using happy-dom and jsdom but they don't see the document object.

'TypeError: fs.existsSync is not a function' ReactJS and Electron

I'm having an issue where I'm getting a TypeError: fs.existsSync is not a function error when my React App loads.
I'm trying to add functionality to my custom MacOS buttons, however, when I seem to import {remote} from 'electron', I get that error.
This is the component source code: https://sourceb.in/1ffad505cd.jsx
This is the error generated in the console: https://sourceb.in/8c01058284.txt
It looks to be an Electron issue but I can't seem to figure out why.
Any help or advice would be much appreciated.
I was facing the same problem and I've spend half of my day looking for the solution Instead of importing or requiring electron in the App.js as
import * as electron from 'electron'
OR
const electron = require("electron")
Go ahead and import electron in your App.js as follows using the window object
const electron = window.require("electron")
I was found this issue : https://github.com/electron/electron/issues/7300
Can you change electron import like this:
const electron = window.require('electron')
and use : electron.remote

Webpack-dev-server and isomorphic react-node application

I've managed to properly use webpack dev server alongside with a node server (express), using the plugin section inside webpack's config.
It all works fine but now I'm trying to go isomorphic and use client-side components inside the express application.
So far the only problem I'm encountering is that without webpack 'parsing' my server-side code I get to a situation where I require components but the paths are not solved
I.E.
Inside a component
'use strict';
import React from 'react';
import { RouteHandler, Link } from 'react-router';
import Header from 'components/header/main'; // <-- This line causes the error because webpack is not working when parsing this JSX server-side
export default React.createClass({
displayName: 'App',
render() {
return ( // ... More code
Shall I configure webpack in another way or do I have to change all the imports to be valid server-side?
the codebase is here in case you want to see the actual state https://github.com/vshjxyz/es6-react-flux-node-quickstart
In order to be able to require components in a way such as require('components/Header.js'); and avoid using long relative paths such as require('../../../../../../Header.js'); you can add this code to your node app before any require() calls:
process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();
However, since this relies on a private Node.js core method, this is
also a hack that might stop working on the previous or next version of
node.
Other possible solutions to this problem can be found at https://gist.github.com/branneman/8048520
I see 2 options:
Compile client code with webpack as well. If client's entry
point is in the same dir as server's - it should work with your
present code. This looks natural to me.
Use relative paths i.e.
import Header from './components/header/main'

include angular in jasmine-node

I'm trying to test an angular module using jasmine-node, my test is setup as
var fs = require('fs');
var angular = require('../bower_components/angular/angular')
var fsm = require('../filesystemModel');
describe("get files",function(){
it("should get files from the file system",function(){
console.log(fsm);
});
});
Unfortunately, this fails to load angular, and therefore, the filesystemModel breaks because angular is undefined. I think this is because angular is looking for window and document, which I don't think are provided in jasmine-node.
I know node-webkit talks about using chromedriver for testing, but I'm trying to be consistent with tests for modules, some of which are available outside of node-webkit, some which require node-webkit.
Any suggestions on getting jasmine-node testing with node-webkit? Or node testing with karma is another option.
You can use Karma which runs the tests in real browsers.

Resources