Testing ExpressJS endpoint with Jest - express

I'm trying to test an endpoint from my express application using Jest. I'm migrating from Mocha to try out Jest to improve the speed. However, my Jest test does not close? I'm at a loss...
process.env.NODE_ENV = 'test';
const app = require('../../../index');
const request = require('supertest')(app);
it('should serve the apple-app-site-association file /assetlinks.json GET', async () => {
const response = await request.get('/apple-app-site-association')
expect(response.statusCode).toBe(200);
});

So the only thing I could think for this failing is that you might be missing the package babel-preset-env.
In any case there are two other ways to use supertest:
it('should serve the apple-app-site-association file /assetlinks.json GET', () => {
return request.get('/apple-app-site-association').expect(200)
})
or
it('should serve the apple-app-site-association file /assetlinks.json GET', () => {
request.get('/apple-app-site-association').then(() => {
expect(response.statusCode).toBe(200);
done()
})
})
async is the fancy solution, but is also the one that has more requirements. If you manage to find what was the issue let me know :).
(Reference for my answer: http://www.albertgao.xyz/2017/05/24/how-to-test-expressjs-with-jest-and-supertest/)

it("should serve the apple-app-site-association file /assetlinks.json GET", async () => {
await request
.get("/apple-app-site-association")
.send()
.expect(200);
});
if your configuration setup is correct this code should work.

Related

Not able to store cookies in all the cypress tests

I am trying to automate my application with cypress. Have written few tests in my class and before visiting the site I have set up cookies (To login without entering username, password and otp). I have tried several ways to store these cookies and call before each of these tests but cookies work only for the 1st test and I am logged out for the subsequent tests.
Please find my code below. I am calling data using fixtures. It works fine only when i set sso and user agent for every test and I want to eliminate this.
describe('Watchlist Testsuite', () => {
let data;
before(() => {
cy.fixture('example').then((fdata) => {
data = fdata;
});
});
it('Setting up cookies', () => {
cy.setupCookies(data.sso, data.uid, data.userAgent, data.devId, data.url)
.then(() => cy.visit(data.url))
})
it('Enter Passcode', () => {
cy.setCookie('x-sso-token', data.sso)
cy.setCookie('x-user-agent', data.userAgent)
Cypress.config('pageLoadTimeout', 2000)
cy.enterPasscode(data.passcode)
Cypress.config('pageLoadTimeout', 20000)
cy.closeOKButton()
})
it('Create a watchlist', () => {
cy.setCookie('x-sso-token', data.sso)
cy.setCookie('x-user-agent', data.userAgent)
watchlistTest.createWatchlist(data.watchlistName)
})
Below are the ways with which I tried to preserve the cookies for all tests but none of them seem to be working.
Setting up cookies in beforeeach method
beforeEach('Setup cookies', ()=> {
cy.setupCookies(data.sso, data.uid, data.userAgent, data.devId, data.url)
.then(() => cy.visit(data.url))
})
Using cookies defaults
Cypress.Cookies.defaults
({
preserve:[data.sso, data.userAgent]
})
Using cy.session (I have set experimentalSessionAndOrigin to true)
it('setting up cookies',() => {
console.log('sso is ', data.sso)
const validate = () => {
cy.getCookie(data.sso).should('exist')
}
cy.session([window.sessionStorage.setItem('x-sso-token', data.sso),
window.sessionStorage.setItem('x-uid', data.uid),
window.sessionStorage.setItem('x-user-agent', data.userAgent),
window.sessionStorage.setItem('dev-id', data.devId)], {validate})
})
PS: I am using the Cypress 10.3.1 version.
Please guide me on the right approach to solve the issue.

How to read synchronously data in ReactNative

AsyncStorage.getItem('token').then(value => {
token = value
console.log("Assigned token")
});
What is the proper way to read this synchronously?
I tried using await/async, they weren't installed, and have tried several ways to install babel generators.
How do I install async/await in React Native and read synchronously?
You don't need to install async/await. It's already there. To use, this is the way it should be. Declare the function as async then put await before AsyncStorage.
async Some(){
var token = await AsyncStorage.getItem('token')
console.log("Assigned token:",token)
});
}
Actually I think you are fine without await/async. You are just sending the "problem" of handling the promise to the parent function.
Usually, what I do, (if you are thinking about loading the auth token before continuing) is something like:
this.setState({loading: true}, () => {
AsyncStorage.getItem('token').then(value => {
token = value
console.log("Assigned token")
this.setState({loading: false}, () => {
this.continue();
})
});
})

Testing serverless with Mocha plugin

I have been using serverless for a while now, however this is the first time I'm trying to use mocha for writing tests. When I'm trying to run the following sls create test --function insiders/create.create I get the following error Cannot read property 'handler' of undefined. This is how my serverless.yml looks like for the handler I have created
createInsider:
handler: insiders/create.create
events:
- http:
path: insiders
method: post
cors: true
This is how the plugin Mocha is defined
plugins:
- serverless-mocha-plugin
The code is deployed and it works fine. The namespacing is as insiders/create.js is where I have defined my function.
module.exports.create = () => {}
I have also tried the following ways
sls create test --function insiders/create
sls create test --function create
Not sure if it answers your question, but since majority of the business logic for serverless code is just regular javascript, you can use mocha directly for unit testing.
npm install --save-dev mocha
In package.json
"test": "mocha test/**/*test.js",
Create a test folder and corresponding test files under it
Ex: for src/insiders/create.js create test/insiders/create.test.js
For every handler test the outputs for different inputs
For callback style
describe('create', () => {
it('should execute', (done) => {
const event = {};
const context = {};
const callback = (_, response) => {
//assert required things
done();
};
const handler = require('../../src/insiders/create.js');
handler(event, context, callback)
});
});
For async await style
describe('create', () => {
it('should execute', async () => {
const event = {};
const handler = require('../../src/insiders/create.js');
const result = await handler(event);
//assert the result
});
});
We use this style and it works very well for us.
Edit: Fix the mocha glob pattern to search recursively for all test files.

How to nest Vue.nextTick when testing?

I'm trying to test what happens in my app on two consecutive ticks. This is what I have so far (the tests fail in the karma devtools, but fail in the command line):
import { mount } from 'avoriaz';
import MyComponent from './MyComponent';
describe('testing', function() {
it('should do something', (done) => {
const wrapper = mount(MyComponent, { store });
wrapper.vm.changeData();
Vue.nextTick(() => {
expect(wrapper.vm.something).to.eql(somethingElse);
wrapper.vm.changeData();
Vue.nextTick(() => {
expect(wrapper.vm.something2).to.eql(somethingElse2);
done();
});
done();
});
});
});
I also tried using then() and catch(), but karma still thinks my failing tests are passing.
Should I only have one done() call? I'm not really sure what this callback is doing.
As indicated here, there is an even better solution, which prevents Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.:
it('should do something', (done) => {
const wrapper = mount(MyComponent, { store });
wrapper.vm.changeData();
Vue.nextTick(() => {
expect(wrapper.vm.something).to.eql(somethingElse);
wrapper.vm.changeData();
Vue.nextTick().then(() => {
expect(wrapper.vm.something2).to.eql(somethingElse2);
}).then(done, done);
});
});
I'd like to also use the async/await version, but I wasn't able to get it to work.

How to test an Electron app with selenium webdriver

I have read the documentation and I have followed the tutorial step by step and I only have managed to run the app.
Documentation: http://electron.atom.io/docs/tutorial/using-selenium-and-webdriver/
The connection with chromedriver I cannot make it work, when I launch the test and try click a simple button I get this:
Error: ChromeDriver did not start within 5000ms at Error (native)
at node_modules/spectron/lib/chrome-driver.js:58:25 at
Request._callback (node_modules/spectron/lib/chrome-driver.js:116:45)
at Request.self.callback
(node_modules/spectron/node_modules/request/request.js:200:22) at
Request.
(node_modules/spectron/node_modules/request/request.js:1067:10) at
IncomingMessage.
(node_modules/spectron/node_modules/request/request.js:988:12) at
endReadableNT (_stream_readable.js:913:12) at _combinedTickCallback
(internal/process/next_tick.js:74:11) at process._tickCallback
(internal/process/next_tick.js:98:9)
My code:
"use strict";
require("co-mocha");
var Application = require('spectron').Application;
var assert = require('assert');
const webdriver = require('selenium-webdriver');
const driver = new webdriver.Builder()
.usingServer('http://127.0.0.1:9515')
.withCapabilities({
chromeOptions: {
binary: "./appPath/app"
}
})
.forBrowser('electron')
.build();
describe('Application launch', function () {
this.timeout(100000);
var app;
beforeEach(function () {
app = new Application({
path: "./appPath/app"
});
return app.start();
});
afterEach(function () {
if (app && app.isRunning()) {
return app.stop();
}
});
it('click a button', function* () {
yield driver.sleep(5000);
yield driver.findElement(webdriver.By.css(".classSelector")).click();
});
});
Thanks and sorry for my English.
I recommend you to use Spectron. which is a less painful way of testing your electron app. in my opinion perfect combination is using it with Ava test framework, which allows the concurrently test.
async & await is also another big win. which allows you to have so clean test cases.
and also if you have a test which needs to happen serial, you can use test.serial
test.serial('login as new user', async t => {
let app = t.context.app
app = await loginNewUser(app)
await util.screenshotCreateOrCompare(app, t, 'new-user-mission-view-empty')
})
test.serial('Can Navigate to Preference Page', async t => {
let app = t.context.app
await app.client.click('[data-test="preference-button"]')
await util.screenshotCreateOrCompare(app, t, 'new-user-preference-page-empty')
})
and just for reference; my helper test cases.
test.before(async t => {
app = util.createApp()
app = await util.waitForLoad(app, t)
})
test.beforeEach(async t => {
t.context.app = app
})
test.afterEach(async t => {
console.log('test complete')
})
// CleanUp
test.after.always(async t => {
// This runs after each test and other test hooks, even if they
failed
await app.client.localStorage('DELETE', 'user')
console.log('delete all files')
const clean = await exec('rm -rf /tmp/DesktopTest')
await clean.stdout.on('data', data => {
console.log(util.format('clean', data))
})
await app.client.close()
await app.stop()
})
util function,
// Returns a promise that resolves to a Spectron Application once the app has loaded.
// Takes a Ava test. Makes some basic assertions to verify that the app loaded correctly.
function createApp (t) {
return new Application({
path: path.join(__dirname, '..', 'node_modules', '.bin',
'electron' + (process.platform === 'win32' ? '.cmd' : '')),
// args: ['-r', path.join(__dirname, 'mocks.js'), path.join(__dirname, '..')],
env: {NODE_ENV: 'test'},
waitTimeout: 10e3
})
}
First off, Spectron (which is a wrapper for WebdriverIO) and WebdriverJS (which is part of Selenium-Webdriver) are two different frameworks, you only need to use one of them for your tests.
If you are using WebdriverJS, then you need to run ./node_modules/.bin/chromedriver in this step: http://electron.atom.io/docs/tutorial/using-selenium-and-webdriver/#start-chromedriver
I could get ChromeDriver working by adding a proxy exception in my terminal.
export {no_proxy,NO_PROXY}="127.0.0.1"