I am using the Detox Test tool, and I am having difficulties.
I only installed Detox, I only ran the basic code for the ios test, and I get the following error:
Please help me.
Just iOS
Error Log
$ detox test --configuration ios.sim.debug --debug-synchronization --take-screenshots all --record-videos nonex --record-logs all
node_modules/.bin/jest e2e --config=e2e/config.json --maxWorkers=1 --testNamePattern='^((?!:android:).)*$'
FAIL e2e/firstTest.spec.js
● Test suite failed to run
ReferenceError: before is not defined
3 | const adapter = require('detox/runners/mocha/adapter');
4 |
> 5 | before(async () => {
| ^
6 | await detox.init(config);
7 | });
8 |
at Object.<anonymous> (init.js:5:1)
package.json
"script":{
"e2e:ios": "detox test --configuration ios.sim.debug --debug-synchronization --take-screenshots all --record-videos nonex --record-logs all",
"e2e:android": "detox test --configuration android.emu.debug --loglevel verbose --take-screenshots all --record-videos none --record-logs all"
},
dependencies": {
"detox": "^8.0.0",
"jest": "^23.1.0",
"mocha": "^5.2.0",
},
"detox": {
"configurations": {
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/{app_name[enter image description here][1]}.app",
"build": "xcodebuild -workspace ios/{workspace_Name}.xcworkspace -scheme {scheme_name} Dev -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 7"
},
"android.emu.debug": {
"binaryPath": "android/app/build/outputs/apk/dev/debug/{apk_name}.apk",
"build": "react-native run-android --variant=devDebug --appId com.noahclient.dev",
"type": "android.emulator",
"name": "Nexus_5X_API_26"
}
},
"test-runner": "jest"
}
}
I looks like you are trying to run a mocha test on the jest runner. As your init.js is setup for mocha but the test runner that you are using is jest. This is confirmed by the error message node_modules/.bin/jest e2e... that you are getting.
You should pick either one, jest or mocha and use it. Rather than trying to use both.
#Jest
If you are using jest your init.js should look like this:
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
jest.setTimeout(120000);
jasmine.getEnv().addReporter(adapter);
beforeAll(async () => {
await detox.init(config);
});
beforeEach(async () => {
await adapter.beforeEach();
});
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});
and you should add "test-runner": "jest" to the detox object in your package.json.
You should also have a config.json file in the same location as the init.js containing:
{
"setupFilesAfterEnv" : ["./init.js"]
}
#Mocha
If you are using mocha then your init.js should look like this:
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/mocha/adapter');
before(async () => {
await detox.init(config);
});
beforeEach(async function () {
await adapter.beforeEach(this);
});
afterEach(async function () {
await adapter.afterEach(this);
});
after(async () => {
await detox.cleanup();
});
and you should remove the "test-runner": "jest" from the detox object in your package.json as it is not required.
Instead of a config.json file you should have a mocha.opts file beside your init.js and it should have something similar to:
--recursive
--timeout 120000
--bail
#Next steps
Choose the test runner that you are wanting to run; either jest or
mocha.
Make sure you have the correct init.js file for the test runner.
If using jest have a config.json file and add the test-runner to the detox object in the package.json.
If using mocha have a mocha.opts file. No need to specify a test-runner in the detox object in the package.json.
You can see the setup instructions here: https://github.com/wix/detox/blob/master/docs/Introduction.GettingStarted.md#step-3-create-your-first-test
If you are still having issues let me know.
Related
I'm trying to use Synpress, but I fail to understand how to solve
TypeError: cy.acceptMetamaskAccess is not a function
Let me share the relevant code* (I mostly followed this tutorial https://medium.com/andamp/how-to-setup-synpress-for-wen3-dapp-frontend-test-automation-with-metamask-73396896684a)
*if something is missing, please let me know
package.json:
{
"devDependencies": {
"#testing-library/cypress": "^8.0.2",
"cypress": "^9.7.0"
},
"scripts": {
"cypress:open": "cypress open",
"test": "env-cmd -f .env npx synpress run -cf synpress.json --config supportFile='tests/support/index.js'",
"test:watch": "env-cmd -f .env npx synpress open -cf synpress.json"
},
"dependencies": {
"#synthetixio/synpress": "^1.2.0",
"env-cmd": "^10.1.0"
}
}
How I configured my synpress.json
{
"baseUrl": "https://dappify.com/",
"userAgent": "synpress",
"retries": { "runMode": 0, "openMode": 0 },
"integrationFolder": "tests/integration",
"screenshotsFolder": "screenshots",
"videosFolder": "videos",
"video": true,
"chromeWebSecurity": true,
"viewportWidth": 1366,
"viewportHeight": 850,
"component": {
"componentFolder": ".",
"testFiles": "**/*spec.{js,jsx,ts,tsx}"
},
"env": {
"coverage": false
},
"defaultCommandTimeout": 30000,
"pageLoadTimeout": 30000,
"requestTimeout": 30000,
"supportFile": "tests/support/index.js"
}
Simple test
describe('Test User Login', () => {
it('Connects with Metamask', () => {
cy.visit('https://dappify.com')
cy.contains('Sign').click();
cy.contains('Confirm').click();
cy.contains('Connect Wallet').click();
cy.contains('Metamask').click();
cy.switchToMetamaskWindow();
cy.acceptMetamaskAccess().should("be.true");
})
})
I don't understand why cy.acceptMetamaskAccess() is not a function, I can find it here: https://github.com/synthetixio/synpress/blob/master/support/index.d.ts
How can I use the functions listed in this index.d.ts file?
** Solution **
Answer by Fody was helpful! Let me summarise the steps needed:
inside support folder you need an index.js
inside index.js
import './commands'
import "#synthetixio/synpress/support";
If you want to add custom functions add this file to support too
inside commands.js:
import "#testing-library/cypress/add-commands";
// here go(es) your custom function(s)
It's a bit hard to untangle the Synpress structure. Usually with a plugin library you import a support component and that adds the library's custom commands to your test.
The article says
Run your tests with env-cmd -f .env npx synpress run -cf synpress.json --config supportFile='support/index.js'
which makes me think the last parameter is bringing in the custom commands.
If you already tried that, the following is the command definition, you can try adding it at the top of your spec.
Cypress.Commands.add('acceptMetamaskAccess', allAccounts => {
return cy.task('acceptMetamaskAccess', allAccounts);
})
My Jest config details are
jest.config.js
module.exports = {
transform: {
'^.+\\.svelte$': 'svelte-jester',
'^.+\\.js$': 'babel-jest',
},
moduleFileExtensions: ['js', 'svelte'],
}
babel.config.js
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
}
package.json
.
.
"#babel/core": "^7.10.2",
"#babel/preset-env": "^7.10.2",
"babel-jest": "^26.0.1",
"jest": "^26.0.1",
"svelte-jester": "^1.0.6",
"#testing-library/svelte": "^3.0.0"
},
"scripts": {
"build": "cross-env NODE_ENV=production webpack",
"dev": "webpack-dev-server --content-base public",
"test": "jest src",
"test:watch": "npm run test -- --watch"
},
.
.
I created src/test folder where my test.spec.js is as follows
import {fireEvent, render} from '#testing-library/svelte';
import App from '../App.svelte';
describe('test', () => {
test('Just a mock test', async () => {
const myMock = jest.fn();
console.log(myMock());
myMock.mockReturnValueOnce(10).mockReturnValueOnce('x').mockReturnValue(true);
console.log(myMock(), myMock(), myMock(), myMock());
});
});
Plz note that this I used a jest mock function just for testing purpose but whenever I import a svelte file as in this case App.svelte I get an error as below
FAIL src/test/test.spec.js
● Test suite failed to run
ParseError: Identifier is expected
I found a possible solution to this parsing error. Apparently, the IDE was unable to resolve certain style classes in the test.svelte file defined inside style tag, which is why it was showing up ParseError.
I would suggest anyone coming across this error to check your svelte file thoroughly for errors since svelte-testing-lib parses through the entire file before executing any test function.
UPDATE: index.js file content added.
I have this electron app that is executing some bash scrips(*.sh) files to perform some task.
Everything is working absolutely fine in the development environment but when building the production build for deb installer for Ubuntu platform, everything is working, like opening on the app, other NodeJS stuff, but bash scripts are not executing.
Problem Statement: How to execute shell scripts in the production build of an electron app for Linux(Ubuntu OS). Getting this error
app/terminal_scripts/timer.sh Not Found
Below are the detailed explanation for the app.
**Project Directory Setup**:
ProjectName
|
app > css | images | js | renders
terminal_scripts
node_modules
package.json
package-lock.json
Where inside the app directory, I have all CSS, images, js, HTML, and terminal scripts.
package.json:
{
"name": "timer",
"productName": "Timely",
"version": "1.0.25",
"description": "This desktop app shows you system clock",
"main": "app/js/main/index.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "nodemon --exec 'electron .'",
"dist": "electron-builder"
},
"homepage": ".",
"keywords": [
"Electron",
"Desktop App"
],
"author": "NotABot Ltd <contact#notabot.com>",
"contributors": [
{
"name": "Not A Bot",
"email": "nab#notabot.com"
}
],
"license": "ISC",
"dependencies": {
"desandro-matches-selector": "^2.0.2",
"electron-context-menu": "^1.0.0",
"electron-is": "^3.0.0",
"fix-path": "^3.0.0",
"isotope-layout": "^3.0.6",
"jquery": "^3.5.0",
"jquery-bridget": "^2.0.1"
},
"build": {
"appId": "com.test.timely",
"productName": "Timely",
"linux": {
"target": "deb",
"category": "System"
}
},
"devDependencies": {
"electron": "^8.1.1",
"electron-builder": "^22.6.0"
}
}
HTML:
<html>
<head>
<title>Timely</title>
</head>
<body>
<button onclick="displayTime()">Display Time</button>
<textarea rows="20" cols="90" id="command-output" disabled="true"></textarea>
<script>
const {app} = require('electron');
function displayTime(){
console.log("button clicked");
let cmd = `bash app/terminal_scripts/timer.sh`;
let completeMessage = 'This is the message';
backgroundProcess(cmd, completeMessage);
}
function getCommandOutput() { return document.getElementById("command-output"); };
function getStatus() { return document.getElementById("status"); };
function appendOutput(msg) { getCommandOutput().value += (msg+'\n'); };
function setStatus(msg) { getStatus().innerHTML = msg; };
function backgroundProcess(cmd, completeMessage){
const process = require('child_process');
var child = process.execFile(cmd, [] , {shell: true} );
appendOutput("Processing......");
child.on('error', function(err) {
appendOutput('stderr: '+err );
});
child.stdout.on('data', function (data) {
appendOutput(data);
});
child.stderr.on('data', function (data) {
appendOutput(data );
});
return new Promise((resolve, reject) => {
child.on('close', function (code) {
console.log(`code is: ${code}`);
if (code == 0){
setStatus(completeMessage);
resolve(1);
}
else{
setStatus('Exited with error code ' + code);
resolve(-1);
}
});
});
}
</script>
</body>
</html>
Bash Script:
#!/bin/bash
timer="$(date)"
echo "$timer"
Permission is set 777 for this shell file
Platform Information:
OS: Ubuntu 18.04.4 LTS
NodeJS: 13.6.0
NPM: 6.14.5
Electron: 8.1.1
Electron Builder: 22.6.0
index.js
const {app, BrowserWindow, Menu, Tray, ipcMain, MenuItem} = require('electron');
const path = require('path');
const contextMenu = require('electron-context-menu');
let splashWindow;
function createMainWindow(){
mainWindow = new BrowserWindow({
minHeight: 700,
minWidth: 800,
webPreferences: {
nodeIntegration: true,
webviewTag: true
},
show: false
});
//For dev only
// mainWindow.webContents.openDevTools();
mainWindow.loadFile('app/renderer/index.html');
mainWindow.maximize();
}
app.on('ready', () =>{
createMainWindow();
});
Another way is to move flies to a new directory outside app directory and call it as extraResources.
Inside that directory you can add all your bash files and for production you can use below method.
let urlPath = path.join(process.resourcesPath, '/extraResources/')
and then use let cmd = `${urlPath}timer.sh`;
I have created a new directory alongside the app directory called the termainal_scripts.
Inside this, I have my bash file timer.sh.
I figured out how to execute shell scripts, in production by using process.resourcesPath inside path.join().
So, let the fixed path be as:
let fixedURL = path.join(process.resourcesPath, '/terminal_scripts/');
Then the command to execute will be:
let cmd = `${fixedURL}timer.sh`
I created a node script which checks if my project contains lock file or not. If it doesn't then I want to abort my npm build. Any idea how to do that?
lock-check.js
const path = require('path');
const fs = require("fs");
const lockFiles = ["package-lock.json", "npm-shrinkwrap.json", "yarn.lock"];
let exists = 0;
function checkIfExists() {
lockFiles.forEach(
(lf) => {
if (fs.existsSync(lf)) {
exists++;
}
});
return exists > 0;
}
package.json
...
"scripts": {
"prestart": "node ./lock-check.js" // Abort the task
"start": "webpack-dev-server --config config/webpack.dev.js --hot --inline"
}
...
To abort the build process you just have to call process.exit(1),
Here I have used 1 but you can use any non-zero exit code to tell it wasn't a successful build as 0 means successful.
You can read more on official nodejs docs
I have a Node app I'd like to test, and get coverage report. I followed the Getting Started Guide but it doesn't seem to work.
My source, in src/two.js:
var two = 1 + 1;
module.exports = two;
My test, in test/two.js:
var expect = require('expect');
var two = require('../src/two');
describe('two', function() {
it('should be 2', function(done) {
expect(two).toBe(2);
done();
});
});
And my package.json:
{
"scripts": {
"test": "mocha",
"cover": "mocha -r blanket -R html-cov > coverage.html"
},
"devDependencies": {
"blanket": "^1.2.1",
"expect": "^1.13.4",
"mocha": "^2.3.4"
}
}
When I run npm run test everything works as you'd expect. But when I run npm run cover, in my coverage.html file I get 0% coverage 0 SLOC and nothing else.
I got it to run by adding this to package.json:
...
"config": {
"blanket": {
"pattern": "src",
"data-cover-never": ["node_modules"]
}
},
...
Apparently Blanket does not default to src despite what the guide says (there's an old open issue on GitHub).
It also tries to cover all of the paths that match the pattern, not just the src dir, so in this case it tried to cover external files as well (node_modules/has/src/index.js, which was installed by Expect). I had to add the data-cover-never to avoid it.