After I migrated Cypress to version 10, Cucumber preprocessor stopped to work. I have found some solutions that I implemented and I also installed the latest #badeball/cypress-cucumber-preprocessor.
Now I am stuck how to set up the cypress.config.js file, as the original plugins folder is deprecated.
In old index.js under plugin folder I had:
const cucumber = require("cypress-cucumber-preprocessor").default;
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
on("file:preprocessor", cucumber());
...
Now the plugin setup should be in cypress-config.js:
e2e: {
baseUrl: 'http://localhost:4200',
specPattern: 'cypress/e2e/features',
setupNodeEvents(on, config) {
const addCucumberPreprocessorPlugin =
require('#badeball/cypress-cucumber-preprocessor').addCucumberPreprocessorPlugin;
on('file:preprocessor', addCucumberPreprocessorPlugin(on, config));
}
},
but now I have an error in on('file:preprocessor', addCucumberPreprocessorPlugin()); that addCucumberPreprocessorPlugin is not a function. I know it is not, but how to correctly configure this section for cucumber? I did not find any info about this.
If I just remove the on('file:preprocessor', addCucumberPreprocessorPlugin(on, config));, after I execute the feature test file, I have this error:
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file
The pattern I'm using is
import { defineConfig } from "cypress";
const preprocessor = require("#badeball/cypress-cucumber-preprocessor");
async function setupNodeEvents(on, config) {
await preprocessor.addCucumberPreprocessorPlugin(on, config);
// webpack config goes here if required
return config;
}
module.exports = defineConfig({
e2e: {
specPattern: "**/*.feature",
supportFile: false,
setupNodeEvents,
},
});
You may need some webpack config as well, the repository has some examples here
Here's another config that's working for me
const { defineConfig } = require("cypress");
const createBundler = require("#bahmutov/cypress-esbuild-preprocessor");
const preprocessor = require("#badeball/cypress-cucumber-preprocessor");
const createEsbuildPlugin = require("#badeball/cypress-cucumber-preprocessor/esbuild");
async function setupNodeEvents(on, config) {
await preprocessor.addCucumberPreprocessorPlugin(on, config);
on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin.default(config)],
})
);
// Make sure to return the config object as it might have been modified by the plugin.
return config;
}
module.exports = defineConfig({
e2e: {
specPattern: "**/*.feature",
supportFile: false,
setupNodeEvents,
},
});
You can try this:
Install two dependencies #bahmutov/cypress-esbuild-preprocessor and #esbuild-plugins/node-modules-polyfill using:
npm install -D #bahmutov/cypress-esbuild-preprocessor
npm install -D #esbuild-plugins/node-modules-polyfill
In your cypress/plugin/index.js, remove:
const cucumber = require('cypress-cucumber-preprocessor').default
module.exports = (on, config) => {
on('file:preprocessor', cucumber()) //For cypress cucumber preprocessor
}
and Add,
//For Cucumber Integration
const createEsbuildPlugin =
require('#badeball/cypress-cucumber-preprocessor/esbuild').createEsbuildPlugin
const createBundler = require('#bahmutov/cypress-esbuild-preprocessor')
const nodePolyfills =
require('#esbuild-plugins/node-modules-polyfill').NodeModulesPolyfillPlugin
const addCucumberPreprocessorPlugin =
require('#badeball/cypress-cucumber-preprocessor').addCucumberPreprocessorPlugin
module.exports = async (on, config) => {
await addCucumberPreprocessorPlugin(on, config) // to allow json to be produced
// To use esBuild for the bundler when preprocessing
on(
'file:preprocessor',
createBundler({
plugins: [nodePolyfills(), createEsbuildPlugin(config)],
})
)
return config
}
In your package.json, add:
"cypress-cucumber-preprocessor": {
"stepDefinitions": "cypress/e2e/path-to-step-definition/**/*.{js,ts}"
}
Next, in the step definition file replace import { Given, When, Then } from ‘cypress-cucumber-preprocessor/steps’
with
import { Given, When, Then, And } from “#badeball/cypress-cucumber-preprocessor”.
For your feature files to be recognised by the cypress test runner, update the specPattern in cypress.config.js file to [“**/*.feature”, “cypress/e2e/**/*.cy.{js,jsx,ts,tsx}”].
In case anyone else gets to this solution but is using webpack and typescript I had to make a few tweaks to our existing tsconfig.json:
"esModuleInterop": false,
"noEmit": false,
Aside from that the Cypress 10 conversion tool and the examples from the #badeball/cypress-cucumber-preproccesor docs for webpack/ts were all I needed.
Related
I am writing the cypress test for my website. I have included reportportal js client in my test and my test was running without any issues.
Now I have added gmail-tester for email verification. When I run it I am getting the error
cy.task('rp_Log') failed with the following error:
The task 'rp_Log' was not handled in the plugins file. The following tasks are registered: gmail:get-messages
my plugin/index.js file looks like this
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* #type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
const registerReportPortalPlugin = require('#reportportal/agent-js-cypress/lib/plugin');
const debug = require('debug');
const path = require('path');
const gmail_tester = require('gmail-tester');
module.exports = (on) => registerReportPortalPlugin(on);
module.exports = (on, config) => {
on("before:browser:launch", (browser = {}, launchOptions) => {
if (browser.name === "chrome"&& browser.isHeadless) {
launchOptions.args.push('--disable-gpu');
return launchOptions;
}
});
on("task", {
"gmail:get-messages": async args => {
const messages = await gmail_tester.get_messages(
path.resolve(__dirname, "credentials.json"),
path.resolve(__dirname, "token.json"),
args.options
);
return messages;
}
});
};
My test file looks like this
describe('Launch website',() => {
it('Home visit',() => {
cy.visit('http://localhost:3000')
cy.log("Visited the page")
cy.screenshot("Launch_name.png")
cy.rp_screenshot("Launch.png")
})
})
When I run the test I can see the my page is getting launched and it's printing the log also. But after that it's telling cy.task('rp_log') is not defined instead it can see the gmail get messages.
can anyone help me to get rid of this error?
I resolved an issue. We cant use two modules.export in index.js file. The answer should look like this
module.exports = (on, config) => {
registerReportPortalPlugin(on);
on("before:browser:launch", (browser = {}, launchOptions) => {
if (browser.name === "chrome"&& browser.isHeadless) {
launchOptions.args.push('--disable-gpu');
return launchOptions;
}
});
on("task", {
"gmail:get-messages": async args => {
const messages = await gmail_tester.get_messages(
path.resolve(__dirname, "credentials.json"),
path.resolve(__dirname, "token.json"),
args.options
);
return messages;
}
});
};
I need help in running my Vue spa in the same domain as my laravel app , when running "npm run serve" in terminal I think it's working but when I go to the browser it's refusing connection. I haven't done the backend which I will use sanctum for handling API. Has anybody here have the same project working on like me? love to make conversations to solve this.
Thanks in advance
here is the vue.config.js file
const path = require('path')
const webpack = require('webpack')
const createThemeColorReplacerPlugin = require('./config/plugin.config')
function resolve (dir) {
return path.join(__dirname, dir)
}
/**
* check production or preview(pro.loacg.com only)
* #returns {boolean}
*/
function isProd () {
return process.env.NODE_ENV === 'production'
}
const assetsCDN = {
css: [],
// https://unpkg.com/browse/vue#2.6.10/
js: [
'//cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.min.js',
'//cdn.jsdelivr.net/npm/vue-router#3.1.3/dist/vue-router.min.js',
'//cdn.jsdelivr.net/npm/vuex#3.1.1/dist/vuex.min.js',
'//cdn.jsdelivr.net/npm/axios#0.19.0/dist/axios.min.js'
]
}
// webpack build externals
const prodExternals = {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios'
}
// vue.config.js
const vueConfig = {
configureWebpack: {
// webpack plugins
plugins: [
// Ignore all locale files of moment.js
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
// if prod is on, add externals
externals: isProd() ? prodExternals : {}
},
chainWebpack: (config) => {
config.resolve.alias
.set('#$', resolve('src'))
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.oneOf('inline')
.resourceQuery(/inline/)
.use('vue-svg-icon-loader')
.loader('vue-svg-icon-loader')
.end()
.end()
.oneOf('external')
.use('file-loader')
.loader('file-loader')
.options({
name: 'assets/[name].[hash:8].[ext]'
})
// if prod is on
// assets require on cdn
if (isProd()) {
config.plugin('html').tap(args => {
args[0].cdn = assetsCDN
return args
})
}
},
css: {
loaderOptions: {
less: {
modifyVars: {
// less vars,customize ant design theme
'primary-color': '#00B4E4',
// 'link-color': '#F5222D',
'border-radius-base': '4px'
},
javascriptEnabled: true
}
}
},
}
if (process.env.VUE_APP_PREVIEW === 'true') {
vueConfig.configureWebpack.plugins.push(createThemeColorReplacerPlugin())
}
module.exports = vueConfig
module.exports = {
devServer: {
host: 'app.paymate-ui.test'
}
}
If I understand you correctly, you want to use Laravel and Vue.js together in the same application folder?
Should be pretty easy then.
First off, build your application with Vue scaffolding for the frontend.
Then, make a route that redirects everything to a single controller method that returns a spa view. (Or use a closure)
In this view, include your app.js as an asset and include the main Vue component (something like <app></app>).
Then build your Vue app. All requests will now be forwarded to the spa view, which includes your app.js, which should bootstrap Vue.
I deployed my 1st Nuxt.js app to Heroku...Everything went smooth but when I opened the app I realised that every .vue file/component has TailwindCSS styles up untill SM breakpoint. Mobile view is fine, but anything bigger than SM breakpoint is not apllied. I also used Purgecss to remove unused styles but not sure if that can cause the problems... Any ideas on how to fix this?
I fixed my problem just by finding this https://github.com/nuxt/nuxt.js/issues/2262
I created modules folder and added import-tailwind-config.js with the code:
module.exports = function () {
const tailwindConfig = require('#nuxtjs/tailwindcss')
this.options.env.tailwind = tailwindConfig
}
And inside nuxt.config.js, outside of module.exports I added
const PurgecssPlugin = require('purgecss-webpack-plugin')
const glob = require('glob-all')
const path = require('path')
class TailwindExtractor {
static extract (content) {
return content.match(/[A-z0-9-:/]+/g) || []
}
}
As well as this code inside of module.exports
build: {
extend (config, ctx) {
config.plugins.push(
new PurgecssPlugin({
whitelist: ['html', 'body'],
paths: glob.sync([
path.join(__dirname, 'components/**/*.vue'),
path.join(__dirname, 'layouts/**/*.vue'),
path.join(__dirname, 'pages/**/*.vue'),
path.join(__dirname, 'plugins/**/*.vue')
]),
extractors: [{
extractor: TailwindExtractor,
extensions: ['html', 'js', 'vue']
}]
})
)
}
}
modules: [
'~modules/import-tailwind-config'
]
I have an existing Node.js (Node only, no Typescript) application with the following files (generated by Visual Studio Node template):
In file app.js:
var express = require("express");
var app = express();
...
module.exports = app;
In file socket.js:
module.exports = function (server,app) {
// ....
}
In file www:
var app = require("../app");
var server = app.listen(app.get(8081), function() {
});
var sockets = require("../routes/sockets")(server, app);
I am no migrating it to Typescript. How do I convert the above export/require to the equivalent in Typescript?
Where can I find the proper specifications of the import and export keywords? I am unable to find documentation of what they mean and do exactly. I do see many examples of some permutations of their usage.
To ensure that your import statements will be transpiled into require(), you need to specify that you want to use commonjs modules during the TypeScript compilation. Here's an example of tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"outDir": "build",
"target": "es5"
}
}
Here's an example of the Node/Express server in TypeScript:
import * as express from "express";
const app = express();
app.get('/products', (req, res) => res.send('Got a request for products'));
const server = app.listen(8000, "localhost", () => {
const {address, port} = server.address();
console.log('Listening on %s %s', address, port);
});
I want to use Webpack in order to create one single scripts.js file out of all needed Javascript files.
Within my main.js I require three modules:
require('jquery');
require('readmore');
require('foundation');
My webpack.config.js is this:
var path = require('path');
module.exports = {
entry: ["./js/main.js"],
output: {
path: path.resolve(__dirname, 'build'),
filename: "scripts.js"
},
resolve: {
modulesDirectories: ["bower_components", "node_modules"],
alias: {
jquery: '../bower_components/jquery/dist/jquery.js',
readmore: '../node_modules/readmore-js/readmore.js',
foundation: '../bower_components/foundation-sites/dist/js/foundation.js'
}
}
}
My problem: as readmore-js is a jQuery-Plugin it requires jQuery by itself.
I got this error after running Webpack:
ERROR in ./~/readmore-js/readmore.js
Module not found: Error: Can't resolve 'jquery' in '/Users/myName/www/myProject/node_modules/readmore-js'
# ./~/readmore-js/readmore.js 17:4-31
# ./js/main.js
# multi main
From my understanding the problem is that readmore also wants to load the module jQuery within the directory "nodes_modules". My first approach was to resolve this problem by adding moduleDirectories to the config-file, but it does still not work.
And even in this case, the plugin shouldn't load jQuery again.
Do you have any idea how I can load jQuery globally and then "tell" all modules which require jQuery by themself "look, it's there!"
As it may helps, the following is copied out of the plugin's readmore.js:
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}
You can use webpack.ProvidePlugin for this:
Remove require jquery from main.js:
require('readmore');
require('foundation');
Configure webpack.ProvidePlugin inside webpack.config.js:
var path = require('path');
module.exports = {
entry: ["./js/main.js"],
output: {
path: path.resolve(__dirname, 'build'),
filename: "scripts.js"
},
resolve: {
modulesDirectories: ["bower_components", "node_modules"],
alias: {
readmore: '../node_modules/readmore-js/readmore.js',
foundation: '../bower_components/foundation-sites/dist/js/foundation.js'
}
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
]
}