I am struggling to add a second module.export cypress/plugin/index.js
My Current cypress/plugin/index.js file look 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 { on } = require('events');
const fs = require('fs-extra');
const path = require('path');
function getConfigurationByFile(file) {
const pathToConfigFile = path.resolve('config', `${file}.json`);
return fs.readJson(pathToConfigFile);
}
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
const file = config.env.configFile || 'qa';
return getConfigurationByFile(file);
};
I want to add the following to cypress/plugin/index.js:
require('cypress-grep/src/plugin')(config)
// make sure to return the config object
// as it might have been modified by the plugin
return config
I believe that you can pass in the config from your function to your require and then return that new config.
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
const file = config.env.configFile || 'qa';
let newConfig = getConfigurationByFile(file);
require('cypress-grep/src/plugin')(newConfig);
return newConfig;
};
Since your getConfigurationByFile() function returns a JSON Object like the original config, and the cypress-grep plugin takes in a JSON Object, you can probably just add the resolved JSON from getConfigurationByFile instead of the standard one provided by config.
If you have your plugins set up correctly, then it may be the environment variables passed via command line. Here is an example repo of using cypress-grep and configuration files.
Related
I have a NS 6.1 Core application. In webpack I want to add a variable which I want to access later in a typescript file. Here is my code:
// Define useful constants like TNS_WEBPACK
new webpack.DefinePlugin({
"global.TNS_WEBPACK": "true",
"process": "global.process",
"myGlobal.environment": JSON.stringify(env.mode|| 'not defined'),
}),
TS:
declare let myGlobal: any;
export function onLoaded(e) {
page = <Page>e.object;
console.log('myGlobal.environment: ' + myGlobal.environment);
}
The problem I am facing is that myGlobal is not defined when I run the code.
I tried deleting the platforms folder and rebuilding, but I get the same error.
Any ideas on what I might be doing wrong?
The thing is that the env constant is not having a mode property but a boolean called production. Here is what env looks like
const {
// The 'appPath' and 'appResourcesPath' values are fetched from
// the nsconfig.json configuration file.
appPath = "app",
appResourcesPath = "app/App_Resources",
// You can provide the following flags when running 'tns run android|ios'
snapshot, // --env.snapshot
production, // --env.production
uglify, // --env.uglify
report, // --env.report
sourceMap, // --env.sourceMap
hiddenSourceMap, // --env.hiddenSourceMap
hmr, // --env.hmr,
unitTesting, // --env.unitTesting,
verbose, // --env.verbose
snapshotInDocker, // --env.snapshotInDocker
skipSnapshotTools, // --env.skipSnapshotTools
compileSnapshot // --env.compileSnapshot
} = env;
As in JavaScript undefined equals false (for booleans), that means that if a release flag is not passed explicitly, the production will always be undefined (false). So you could do the following:
"myGlobal.environment": JSON.stringify(env.production || "development")
Or on second thought more like
"myGlobal.environment": JSON.stringify(env.production ? "production" : "development")
I'm trying to create multiple web-custom elements using Svelte and Rollup inside the one project.
The idea is to have a folder structure like this
web-components
component-1
index.svelte
component-2
index.svelte
This should the be "looped" by Rollup and create a set of JS files
publish
component-1.js
component-2.js
Each of the svelte components will be standalone/autonomous, and I might also create other components using other technologies as well. (React/Vanilla.js/lit.hmtl/stencil)
I'm working in Visual Studio, and the examples for doing these things is quite sparse.. Anyone that can direct me to a good example?
I do not have a current example for what you are trying to do, but having done something similar this seems to be an approach worth trying:
Your rollup.config.js file can, instead of a single object, return an array:
export default [
{ configuration for component 1 },
{ configuration for component 2 }
];
Since each configuration would have some duplication (plugins, format, ...) it's probably best to abstract those out:
const toRollupConfig = ({ src, dest }) = {
/// Rollup Configuration
};
export default [
toRollupConfig({
src: './web-components/component-1/index.svelte',
dest: './publish/component-1.js'
}),
toRollupConfig({
src: './web-components/component-2/index.svelte',
dest: './publish/component-2.js'
}),
];
Since this would require you make a line for each component, you could go a step further and fetch all your .svelte files using something like glob or similar and map the result with toRollupConfig given you the final code:
const GetComponents = (srcDir, destDir) => {
// Get the files and return for each an object of the form { src, dest }
};
const toRollupConfig = ({ src, dest }) = {
/// Rollup Configuration
};
export default GetComponents('./web-components/','./publish').map(toRollupConfig);
I'am using chakram + mocha.
How can I use shared variables for all test?
For example, I would like to use variable API_PATH="http://example.com/v1/" in tests. And this variable could be changed during running test. So, my test looks like this.
var response = chakram.get(API_PATH + "products");
expect(response).to.have.status(200);
As example, protractor has conf.js with parameter baseUrl. Running test looks like protractor conf.js --baseUrl http://example.com/
what have you tried so far? Have you tried using beforeEach to reinitialize the object that you are using? You could just make the the shared variables declared outside of your tests.
EDIT: Adding details from what Jerry said:
If you want all variable to be reused within the same test, you must make them global variables. See example below
///include dependencies
var assert = require('assert'),
chai = require('chai'),
expect = chai.expect,
chakram = require('chakram');
//INIT GLOBAL VARAIBLES FOR within the same test
var testObj,
dummyData = {
user: 'John Kim',
lastSeenOnline: 'Wed August 11 12:05 2017'
};
describe ('#User', function () {
beforeEach(function () {
//init what the object contains
testObj = new DataStore(data, ContainerStore);
});
it ('#Should return the name of the user', function () {
assert.equal(testObj.get('user'), dummyData.user);
});
it("should offer simple HTTP request capabilities", function () {
return chakram.get("http://httpbin.org/get");
});
});
Note: I work with react but this is an example. We assume that the ContainerStore contains a method that has a method for get() which just gets the value of our JSON object. You can use testObj many time in different describe blocks since it is declared outside of your tests. But you should remember to always reinitialize your tesObj in a beforeEach(); otherwise, you risk populating your individual tests. There are cases were you do not have to initialize the beforeEach() and it is optional.
For Example in config.js
module.exports = {
"baseUrl": "http://example.com/",
"googleUrl": "http://www.google.com.tr/"
};
And use in javascript code:
let config = require('/config');
describle("test describle", () => {
it("test", () => {
chakram.get(config.baseUrl + "products"); //for example use
})
})
I have many commands and each of them is long.
For example, I have:
create
read
update
delete
I want to put them in separate files:
./commands/create.js
./commands/read.js
./commands/update.js
./commands/delete.js
and I want to require them in app.js:
require('./commands/create.js');
// ...
so I can:
node app.js create HelloWorld
How can I achieve this?
I would do something like this:
// create.js
function create(args, cb) {
// ... your logic
}
module.exports = function (vorpal) {
vorpal
.command('create')
.action(create);
}
Then in your main file, you can do:
// main.js
const vorpal = Vorpal();
vorpal
.use(require('./create.js'))
.use(require('./read.js'))
.show();
More on this here.
While writing tests I got bug TypeError: $.extend is not a function on toastr plugin that we are using. It seems that jQuery is not picked up properly, even tho is working normally in browser.
In our main mock file we imported jQuery and bind it to global windows object and it's accessible across whole application (but toastr plugin), even while testing in mocha:
import jsdom from 'jsdom';
import $ from 'jquery';
import chai from 'chai';
import chaiImmutable from 'chai-immutable';
import React from 'react';
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
const win = doc.defaultView;
global.document = doc;
global.window = win;
global.expect = chai.expect;
global.$ = $(win);
global.jquery = $(win);
global.jQuery = $(win);
Object.keys(window).forEach((key) => {
if (!(key in global)) {
global[key] = window[key];
}
});
chai.use(chaiImmutable);
So while taking closer look at toastr I noticed this:
; (function (define) {
define(['jquery'], function ($) {
// this function is called on inizialization
function getOptions() {
return $.extend({}, getDefaults(), toastr.options);
}
It takes jquery from node_modules directly and then defines object $ in function scope, that means that it's ignoring window.$ (which is working normally even in here).
Therefore logging $ will return function, and logging $.anyMethodFromjQuery ($.extend) will return undefined.
In the end I tried logging $.prototype, in the browser it will return me jQuery object while in mocha it returns empty object {}
So in the end it define didn't created prototype in mocha environment and I cannot add one line of code $ = window.$; in plugin, since no one should edit a plugin + we are using npm.
Is there any solution for this?
You're running into trouble because you are loading code that should be loaded by JSDom outside of it. While it is possible in some cases to load code in Node and then pass it to the window that JSDom creates, that's a brittle approach, as you've discovered. Whenever I use JSDom for things other than write-and-toss cases, I load every script that would normally be loaded by a browser through JSDom. This avoids running into the issue you ran into. Here's a proof-of-concept based on the code you've shown in the question. You'll see that toastr.getContainer() runs fine, because Toastr has been loaded by JSDom. If you try to use the same code with an import toastr from "toastr" you'll get the same problem you ran into.
import jsdom from 'jsdom';
import $ from 'jquery';
import path from "path";
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>', {
features: {
FetchExternalResources: ["script"],
ProcessExternalResources: ["script"]
}
});
const win = doc.defaultView;
global.document = doc;
global.window = win;
global.$ = $(win);
global.jquery = $(win);
global.jQuery = $(win);
window.addEventListener("error", function () {
console.log("ERROR");
});
const script = document.createElement("script");
script.src = path.join(__dirname, "./node_modules/toastr/toastr.js");
document.head.appendChild(script);
// The load will necessarily be asynchronous, so we have to wait for it.
script.addEventListener("load", function () {
console.log("LOADED");
console.log(window.toastr);
// We do this here so that `toastr` is also picked up.
Object.keys(window).forEach((key) => {
if (!(key in global)) {
global[key] = window[key];
}
});
toastr.getContainer();
});
Note that the code hung when I tried calling toastr.info(...). I took a look at the code of Toastr but it is not clear to me what causes the problem. There are features of browsers that JSDom is unable to emulate. It is possible that Toastr is dependent on such features. In the past, I've sometimes had to switch test suites away from JSDom due to its limitations.