Node e2e tests - async beforeEach/afterEach hooks fail on Windows - node.js

On OSX and Linux, the following works great (this is as simplified a reproduction as possible, hopefully without sacrificing meaning):
import { expect } from 'chai';
import { MongoClient, Db } from 'mongodb';
import { Application, Request } from 'express';
import { Server } from 'http';
import * as config from 'config';
describe('some test', () =>
{
let Session:{ new(app:Application):Request } = require('supertest-session'),
app:Application,
server:Server,
mongoClient:MongoClient,
db:Db;
beforeEach(async () =>
{
app = express();
server = app.listen(config.Http.port);
request = new Session(app);
// On Windows tests are executed before this resolves
mongoClient = await MongoClient.connect(config.Database.connectionOptions.url);
db = mongoClient.db(config.Database.connectionOptions.database);
});
afterEach(async () =>
{
await db.dropDatabase();
request.destroy();
server.close();
});
it('works like it oughtta', () =>
{
request.post('/api/account/login')
.send({ email: 'me#example.com', password: 'password' })
.expect(200)
.then((res) =>
{
expect(res.success).to.eq(true);
})
})
});
On a Windows machine, the above fails with the following output from npm:
13 verbose stack Exit status 4
13 verbose stack at EventEmitter.<anonymous> (C:\Path\To\AppData\Roaming\nvm\v9.4.0\node_modules\npm\node_modules\npm-lifecycle\lib\index.js:285:16)
... rest of stack
13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:220:5)
If I take the database connection out of the beforeEach hook and do this instead, the test will run and pass, but I still notice hard-to-track-down failures in further tests with async hooks:
before(function(done)
{
MongoClient.connect(function(err, client)
{
mongoClient = client;
done();
});
});
after(function(done)
{
mongoClient.close(function() { done(); });
});
I've seen this behavior using Mocha, Jest and FuseBox test runners. Running node#9.4 on both machines. The solution to this cannot be "just make sure I test my tests on a Windows machine before I push".

Related

Express.js + Jest + Supertest + TypeORM ReferenceError

I am trying to develop an API and test it with jest + supertest + typeorm. So, if I import my server instance, I see this error:
ReferenceError: You are trying to "import" a file after the Jest environment has been torn down. From test/Test.test.ts.
// src/app.ts
import express from "express";
import ds from "./app-data-source";
ds.initialize().catch((err) => {
console.error("Error during Data Source initialization:", err)
})
const app = express();
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.on("close", () => ds.destroy())
export default app;
// src/server.ts
import app from "./app";
const server = app.listen(3000);
export default server;
// src/app-data-source.ts
import { DataSource } from "typeorm"
const ds = new DataSource({
type: "sqlite",
database: ":memory:",
entities: ["src/entity/*.ts"],
logging: false,
synchronize: true,
})
export default ds;
// test/Test.test.ts
import request from "supertest";
import server from "../src/server";
describe("GET / - a simple api endpoint", () => {
test("Test #1", async () => {
const response = await request(server).get("/");
expect(response.statusCode).toBe(404);
});
afterAll(done => {
server.close(done)
})
});
And as a result I get this error
yarn run v1.22.17
warning ../package.json: No license field
$ NODE_ENV=test jest --runInBand
PASS test/Test.test.ts
GET / - a simple api endpoint
✓ Test #1 (9 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.134 s, estimated 2 s
Ran all test suites.
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From test/Test.test.ts.
at tryToRequire (node_modules/src/util/ImportUtils.ts:21:17)
at importOrRequireFile (node_modules/src/util/ImportUtils.ts:35:25)
at async /Users/sergey/Work/*****/node_modules/src/util/DirectoryExportedClassesLoader.ts:57:45
at async Promise.all (index 0)
at async importClassesFromDirectories (node_modules/src/util/DirectoryExportedClassesLoader.ts:63:18)
at async ConnectionMetadataBuilder.buildEntityMetadatas (node_modules/src/connection/ConnectionMetadataBuilder.ts:92:17)
at async DataSource.buildMetadatas (node_modules/src/data-source/DataSource.ts:674:13)
at async DataSource.initialize (node_modules/src/data-source/DataSource.ts:242:13)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
I figured out that this is a problem, probably due to an open typeorm connection, but I don't know how to fix it because I do
// In test file
// ...
afterAll(done => {
server.close(done)
})
// ...
as well as
import ds from "./app-data-source";
ds.initialize() // ...
// ...
app.on("close", () => ds.destroy())
I tried to search for information on Google and did not find anything useful, all the answers do not help me, useFakeTimers not working for me

