NX component testing with cypress error process is not defined - cypress

I am using NX 14.5.1 and cypress 10.2.0. When I run cypress component testing for "libs/ui" always got "Process not defined" error. In the component call ".env" like this:
import consola from 'consola'
export const logger = consola.create({
level: process.env.NX_ENV_NAME === 'production' ? 0 : 5
})
This is my "cypress.config.ts":
import { defineConfig } from 'cypress';
import { nxComponentTestingPreset } from '#nrwl/react/plugins/component-testing';
export default defineConfig({
component: {
...nxComponentTestingPreset(__dirname)
}
})
And the error is like this:
process is not defined
ReferenceError
The following error originated from your test code, not from Cypress.
> process is not defined
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
Cypress could not associate this error to any specific test.
We dynamically generated a new test to display this failure.
I think Cypress doesn't recognize my ".env". How do I pass my ".env" when I run component testing?

I think the basic problem is the app is server-side-rendered. The server compiles in Node where process is available, but the component test runs in the browser where process isn't valid.
This is the way you might tackle it:
In cypress.config.js load the process.env you need into Cypress.env
import { defineConfig } from 'cypress';
import { nxComponentTestingPreset } from '#nrwl/react/plugins/component-testing';
const setupNodeEvents = (on, config) => {
config.env = {
...config.env,
...process.env.NX_ENV_NAME,
}
return config
}
export default defineConfig({
component: {
...nxComponentTestingPreset(__dirname),
setupNodeEvents
}
})
In the component, check where the component is being run from.
import consola from 'consola'
const envName = window && window.Cypress
? window.Cypress.env('NX_ENV_NAME') // running in browser, take Cypress.env
: process.env.NX_ENV_NAME; // running SSR, take process.env
const level = envName === 'production' ? 0 : 5;
export const logger = consola.create({
level
})
This is messy but removes the restriction on running SSR code in a browser environment.

Related

How can I see `cy.log` output when using Cypress headlessly?

When running Cypress headlessly, I can see console.log output from the frontend code under test by using the DEBUG environment variable, like:
DEBUG='cypress:launcher' npx cypress run --browser chrome
However, I haven't found any similar way to see the output of cy.log from the Cypress test code when running headlessly. Even with DEBUG='cypress:*' I don't see them - they only seem to be visible in the interactive interface. It feels like there must be some way to see the cy.log output headlessly - can someone help with that?
The first step is to add a new task in your Cypress config file so that you can run console.log from Node:
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
on("task", {
log(args) {
console.log(...args);
return null;
}
});
},
},
});
Then, you can override cy.log so that it calls this task whenever you run the command in headless mode, and console.log when you're running in headed mode. You can do this by adding the following to your commands file:
Cypress.Commands.overwrite("log", function(log, ...args) {
if (Cypress.browser.isHeadless) {
return cy.task("log", args, { log: false }).then(() => {
return log(...args);
});
} else {
console.log(...args);
return log(...args);
}
});

Error: Step implementation missing for: [step_definition] when trying to run a scenario using cucumber with cypress 10

I have updated my project to cypress 10. But getting this error couldn't solve the problem described in the title.
my feature file:
spec file:
Error:
File order:
Config file:
package.json file:
It's probably a mistake to use both cypress-cucumber-preprocessor and #badeball/cypress-cucumber-preprocessor in the same project.
Uninstall cypress-cucumber-preprocessor, it is a defunct version.
Then follow badeball Example setup to make corrections to the configuration, for example
import { defineConfig } from "cypress";
import createBundler from "#bahmutov/cypress-esbuild-preprocessor";
import { addCucumberPreprocessorPlugin } from "#badeball/cypress-cucumber-preprocessor";
import createEsbuildPlugin from "#badeball/cypress-cucumber-preprocessor/esbuild";
export default defineConfig({
e2e: {
specPattern: "**/*.feature",
async setupNodeEvents(
on: Cypress.PluginEvents,
config: Cypress.PluginConfigOptions
): Promise<Cypress.PluginConfigOptions> {
// This is required for the preprocessor to be able to generate JSON reports after each run, and more,
await addCucumberPreprocessorPlugin(on, config);
on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin(config)],
})
);
// Make sure to return the config object as it might have been modified by the plugin.
return config;
},
},
});

Cypress: How to add functions to Mocha Context?

