Issues running jest tests from Stackblitz - jestjs

I am having difficulties running my jest tests from stackblitz.
I have configured a start command in .stackblitzrc but my tests are not run...
My jest config is as follows:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$',
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
setupFilesAfterEnv: ['#testing-library/jest-dom', 'src/setupTests.ts'],
};
Here is the stackblitz:
https://stackblitz.com/edit/react-74twff
Can someone please help?

First, the template you started out with doesn't look like it supports Web Containers. I'm not sure if there's a way to migrate it or not. In order to use Web Containers, you start with a Node-based template and add functionality to that.
Below is a sample I put together that should get you working. You should be able to fork this and add your application's files or use it as a reference when building a new Stackblitz project.
https://stackblitz.com/edit/webpack-5-react-starter-ahpjpn?file=src/app.test.tsx

Related

Jest resolver cannot find a file which path ressembles existing node modules

I have upgraded jest from version 27 to version 29.
Since then, some indirect file resolve do not work anymore.
Here is my config:
module.exports = {
roots: ['app/javascript/__tests__/'],
testMatch: ['**/?(*.)(spec|test).js?(x)'],
testEnvironment: 'jsdom',
testRunner: 'jest-jasmine2',
moduleDirectories: [
'node_modules',
'app/javascript',
'app/javascript/__tests__'
],
transform: {
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^.+\\.(svg)$': '<rootDir>/app/javascript/__tests__/fileMock.js'
},
setupFiles: ['./app/javascript/__tests__/setup.jsx']
}
There is a file in my code base, let's say app/javascript/MyReactComponent.jsx, which is imported as part of my tested component, and that contains the following import line:
// app/javascript/MyReactComponent.jsx
import 'firebase/init'
Expected behavior
Until today, I could run jest, and it was finding all my code as expected, inclluding the above import, which is located here:
app/javascript/firebase/init.js
Error
Instead, running jest throws the following error.
Cannot find module 'firebase/init' from 'app/javascript/MyReactComponent.jsx'
FWIW, I have traced the resolver code up to the default jest resolver, and it seems like it tries to get the file from within the firebase node module, instead of fetching the init.js file in the firebase directory.
Question
Is there a way to adjust my configuration in order for the resolver to find my file?
Have you tried adding an entry for that aliased module in moduleNameMapper?
moduleNameMapper: {
'^.+\\.(svg)$': '<rootDir>/app/javascript/__tests__/fileMock.js',
'^firebase/init': '<rootDir>/app/javascript/firebase/init.js'
}

Jest not working with fs/promises typescript

I'm trying to add jest to my typescript project for testing, but when I run jest, it keeps giving me the error
● Test suite failed to run
Cannot find module 'fs/promises' from 'src/path/to/file'
Require stack:
src/path/to/file
test/test.ts
> 3 | import fsp from 'fs/promises';
at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:311:11)
at Object.<anonymous> (src/path/to/file.ts:3:1)
The program itself runs fine, but whenever I try to run jest on it, it runs into this issue. I've tried adding jest.mock('fs');, which didn't help, and adding jest.mock('fs/promises'); gives the same error in the test file.
I've read that certain versions of Node don't support 'fs/promises' and instead need require('fs').promises, which I've tried and still doesn't work (I'm on Node version 12).
How can I configure jest to be able to load 'fs/promises'? I've included my jest.config.js file below:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: [
'/node_modules/',
'/out/',
],
moduleDirectories: [
'.',
'node_modules'
],
moduleFileExtensions: [
'ts',
'tsx',
'js',
'jsx'
]
}
Turns out Jest is interpreting 'fs/promises' as a folder in the file system, which is incorrect as this is an API from the fs module. To fix this, simply add
moduleNameMapper: {
"fs/promises": "<rootDir>/node_modules/fs-extra/lib/fs"
}
to jest.config.js to tell Jest to map the module 'fs/promises' to the file <rootDir>/node_modules/fs-extra/lib/fs, or wherever the fs module is defined in your file system.

AWS: Steps to pass a node.js application to EC2