I can't create the pact-file, because the Query Path isn't correct

When I run the consumer part, Its get the following error:
1 failing
1) The Project API
"after each" hook for "returns the correct response":
Error: Pact verification failed - expected interactions did not match actual.
at new VerificationError (node_modules\#pact-foundation\pact\errors\verificationError.js:19:42)
at C:\Nexus\NovoTesteContrato\node_modules\#pact-foundation\pact\httpPact.js:102:23
at processTicksAndRejections (internal/process/task_queues.js:95:5)
And
Pact verification failed!
Actual interactions do not match expected interactions for mock MockService.
Missing requests:
GET /Project?Responsible=teste.k6%40k6.com&Name=Teste+para+a+pequisa
See C:/Nexus/NovoTesteContrato/logs/mockserver-integration.log for details.
My mock API and official API don't aceppt:
GET /Project?Responsible=teste.k6%40k6.com&Name=Teste+para+a+pequisa
My mock API and official API aceppt:
GET /Project?responsible=teste.k6%40k6.com&Name=Teste%20para%20a%20pequisa
How do I make PACT-JS send the request with "Test%20for%20a%20research" and not with "Test+for+the+research"?
My code is
import 'dotenv/config';
import { Matchers, Pact } from '#pact-foundation/pact';
import { eachLike, somethingLike, integer } from '#pact-foundation/pact/src/dsl/matchers';
import path from 'path';
import { GetProjectScenario1 } from '../../../api';
const mockProvider = new Pact({
consumer: 'TestProjectApi',
provider: 'Nexus',
log: path.resolve(process.cwd(), "__tests__/contract/logs", "pact.log"),
dir: path.resolve(process.cwd(), "__tests__/contract/pacts"),
logLevel: 'INFO',
pactfileWriteMode: 'overwrite',
spec: 2,
cors: true
});
let ProjectJsonSucessfull = ""
let responsibleSceario1 = "teste.k6#k6.com"
describe('Given - API TEST Nexus Project STAY ONLINE', () => {
beforeAll(async () => {
ProjectJsonSucessfull = require("./resources/tmp/Get_project_successfull_response.json")
})
describe('When I Search Project with sucessfull', () => {
beforeAll(async () =>
await mockProvider.setup().then(() => {
mockProvider.addInteraction({
uponReceiving: 'Only responsible',
withRequest: {
method: 'GET',
path: `/Project?Responsible=${responsibleSceario1}`
},
willRespondWith: {
status: 200,
headers: {
'Content-Type': 'application/json',
},
body: Matchers.like(ProjectJsonSucessfull).contents
}
});
})
);
afterEach(() => mockProvider.verify());
it('should return the expected data', async () => {
const response = await GetProjectScenario1(responsibleSceario1);
expect(response.headers['content-type']).toBe("application/json; charset=utf-8")
expect(response.status).toEqual(200);
expect(response.data).toEqual(ProjectJsonSucessfull);
});
})
afterAll(() => mockProvider.finalize())
})
Sed resquest with "/Project?responsible=teste.k6%40k6.com&Name=Teste%20para%20a%20pequisa"

MSW v0.40 Error: thrown: Exceeded timeout of 5000 ms for a test

I've been using MSW since v0.35.0. Recently I updated it to v0.40.1 and now it seems like MSW is not intercepting the request to the servers and I'm getting the following error.
Here is my test code.
import axios from 'axios';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const path = 'login/';
const accessToken = 'AccessTokenValue';
const correctCredential = { email: 'test#email.com', password: 'password' };
const server = setupServer(
rest.post(path, (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ data: { access: accessToken } }));
}),
);
beforeAll(() => server.listen());
afterAll(() => server.close());
afterEach(() => server.resetHandlers());
describe('Login', () => {
test('Case: Success', async () => {
let token = '';
await axios
.post('https://test.com' + path, correctCredential)
.then((response) => (token = response.data.data.access));
expect(token).toBe(accessToken);
});
});
And this is the error I get.
Error: Request failed with status code 400
at createError (<my_local_path>)
at settle (<my_local_path>)
at IncomingMessage.handleStreamEnd (<my_local_path>)
at IncomingMessage.emit (node:events:402:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
Here are the versions of the other packages I use.
jest: 27.0.6
axios: 0.25.0
I read Examples from MSW and I don't see any problem with my implementation.
Perhaps this issue is relevant.
https://github.com/mswjs/msw/issues/1125
This issues was fixed 5 days ago, so I believe a corrected version will be released in the near future.
btw, downgrading to 0.36.8 is temporary solution.

Cannot set uncompiled validation rules without configuring a validator

I have downloaded a learning project so it is not my code, but when I want to start it getting this error. I tried to debug a little bit by myself but as I'm new to Nodejs so having a problem here...
Error: Cannot set uncompiled validation rules without configuring a validator
at Object.module.exports.register (/home/antonp/Desktop/pizza-luvrs/routes/index.js:25:10)
at startServer (/home/antonp/Desktop/pizza-luvrs/index.js:12:10)
here is the link for the full project. Github repo
index.js
const Hapi = require('#hapi/hapi')
const plugins = require('./plugins')
const routes = require('./routes')
async function startServer () {
const server = Hapi.Server({
port: process.env.PORT || 3000
})
await plugins.register(server)
routes.register(server)
try {
await server.start()
console.log(`Server running at: ${server.info.uri}`)
} catch (err) {
console.error(`Server could not start. Error: ${err}`)
}
}
process.on('unhandledRejection', err => {
console.log(err)
process.exit()
})
startServer()
Your issue is due to a change in hapi. Try changing the following code in pizza-luvrs-master/routes/login.post.js
validate: {
payload: {
username: Joi.string().alphanum().min(3).max(30).required(),
password: Joi.string().min(3).max(30).required()
}
}
to
validate: {
query:Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
password: Joi.string().min(3).max(30).required()
})
}

