How to setup Unit test with mocha and mongodb-memory-server? - javascript

I am trying to make test case suite with mocha and mongodb-memory-server(as an in memory db). I am trying to implement this in the way below.
Project structure:
test runner: (in package.json)
"scripts": {
"test": "mocha 'app/**/*.spec.js' --recursive --exit"
},
So, First I need to initialise the in memory MongoDB, thats why I am using global.spec.js which looks like this,
const { MongoMemoryServer } = require("mongodb-memory-server");
const mongoose = require("mongoose");
mongoose.set("usePushEach", true);
let mongoServer;
before(async function () {
// mongod donwload on first time
this.timeout(30 * 1000);
mongoServer = new MongoMemoryServer();
const mongoUri = await mongoServer.getUri();
await mongoose.connect(mongoUri, {});
process.env.AGENDA_DB_URI = mongoUri;
});
after(function () {
mongoose.disconnect();
mongoServer.stop();
});
and a test-setup.js file which looks like this,
const { MongoMemoryServer } = require("mongodb-memory-server");
(async function() {
// trigger downloading mongodb executable on first time
const mongoServer = new MongoMemoryServer();
await mongoServer.getUri();
mongoServer.stop();
})()
.then(() => {
process.exit(0);
})
.catch(err => {
console.error(err);
process.exit(1);
});
all *.spec.js files will be inside modules folder. In simple word each folder inside module will have one .spec.js file. If I try to run this using the npm run test command it is throwing me some error, that looks like this,
1) "before all" hook
0 passing (448ms)
1 failing
1) "before all" hook:
Uncaught Error: TypeError: logWarnFn is not a function
I believe this logWarnFn error is coming from i18n. But when i start the server it is working fine.
versions:
"mongodb-memory-server": "^6.6.2",
"mocha": "^6.0.2",
"i18n": "0.8.3",

Related

How to connect any server using ssh in Cypress.io to run a command?

I know that this probably is not the best way to do this. I read the question with the same title here, but it not solve my problem.
The question is: I have a server that only will achieve a result that I wanna if I run a command line in the server. So I wanna write a test to check the state of one page before and after I run that command. How I do that?
I tried to use the simple-ssh package, but I keep getting this error while trying to read the ssh key file:
fs.readFileSync is not a function
Actually my code looks like this:
import * as fs from 'fs';
let sshConfig = Cypress.config('ssh')
sshConfig.key = fs.readFileSync('path/to/key/file')
let SSH = require('simple-ssh');
Cypress.Commands.add('teste', () => {
let ssh = new SSH(sshConfig)
ssh.exec('echo', {
args: ['$PATH'],
out: function(stdout) {
console.log(stdout);
}
}).start();
})
Other possibility's are welcome.
As Fody mentioned, there are node.js functions present inside simple-ssh so a task is needed.
This is the basic configuration.
It's a direct translation of what you have, but you would want to return something from the task. As it is, the console.log() goes to the terminal console not the browser console.
cypress.config.js
const { defineConfig } = require('cypress')
const fs = require('fs')
const SSH = require('simple-ssh');
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
ssh() {
const sshConfig = config.ssh
sshConfig.key = fs.readFileSync('path/to/key/file')
const ssh = new SSH(sshConfig)
ssh.exec('echo', {
args: ['$PATH'],
out: function(stdout) {
console.log(stdout);
}
}).start();
return null
},
})
}
}
})
test
Cypress.Commands.add('ssh', () => {
cy.task('ssh')
})
cy.ssh()
Try it with cy.readFile().
const SSH = require('simple-ssh');
Cypress.Commands.add('testSSH', () => {
cy.readFile('path/to/key/file').then(key
const sshConfig = Cypress.config('ssh')
sshConfig.key = key
const ssh = new SSH(sshConfig)
ssh.exec('echo', {
args: ['$PATH'],
out: function(stdout) {
console.log(stdout);
}
}).start()
})
})
The problem is fs is a node.js library, and it cannot be used in the browser.
But you may find the same thing applies to simple-ssh, If so, you will have to shift the code into a task where you can use any node.js functions.

Error: Cannot find module '#playwright/test'

