Cypress headless - no loaders are configured to process png files - reactjs

I am trying to run cypress test cases headless using cmd command
npx cypress run
But it gives me below error -
Do I need to install any dependency for this to load.
Even css files are not getting loaded.
Note : I haven't installed webpack or any other dependency. Only cypress is installed additionally.

Yes, you will need to extend the webpack configuration used by cypress to handle the files you would like to load. You can find an example here
Below I've modified the example to work with cypress 10.
// cypress.config.ts
import { defineConfig } from 'cypress';
import findWebpack from 'find-webpack';
import webpackPreprocessor from '#cypress/webpack-preprocessor';
const webpackOptions = findWebpack.getWebpackOptions();
const options = {
webpackOptions,
watchOptions: {},
};
export default defineConfig({
e2e: {
setupNodeEvents(on) {
// implement node event listeners here
// on('file:preprocessor', webpack(options));
// use a module that carefully removes only plugins
// that we found to be breaking the bundling
// https://github.com/bahmutov/find-webpack
const cleanOptions = {
reactScripts: true,
};
findWebpack.cleanForCypress(cleanOptions, webpackOptions);
on('file:preprocessor', webpackPreprocessor(options));
},
specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}',
},
});

Related

how to run multiple spec files in cypress 10?

I am using cypress 10.0.0, I try to integrate multiple test (spec) file on cypress.config.ts, is possible on new cypress update ??
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
supportFolder: 'cypress/support',
fixturesFolder: 'cypress/fixtures',
screenshotsFolder: 'cypress/screenshots',
videosFolder: 'cypress/videos',
baseUrl: 'http://localhost:5200',
retries: {
runMode: 5,
openMode: 5,
}
},
});
Yes it is possible, create a new e2e spec that just imports all other specs.
cypress/e2e/all.cy.js
import './spec1.cy.js'
import './spec2.cy.js'
import './spec3.cy.js'
Then chose all.cy.js as the spec to open in the runner.
To run all spec files together you have to use the command:
npx cypress run

React with TypeScript using tsyringe for dependency injection