get read ENOTCONN error on windows 10 when calling a docker api

I' trying to start an exec instance of my docker image through my node project with code below:
return axios.post(host + `/exec/${id}/start`, { Detach: false, Tty: true },
{ responseType: 'stream' })
.then(function () {
let stream = response.data
let socket = stream.socket
socket.on('data', (data: string) => {
process.stdin.pause()
if (!firstLine)
process.stdout.write(data)
firstLine = false
process.stdin.resume()
})
process.stdout.on('data', i => {
socket.write(i.toString())
if (i == DetachKey) {
rl.emit('SIGINT')
}
})
rl.on('SIGINT', function () {
// stop input
socket.emit('end')
process.stdin.pause()
process.stdout.write(exec_exit_msg)
process.exit(0)
})
})
On Linux(Ubuntu & Mint) everything is OK, but when I test my code on windows 10 I get the error blow:
Error: read ENOTCONN
at WriteStream.Socket._read (net.js:529:20)
at WriteStream.Readable.read (_stream_readable.js:453:10)
at resume_ (_stream_readable.js:929:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
My node version is v10.15.3 (using nvm).
It seems that there is something wrong with the socket connection. I searched a lot but could not figured out how to solve the problem.
Below Part of Code makes the error. I removed it and change the code a little
But I don't know why it was ok in ubuntu
process.stdout.on('data', i => {
socket.write(i.toString())
if (i == DetachKey) {
rl.emit('SIGINT')
}
})

Resources