I am currently trying to use expect to do assertions by using const { expect } = require('#playwright/test'); but every time I get Error: Cannot find module '#playwright/test'. It is a very short script but something is wrong with that.
const { chromium } = require("playwright");
const { expect } = require('#playwright/test');
const { matchers } = require('playwright-expect');
console.log("##########", expect)
// add custom matchers
expect.extend(matchers);
(async () => {
const browser = await chromium.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto("someurl");
await page.fill("input[name='userLoginId']", 'nnn');
await page.fill("input[name='password']", 'nnn');
await page.click("button[type=submit]");
})();
package.json
{
"name": "playwright",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "node ./index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"playwright": "^1.15.1",
"playwright-expect": "^0.1.2"
}
}
The test works fine without this:
const { expect } = require('#playwright/test');
const { matchers } = require('playwright-expect');
console.log("##########", expect)
// add custom matchers
expect.extend(matchers);
And it does what I ask it to do, but now that I want to do assertions and I add that, now it does not work.
You have to install #playwright/test library:
npm i -D #playwright/test
Do not use playwright-expect library. Playwright already includes web-first assertions. Hence, there is no reason to use an additional library to extend expect.
Remove unused code:
const { matchers } = require('playwright-expect');
console.log("##########", expect)
// add custom matchers
expect.extend(matchers);
I've created an issue about the same question here https://github.com/microsoft/playwright/issues/14971 and I'll update the result when it's answered.
While trying to use playwright as a library i did run into the same error
Error: Cannot find module '#playwright/test'
To fix this error in my case the following needed to be done. The pre-condition is that playwright is already installed.
Create a node js project
Create a folder: mkdir HelloLibrary
Inside this folder create a file from the command prompt: echo var msg = 'Hello World'; console.log(msg); > app.js
Open a command prompt and run node app.js
Add playwright npm i -D playwright
Change content of app.js like code sample below
Run it again node app.js
Voila done
App.js sample
This code launches a browser and takes a screenshot
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: false, slowMo: 50 });
const page = await browser.newPage();
await page.goto('http://whatsmyuseragent.org/');
await page.screenshot({ path: `example.png` });
await browser.close();
})();
See also
Tutorial: Node.js for Beginners
Use playwright as a library

require('fs-extra') not loading: throwing error "Cant find module fs-extra"