I am currently having trouble with my React TypeScript project.
I created my project with npx create-react-app my-app --template typescript.
I recently added tsyringe for dependency injection and was trying to implement it for an apiService. After following the readme(https://github.com/microsoft/tsyringe#injecting-primitive-values-named-injection) for adding primitive values I have hit a block. I already add experimentalDecorators and emitDecoratorMetadata to my tsconfig.json file with no success.
The error actual error I am encountering is:
./src/ts/utils/NetworkService.ts 9:14
Module parse failed: Unexpected character '#' (9:14)
File was processed with these loaders:
* ./node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|
| let NetworkService = (_dec = singleton(), _dec(_class = (_temp = class NetworkService {
> constructor(#inject('SpecialString')
| value) {
| this.str = void 0;
I am fairly sure this problem is caused by Babel, however I created this with npm create react-app --template typescript and do not seem to have access to the Babel configuration.
NetworkService.ts
#singleton()
export default class NetworkService
{
private str: string;
constructor(#inject('SpecialString') value: string) {
this.str = value;
}
}
Invocation method
bob()
{
const inst = container.resolve(NetworkService);
}
Registering Class in index.ts
container.register('SpecialString', {useValue: 'https://myme.test'});
#registry([
{ token: NetworkService, useClass: NetworkService },
])
class RegisterService{}
React-Scripts manages many of the configs related to the project. For many cases, this is fine and actually a nice feature. However, because React-Scripts uses Babel for it's development environment and does not expose the config.
You have to run npm run eject to expose the configurations.
Please note, this is a one-way operation and can not be undone.
Personally, I prefer more control with my configuration.
After this you can edit the webpack.config.js in the newly created config folder.
Find the section related to the babel-loader in the dev-environment and add 'babel-plugin-transform-typescript-metadata' to the plugins array.
Expanding on Jordan Schnur's reply, here are some more pitfalls I encountered when adding TSyringe to my CRA app:
Use import type with #inject
If you get this error "TS1272: A type referenced in a decorated signature must be imported with 'import type' or a namespace import when 'isolatedModules' and 'emitDecoratorMetadata' are enabled." replace import with import type for the offending imports. You will encounter this when working with #inject
E.g. replace import { IConfig } from "iconfig" with import type { IConfig } from "iconfig"
Fixing Jest
Your Jest tests will also break with TSyringe, especially when using #inject. I got the error "Jest encountered an unexpected token" with details constructor(#((0, _tsyringe.inject)("")) ("#" marked as the offending token). I took the following steps to fix that in CRA:
Add the line import "reflect-metadata"; to the top of the file src/setupTests.ts
In config/jest/babelTransform.js replace line 18 and following:
From
module.exports = babelJest.createTransformer({
presets: [
[
require.resolve('babel-preset-react-app'),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
babelrc: false,
configFile: false,
});
to:
module.exports = babelJest.createTransformer({
presets: [
[
require.resolve('babel-preset-react-app'),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
plugins: [
require.resolve('babel-plugin-transform-typescript-metadata')
],
babelrc: false,
configFile: false,
});
Instead of eject, you may use a lib that "overrides" some of your params.
I used craco : https://www.npmjs.com/package/#craco/craco
I've created an simpler DI library that doesn't need decorators or polyfill. Works with CRA like a charm and has cool React bindings
iti
import { useContainer } from "./_containers/main-app"
function Profile() {
const [auth, authErr] = useContainer().auth
if (authErr) return <div>failed to load</div>
if (!auth) return <div>loading...</div>
return <div>hello {auth.profile.name}!</div>
}

Module not found: Error: Can't resolve 'zlib'

I am trying to migrate a CRA react application to NX, following steps on the official site
When I hit nx serve
I am facing the following error:
ERROR in C:/dev/nx-dev/scandy/node_modules/#react-pdf/png-js/dist/png-js.browser.es.js
Module not found: Error: Can't resolve 'zlib' in 'C:\dev\nx-dev\scandy\node_modules#react-pdf\png-js\dist'
ERROR in C:/dev/nx-dev/scandy/node_modules/#react-pdf/pdfkit/dist/pdfkit.browser.es.js
Module not found: Error: Can't resolve 'zlib' in 'C:\dev\nx-dev\scandy\node_modules#react-pdf\pdfkit\dist'
Knowing that: before I start migration my project worked fine.
npm version: 6.14.11
node version: 14.16.0
I've tried to hit npm install zlib yet I get
Cannot find module './zlib_bindings'
For some reason, VSCode inserted import e from 'express' at the top of my file in react
import { response } from 'express';
I delete the above import line and then the problem is resolved, all the errors are gone after the above change.
It's about Webpack 5 and its default config you use for React app. I followed an advice from here: https://github.com/nrwl/nx/issues/4817#issuecomment-824316899 and React NX docs for how to use custom webpack config.
Create a custom webpack config, say, in /apps/myapp/webpack.config.js and reference it in workspace.json instead of "webpackConfig": "#nrwl/react/plugins/webpack". It should be "webpackConfig": "apps/myapp/webpack.config.js".
Content for webpack.config.js:
const nrwlConfig = require("#nrwl/react/plugins/webpack.js");
module.exports = (config, context) => {
// first call it so that #nrwl/react plugin adds its configs
nrwlConfig(config);
return {
...config,
node: undefined
};
};
So, this config change makes webpack correctly understand what polyfills are needed.
Alternatively, you can do the following:
const nrwlConfig = require("#nrwl/react/plugins/webpack.js");
module.exports = (config, context) => {
// first call it so that #nrwl/react plugin adds its configs
nrwlConfig(config);
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
stream: require.resolve('stream-browserify'),
zlib: require.resolve('browserify-zlib'),
}
}
};
};
For me it was the code:
import { response } from 'express'
This was entered automatically by VSCode at the beginning of the file.
Deleting it solved the problem.
In my case was because I tried to type 'Text' and suddenly, the autocomplete added me this line on top:
import { text } from 'express';
Just deleted it and it worked fine.
Go Search Icon in VSCode search "express" you may get things like
import { text } from 'express'
import { Router } from 'express'
import { X,Y,Z } from 'express'
delete this line your app will work fine

How to import other applications exported files in .test.js files in single-spa environment

Hi I actually need to import exported files from one application(commons) to other application(login) in some jest files, but it is not getting detected by jest.
Jest Test file:
import { auth as ServiceAuth } from "#dfs/standard"
import { ContextAlert } from '#dfs/standard';
describe("login page", () => {
it("test case 1", () => {
const ContextAlert = useContext(ContextAlert );
expect(ContextAlert).toBeTruthy()
})
})
Error Message:
FAIL src/Components/LoginPage.test.js
● Test suite failed to run
Cannot find module '#dfs/standard' from 'LoginPage.test.js'
> 1 | import { auth as ServiceAuth } from "#dfs/standard"
| ^
2 | import { ContextAlert } from '#dfs/standard';
3 |
4 | describe("login page", () => {
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:299:11)
at Object.<anonymous> (src/Components/LoginPage.test.js:1:1)
jest.config.js
module.exports = {
transform: {
"^.+\\.(j|t)sx?$": "babel-jest"
},
moduleNameMapper: {
"\\.(css)$": "identity-obj-proxy",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "identity-
obj-proxy",
}
};
But the file is getting imported in the component files with the same syntax.
How can I import the file in the jest test file ?
Jest is a very different environment than the browser, and resolving modules is also different. The code being loaded in Jest is not bundled and has not been processed through Webpack so externals are not resolved at run-time.
To enable unit tests with cross microfrontend imports, these are your options:
Publish mocks for that shared dependency (so that the mock and the actual implementation are nearest to each other)
Mock the shared dependency with Jest’s moduleNameMapper configuration
Mock the shared dependency locally in a __mocks__ file
Publish the shared dependency to a registry (npm or some other internal registry such as artifactory) and install it as a devDependency locally so that Jest can resolve it locally (though this will likely require a separate build to execute in jest/node environment)
The option you choose depends on your organization's needs.
See also: https://github.com/single-spa/single-spa.js.org/issues/389

Storybook - no stories showing up in typescript project with custom webpack / babel

I am trying to set up Storybook in a project. My project is runing on react#^16, and I'm using typescript, with a custom babel and webpack setup for development and build. To set up storybook, I did
npx sb init
This installs everything needed. It puts a .storybook folder in the root folder, and a stories folder in my src folder with some prefab components and stories in tsx format (which is what I want):
The .storybook/main.js file seems fine:
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
]
}
And the average .stories.js file automatically installed by npx sb init also seems fine:
import React from 'react';
// also exported from '#storybook/react' if you can deal with breaking changes in 6.1
import { Story, Meta } from '#storybook/react/types-6-0';
import { Header, HeaderProps } from './Header';
export default {
title: 'Example/Header',
component: Header,
} as Meta;
const Template: Story<HeaderProps> = (args) => <Header {...args} />;
export const LoggedIn = Template.bind({});
LoggedIn.args = {
user: {},
};
export const LoggedOut = Template.bind({});
LoggedOut.args = {};
But when I run npm run storybook, the storybook landing page has no stories. Even though it had installed some default stories to start playing with. It says:
Oh no! Your Storybook is empty. Possible reasons why:
The glob specified in main.js isn't correct.
No stories are defined in your story files.
As requested, here is a link to the repo so you can dig a bit deeper into the structure, weback config, etc. Note I have not committed the npx sb init changes yet, so you won't see the files there, only my starting point just before running the sb init.
I haven't had any issues getting npx sb init to work with a standard create-react-app, but with my custom webpack build and typescript, its just empty. What's going wrong?
Edit: Additional detail
I realize that just running npx sb init, then npm run storybook throws this error:
ERROR in ./.storybook/preview.js-generated-config-entry.js
Module not found: Error: Can't resolve 'core-js/modules/es.array.filter'
Based on this thread, installing core-js#3 solves the problem and storybook runs, though with no stories.
It seems like the babel plugin transform-es2015-modules-amd doesn't fit right with storybook since sb still uses your babel configuration.
You might need to remove it then it would work:
{
"plugins": [
// "transform-es2015-modules-amd", // Remove this plugin
]
}
If you want to have a special babel configuration for storybook, place it .storybook/.babelrc so the configuration would be simple like this:
.storybook/.babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react", "#babel/preset-typescript"]
}
NOTE: You might miss to forget install #babel/preset-typescript to help you transform your typescript code.
Maybe you have problems with the stories path, try to save only "../src/**/*.stories.js" in your config to see if its the reason
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
]
In case of dealing with arcgis-js-api in sb, you have to declare #arcgis/webpack-plugin in storybook's webpack configuration by adding to its config.
Here are a few steps you have to do:
Add webpackFinal property in .storybook/main.js with following content:
const ArcGISPlugin = require('#arcgis/webpack-plugin');
module.exports = {
// ...
webpackFinal: (config) => {
// Add your plugin
config.plugins.push(
new ArcGISPlugin(),
);
// Since this package has used some node's API so you might have to stop using it as client side
config.node = {
...config.node,
process: false,
fs: "empty"
};
return config;
}
};
One more thing to be aware of, some components are importing scss files, so you might need to support it by adding a scss addon '#storybook/preset-scss'
// Install
npm i -D #storybook/preset-scss css-loader sass-loader style-loader
// Add to your current addons
{
addons: ['#storybook/addon-links', '#storybook/addon-essentials', '#storybook/preset-scss'],
}
Like a tmhao2005 say. Storybook still uses your babel configuration. And this is the intended behavior. This thread at github also describes how the fix similar issue.
Updated your config .storybook/main.js.
If you use .babelrc:
babel: async options => ({ ...options, babelrc: false })
Or .babel.config.js:
babel: async options => ({ ...options, configFile: false })

Resources