I'm newbie with AWS and I'm developing a web application with node.js and react.js. My application works fine in my laptop but I want to upload it to AWS EC2.
When I simulate a production environment in my laptop, I have a /dist folder where are all the code of the front end and the server code is in /src/server folder.
I have uploaded my app to EC2 and now I'm a little bit lost about the next steps.
First, I would like if there is any way to download the modules only if they are not installed
Second, I would like to know if its mandatory to use babel in this environment, because in all tutorial that I have followed to make the development these modules are always installed like a dev depencies. So, is it now mandatory to move all babel modules to dependencies? Right now, my script to this two steps is:
npm -i --production && cross-env NODE_ENV=production babel-node src/server/server.js
If I change babel-node for node then I've got an error with "import" command because I'm not using babel.
My scripts are:
Is there to make a build like I do for the front-end code but for the server code? How can I do it?
Fourt, the server who will be listening the calls to the api will be node server and this will get when I finish to make correctly my aws-start script. But ... Which is the best option to server the front-end pages?
Sorry, I've got too many questions because this is my first app in AWS.
Edit I:
Following the wise advices of #Corrie MacDonald when I build my code I've got this files and folders:
Next, I modify my aws-start script:
npm i --production && cross-env NODE_ENV=production node dist/assets/js/bundle.js
But, I've got this error:
What am I doing wrong?
Edit II:
My webpack.config.babel.js file is:
import path from "path";
import HtmlWebpackPlugin from "html-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
const devMode = process.env.NODE_ENV !== "production";
console.log("devMode: " + devMode);
module.exports = {
entry: "./src/client/index.js", //set entry file
// Resolve to output directory and set file
output: {
path: path.resolve("dist/assets"),
filename: "js/bundle.js",
publicPath: "/assets" //It's mandatory to define this publicPath to get access to the website when we reload pages
//or we access to them directly with url's which have directories of second level like
//http://localhost:4000/directory-level-1/directory-level-2
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/client/index.html", //where is our template
filename: "../index.html", //where we are going to put our index.html inside the output directory
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
}),
new MiniCssExtractPlugin({
filename: "css/bundle.css",
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
})
],
//It help us to detect errors.
devtool: "source-map",
// Set dev-server configuration
devServer: {
inline: true,
contentBase: './dist',
port: 3000,
historyApiFallback: true
},
// Add babel-loader to transpile js and jsx files
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use:[
{
loader: "babel-loader",
query: {
presets: [
"#babel/preset-react"
]
}
}
]
},
{
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader"],
test: /\.css$/
},
{
test: /\.scss$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
sourceMap: true
}
},
{
loader: "saas-loader",
options: {
sourceMap: true
}
}
]
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: "url-loader",
options: {
limit: 10000,
publicPath: "/assets/images/",
outputPath: "./images/"
}
},
{
test: /\.(eot|ttf|woff|woff2)$/,
loader: "url-loader",
options: {
limit: 10000,
publicPath: "/assets/fonts/", //It's mandatory to get access to the fonts when we reload pages or access directly
outputPath: "./fonts/"
}
}
]
}
}
Edit III:
This are the folders of my development environment:
How you can see when I make a build I create the /dist folder with the front-end code, but my server code still being in /src/server folder. How can I create a /dist folder for my server code? Is that possible?
Without going into a lot of detail about automated building procedures, the steps usually go as follows:
Build Code
-- Here, your source code is built and transpiled into a distributable format, which usually goes into a dist/ folder.
Upload your distributable code.
-- Here, all of the files you have built should be uploaded (manually or automatically) to your EC2 instance.
Run a startup script
-- Here, any project startup code should be run in order to actually start your server.
You don't need babel in production because your project should already have been built by that point. However, if you are building on the EC2 instance, instead of just uploading your dist, then you will need it.
In order to turn your EC2 into a routable, reachable web server, you will need to configure some security and routing policies on AWS. You will need to ensure that the instance has a routable IP (or you can use the automatically generated DNS provided by AWS). Secondly, you'll need to ensure that your security policy allows port 80 (at the very least, and any additional ports you need to interact with the server - for HTTPS, SSH or something else.)
Once you have all this in place, you should be good.
EDIT
If you want to serve static HTML pages, you will have to ensure that you have set up your EC2 container as a web server with something like Apache. However, I would recommend that you run your Node Server exclusively from the server and host your static webpack bundle on S3 as a static website.
EDIT 2
Here's an introduction to setting up your EC2 instance for node. - https://medium.com/#nishankjaintdk/setting-up-a-node-js-app-on-a-linux-ami-on-an-aws-ec2-instance-with-nginx-59cbc1bcc68c
Here's an introduction to setting up a static website with S3. - https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html

office-js + outlook-web-addins + Webpack + Production