Trying to use some installed npm packages like fs-extra into below js files given by Truffle.But it says "can't find module "fs-extra".
1) Tried importing local js files using require() method but that fails too.
2) Tried running separate js files using node and it works just fine.
3) Issue comes when I try to use require("fs-extra") inside a function declared in APP object.
App = {
web3Provider: null,
contracts: {},
init: async function () {
return await App.initWeb3();
},
initWeb3: async function () {
// Modern dapp browsers...
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.enable();
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider('http://0.0.0.0:9283');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function () {
$.getJSON('UserCreation.json', function (data) { //<VK>Satish to add his contract file here
// Get the necessary contract artifact file and instantiate it with truffle-contract
var CMArtifact = data;
App.contracts.UserCreation = TruffleContract(CMArtifact);
App.contracts.UserCreation.setProvider(App.web3Provider);
});
return App.bindEvents();
},
createUser: function (event) {
event.preventDefault();
var username = $("#sign-up-username").val();
var title = $("#sign-up-title").val();
var intro = $("#sign-up-intro").val();
const utility=require('fs-extra'); // Failing to find module
}
}
$(function () {
console.log("initiaing farmer")
$(window).load(function () {
App.init();
});
});
Expected: Should be able to call methods from fs-extra package
Actual : can't find module "fs-extra"
npm ls fs-extra to check if you've installed it correctly. Then try npm install fs-extra.
require('fs-extra') will only work in server side javascript (nodejs) .
If your code runs on a browser require will not work

Sequelize migrations - run automatically when node application starts

I am trying to get my Sequelize migration scripts to run automatically when my node application starts. I have manually tested the migration scripts to make sure they are running correctly, by running db:migrate command.
Now, I have added this file to run the migration scripts:
index.js
const {exec} = require('child_process');
const Sequelize = require('sequelize');
const config = require("config");
const sequelize = new Sequelize(config.get('postgres'));
async function start() {
await new Promise((resolve, reject) => {
const migrate = exec(
'npm run db:migrate',
{env: 'development'},
(err, stdout, stderr) => {
if (err) {
reject(err);
} else {
resolve();
}
}
);
// Forward stdout+stderr to this process
migrate.stdout.pipe(process.stdout);
migrate.stderr.pipe(process.stderr);
});
}
module.exports = {
start: start
};
And in server.js:
async function start(appStarted) {
logger.info('Initializing ...');
// execute pending migrations
logger.info('Migrating DB...');
await require('../migrations').start();
logger.info('DB Migration complete.');
When I start the app, it displays Migrating DB... and gets stuck there.
How can I resolve this?
You can listen for the console message and kill the child process, like this:
// Listen for the console.log message and kill the process to proceed to the next step in the npm script
migrate.stdout.on('data', (data) => {
console.log(data);
if (data.indexOf('No migrations were executed, database schema was already up to date.') !== -1) {
migrate.kill();
}
});
This will make sure that the child process is killed when you've already run your migrations.

Testcafe - Test command line argument outside test case

As I'm getting familiar with Testcafe, I'm trying to use a command line argument to give the user more information on how to run tests. For that reason, I'm using the minimist package.
However, I cannot print or use any variables outside the test cases. Please find below my code.
import { Selector } from 'testcafe';
import minimist from 'minimist';
const args = minimist(process.argv.slice(2));
const env = args.env;
console.log('*** A SAMPLE CONSOLE OUTPUT ***'); // does not print
fixture `Getting Started`
.page `http://devexpress.github.io/testcafe/example`;
test('My first test', async t => {
console.log('*** ANOTHER SAMPLE CONSOLE OUTPUT ***'); // prints
await t
.typeText('#developer-name', 'John Smith')
.wait(1000)
.click('#submit-button')
// Use the assertion to check if the actual header text is equal to the expected one
.expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');
});
I want to write an if statement that checks if env === '' or use a default argument.
How can I accomplish this?
However, I cannot print or use any variables outside the test cases.
 
Please use a programming way to run TestCafe.
I've changed you code example (test.js) and created a file that runs TestCafe programmatically (run.js).
Put these files into a folder and perform command 'node run.js --env value' in your terminal.
Then you will see the following output:
'*** A SAMPLE CONSOLE OUTPUT ***'
Getting Started
value
test.js
import { Selector } from 'testcafe';
import minimist from 'minimist';
const args = minimist(process.argv.slice(2));
const env = args.env;
console.log('*** A SAMPLE CONSOLE OUTPUT ***');
fixture `Getting Started`
.page `http://devexpress.github.io/testcafe/example`;
test('My first test', async t => {
console.log(env); // prints
await t
.typeText('#developer-name', 'John Smith')
.wait(1000)
.click('#submit-button')
.expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');
});
run.js
const createTestCafe = require('testcafe');
let runner = null;
createTestCafe('localhost', 1337, 1338, void 0, true)
.then(testcafe => {
runner = testcafe.createRunner();
})
.then(() => {
return runner
.src('test.js')
.browsers('chrome')
.run()
.then(failedCount => {
console.log(`Finished. Count failed tests:${failedCount}`);
process.exit(failedCount)
});
})
.catch(error => {
console.log(error);
process.exit(1);
});
A solution to accomplish this is:
1) Create a separate config.js file that will handle your custom command-line options:
import * as minimist from 'minimist';
const args = minimist(process.argv.slice(2));
// get the options --env=xxx --user=yyy from the command line
export const config = {
env: args.env,
user: args.user,
};
2) In you test file:
remove any code outside the fixture and the test methods.
import the config file and inject it in the TestController context
get the command args via the TestController context
import 'testcafe';
import { Selector } from 'testcafe';
import { config } from './config';
fixture('Getting Started')
.beforeEach(async (t) => {
// inject config in the test context
t.ctx.currentConfig = config;
});
test('My first test', async (t) => {
// retrieve cli args from the test context
const currentConfig = t.ctx.currentConfig;
console.log(`env=${currentConfig.env}`);
});

Categories