I am trying add functions to this (which is a Mocha Context) in tests, so I can do e.g.
describe('my spec', () => {
it('should work', function () {
this.sayHelloWorld();
})
})
In an empty folder I call
yarn add cypress
yarn cypress open
so that default config files are created. It also creates a sample test in cypress/e2e/spec.cy.js.
I can run the sample test without problem. But if I add
import { Context } from "mocha";
to cypress/support/e2e.js I get
Error: Webpack Compilation Error
./cypress/support/e2e.js
Module not found: Error: Can't resolve 'mocha' in '...\support'
resolve 'mocha' in '...\support'
Parsed request is a module
So I installed Mocha, the same version which is in devDependencies of Cypress (see package.json):
yarn add mocha#3.5.3
My package.json now looks like this:
{
"dependencies": {
"cypress": "^10.4.0",
"mocha": "3.5.3"
}
}
Now that import line passes. But this fails:
import { Context } from "mocha";
Context.prototype.sayHelloWorld = () => console.log("hello world");
Error:
> Cannot read properties of undefined (reading 'prototype')
Why is that? In comparison adding something to String.prototype works.
Also in comparison: Again in an empty folder:
yarn add mocha#3.5.3
And in test/test.js:
const { Context } = require("mocha");
it("should work", function () {
Context.prototype.sayHelloWorld = () => console.log("hello world");
this.sayHelloWorld();
});
Now yarn mocha works (says hello world).
What is going on in Cypress? Possibly a bug?
Solution:
no import { Context } from "mocha";
add functions like that:
Mocha.Context.prototype.sayHelloWorld = function () {
cy.log('hello world');
};

Cypress 10 - How can I run test files in order

Previously it should be set up in cypress.json.
Like
testFiles: [
"e2e/register.cy.ts",
"e2e/buyGiftCertificate.cy.ts",
"e2e/buyMembershipCertificate.cy.ts"
]
But after migrating to Cypress 10 the place for it is cypress.config.ts
There should be a pattern but how to order tests it's not clear
If you are using npx cypress run, you can do exactly the same thing, except use specPattern instead of testFiles.
The following will run the test (only these tests) in the order spec2.cy.js, spec3.cy.js, spec1.cy.js
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
specPattern: [
"cypress/e2e/spec2.cy.js",
"cypress/e2e/spec3.cy.js",
"cypress/e2e/spec1.cy.js",
]
},
});
Create a file inside your e2e folder as tests-in-order.cy.ts and inside that file import the tests in order you want them to execute:
//Run tests in the intended order
import './register.cy.ts'
import './buyGiftCertificate.cy.ts'
import './buyMembershipCertificate.cy.ts'
And then execute the file using the command (from cli):
npx cypress run --spec=cypress/e2e/tests-in-order.cy.ts
For Test Runner, just click on the file to execute.

Unresolved dependencies & Missing global variable name when trying to import #mapbox/mapbox-gl-geocoder

I'm beginning with Svelte and I would like to (more or less) reproduce Mapbox store locator tutorial with Svelte & rollup. (Starting from svelte REPL starter kit).
Everything's fine for loading a map and some markers, but as soon as I try to import this package https://github.com/mapbox/mapbox-gl-geocoder, nothing works anymore and I'm not familiar enough with Svelte to figure out how to setup rollup and fix it.
<script>
import { onMount, setContext } from 'svelte'
import mapbox from 'mapbox-gl/dist/mapbox-gl.js';
import MapboxGeocoder from '#mapbox/mapbox-gl-geocoder'; // <<--- Problem here
mapbox.accessToken = 'xxx';
let map;
let geocoder;
onMount(() => {
map = new mapbox.Map({,,,});
geocoder = new MapboxGeocoder({,,,});
});
</script>
terminal :
bundles src/main.js → public/build/bundle.js...
(!) Missing shims for Node.js built-ins
Creating a browser bundle that depends on 'events'. You might need to include https://github.com/ionic-team/rollup-plugin-node-polyfills
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
events (imported by node_modules/#mapbox/mapbox-gl-geocoder/lib/index.js, events?commonjs-external)
(!) Missing global variable name
Use output.globals to specify browser global variable names corresponding to external modules
events (guessing 'events$1')
created public/build/bundle.js in 2s
browser console :
Uncaught ReferenceError: events$1 is not defined
at main.js:5
Then, I tried to add to my rollup config resolve and polyfills plugins, but have other errors.
rollup.config.js
import svelte from 'rollup-plugin-svelte';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import preprocess from 'svelte-preprocess';
import nodeResolve from '#rollup/plugin-node-resolve';
import nodePolyfills from 'rollup-plugin-node-polyfills';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
nodeResolve(),
nodePolyfills(),
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
},
preprocess: preprocess()
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
Gives me this
bundles src/main.js → public/build/bundle.js...
LiveReload enabled
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en/#error-this-is-undefined
node_modules/base-64/base64.js
163: }
164:
165: }(this));
^
to conclude: I'm a bit lost :D
thanks in advance

Resources