I am totally new to NodeJS, Webpack and specially to Outlook Addin. So, I created my Outlook Addin using basic tutorials from https://learn.microsoft.com/en-us/outlook/add-ins/addin-tutorial, all went well.
However, when it came to deployment on Production, I struggled a lot. I put all my code up on Production (Ubuntu instance). First tested a simple NodeJS "hello World" app on Port:8080 and it worked just fine. Then I tried to start my Outlook Addin, just like I was doing locally, it started on port 3000, but I needed to run it on 8080 and in the background. So, I used "PM2", and here comes the "WALL".
pm2 start src/index.js doesn't work for me, as the inside Office.onReady or any other reference to Office does not work, throws undefined Office error.
I tried pm2 run-script build, (after modifications in package.json and webpack.prod.js files)
However, I am still getting the same error when try to run pm2 start dist/app.bundle.js
So, please guide me which file should I reference to when using pm2 start {filename/path}?
Here are some configurations that I am using,
webpack.common.js
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
polyfill: 'babel-polyfill',
app: './src/index.js',
'function-file': './function-file/function-file.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.html$/,
exclude: /node_modules/,
use: 'html-loader'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: 'file-loader'
}
]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Production'
}),
new HtmlWebpackPlugin({
template: './index.html',
chunks: ['polyfill', 'app']
}),
new HtmlWebpackPlugin({
template: './function-file/function-file.html',
filename: 'function-file/function-file.html',
chunks: ['function-file']
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map'
});
Contents of an Add-in
The files that are produced from your project when building should be at least some JavaScript, then perhaps HTML and some CSS, depending on what kind of add-in you're building. The most common is probably building an add-in with a task pane - which is basically a web page. In any case, the built files is not a Node.js web server.
Hosting your Add-in
Making your add-in available inside Outlook or Office requires that you host your files somewhere. It can be done with any web server - a simple python web server, Apache, Node.js HTTP server, or anything similar. It can be done on either localhost or in some other hosting service. The add-in tutorial shows you how to run a Webpack development server to host the files on https://localhost:3000 while you are coding (npm run start).
In your manifest.xml file you'll notice that you specify the address where your files are hosted. In my development setup, for an add-in with a task pane, I've specified that the files are hosted on localhost, like this:
<FormSettings>
<Form xsi:type="ItemRead">
<DesktopSettings>
<SourceLocation DefaultValue="https://localhost:3000/index.html"/>
<RequestedHeight>250</RequestedHeight>
</DesktopSettings>
</Form>
</FormSettings>
Production
However, when running your app in production, the tutorial says that you should do npm run build. Those files that are produced, need to be hosted somewhere. I've hosted my add-in on Amazon S3, which is another way of hosting files.
To simulate it on localhost, follow these steps.
In the same folder as your project (where the dist/ folder is located):
Run npm install http-server -g
Run http-server dist/
Tools
To clarify what the tools are used for:
Webpack is what puts your app together, from your source code to a bundled version which can be run in a browser context. Webpack development server can be used to host files on localhost during development
Node.js HTTP server can also be used to host files on your localhost
pm2 is a process manager for Node.js. You can use it for hosting a Node.js server in production
#shahroon and I working on the issue together. We're still not able to get things to work and have now paid for a support with Microsoft. Sadly and very frustratingly Microsoft hasn't even acknowledge our support ticket and it's been 3 days.

Is it possible to run Grunt Karma locally?

Is it possible to run Grunt Karma locally?
Start the Karma server, assign a port to it and then open different browsers on my computer and run tests by inserting the localhost:port?
I have a Github project running Travis and have strange results in some Browsers. I can run the tests locally but only with "virtual" PhantomJS. Would be nice to check my Specs in a real browser.
I regularly use karma-chrome-launcher and know that there is also karma-firefox-launcher as well.
In your karma.conf.js file, or in your Gruntfile.js options area you can define:
browsers: ['Phantomjs', 'Chrome'],
and then in the plugins section include:
plugins: [
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-phantomjs-launcher'
]
https://github.com/karma-runner has a list of launcher plugins and other useful plugins. There is even a karma-browserstack-launcher, though that wouldn't be local.
Documentation on what you can configure either total in the Gruntfile.js or by referencing a karma.conf.js in your Gruntfile.js can be found:
https://github.com/karma-runner/grunt-karma
http://karma-runner.github.io/0.10/config/configuration-file.html
I like the functionality of using a karma.conf.js file to separate out the majority of my karma config, so in my Gruntfile.js I do the following:
karma: {
options: {
configFile: 'karma.conf.js'
},
unit: {
autoWatch: true,
singleRun: true
},
watch: { // still needs watch integration and testing
browsers: ['PhantomJS'],
background: true
}
},
Then in my karma.conf.js file I follow the base structure shown https://github.com/karma-runner/karma/blob/master/test/client/karma.conf.js

Resources