JSDOM - nodejs makes clean exit, doesn't load - node.js

I am following a tutorial on this site:
https://phasertutorials.com/creating-a-simple-multiplayer-game-in-phaser-3-with-an-authoritative-server-part-1/
I am trying to get the last step to work.
I tried this initially with my own code as I am begining to understand using node and express. I got the same error, so I did a clean start and followed the guide exactly as I thought I had made a mistake and couldn't find it. But now I think there is an issue in this function, I don't know of.
Everything works fine until I reach the last step- including this function:
function setupAuthoritativePhaser() {
JSDOM.fromFile(path.join(__dirname, 'authoritative_server/index.html'), {
// To run the scripts in the html file
runScripts: "dangerously",
// Also load supported external resources
resources: "usable",
// So requestAnimatinFrame events fire
pretendToBeVisual: true
}).then((dom) => {
dom.window.gameLoaded = () => {
server.listen(8081, function () {
console.log(`Listening on ${server.address().port}`);
});
};
}).catch((error) => {
console.log(error.message);
});
};
my nodemon makes a clean exit and waits for changes before restarting.
any ideas?
Your help is greatly appreciated.

I found my own answer. Apparently I am a fool, I removed the call of this function...
setupAuthoritativePhaser();
However, I am not getting the correct phaser tag in the console log, it should say Phaser .... (Headless | HTML5 Audio) but it still says Phaser v3.15.1 (WebGL | Web Audio), though in my node it says the correct phrase...

you need remove old code in server/index.js
server.listen(8081, function () {
console.log(`Listening on ${server.address().port}`);
});
and use
dom.window.gameLoaded = () => {
server.listen(8081, function () {
console.log(`Listening on the ${server.address().port}`);
});
};
finaly server/index.js look like
const express = require('express');
const app = express();
const server = require('http').Server(app);
const path = require('path');
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
app.use(express.static(__dirname + '/public'));
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
// server.listen(8081, function () {
// console.log(`Listening on ${server.address().port}`);
// });
function setupAuthoritativePhaser() {
console.log(__dirname)
JSDOM.fromFile(path.join(__dirname, '/authoritative_server/index.html'), {
// To run the scripts in the html file
runScripts: "dangerously",
// Also load supported external resources
resources: "usable",
// So requestAnimatinFrame events fire
pretendToBeVisual: true
}).then((dom) => {
dom.window.gameLoaded = () => {
server.listen(8081, function () {
console.log(`Listening on the ${server.address().port}`);
});
};
}).catch((error) => {
console.log(error.message);
});
}
setupAuthoritativePhaser();

Related

How to run Koa server before Tests in Mocha?

I read a lot of answers to similar questions already but can't figure out what is wrong in my code.
this is my server.js file
const Koa = require('koa')
const Router = require('koa-router')
const app = new Koa()
app.use(require('koa-bodyparser')())
const login = (ctx, next) => {
ctx.body = ctx.request.body
}
const router = new Router({ prefix: '/api' })
router.get('/test', (ctx, next) => {
ctx.body = { resp: 'GET REQUEST /test WORKING' }
})
router.post('/login', login)
app.use(router.routes())
module.exports = app
this is my index.js file
const server = require('./server')
server.listen(3000, () => {
console.log('App is running on http://localhost:3000')
})
and this is my mocha test file
const axios = require('axios').default
const expect = require('chai').expect
const app = require('./server')
describe('7-module-3-task', () => {
describe('test', function () {
let server
before(done => {
server = app.listen(3000, done)
})
after(async () => {
server.close()
})
it('should return response from server', async () => {
const response = await axios.get('http://localhost:3000/api/test')
expect(response.data, 'should return object with key "resp').to.have.property('resp')
})
})
})
It's working okay when I make a request in Postman. I tried multiple options already but I still get 404 response, as I understand test is performed before server started running...? How can I make it working ?
First, I would move the startup (app.listen) directly into the server.js (not critical, but maybe more simpler because the require in your test would then already start your server:
const Koa = require('koa')
const Router = require('koa-router')
const app = new Koa()
app.use(require('koa-bodyparser')())
const router = new Router({ prefix: '/api' })
router.get('/test', (ctx, next) => {
ctx.body = { resp: 'GET REQUEST /test WORKING' }
})
app.use(router.routes())
app.listen(3000); // can be a parameter but for simplicity hardcoded here
module.exports = app
In your test you then do:
let chai = require('chai');
let chaiHttp = require('chai-http');
let server = require('./server'); // this will already start up your server
describe('API Tests', () => {
describe('TEST endpoint', () => {
it('It should GET response from test endpoint', (done) => {
chai.request('http://localhost:3000')
.get('/api/test/') // be sure to have a trailing '/' !!
.end((err, res) => {
res.body.should.have.property('resp');
done();
});
})
});
});
One more hint: maybe in your original code you just have to make sure, that you have a trailing / when calling your route in the test.
Code snippets not testet but I hope you get the idea.
I shared the same code with 2 of my friends and they managed to run tests successfully.
I tested it on my other laptop after this and tests worked as well.
The problem was in the port. 3000 port was used as a default one in the debugger in Webstorm, not sure why but still.
Launching the server on port 3000 in a regular way, not in mocha tests, worked very well but in tests, it did not work, not sure why.
So for those who ever face something similar, check the default port of the debugger or any other built-in server.

Ensure express app is running before starting mocha tests

I built an API for a couchbase database, using express and node.js. My problem is that when I run my tests some of them fail, because the server is not fully running. I found a solution here https://mrvautin.com/ensure-express-app-started-before-tests on how to solve this issue. The article stated that in order to solve this issue, you have to add an event emitter in your server file like this
app.listen(app_port, app_host, function () {
console.log('App has started');
app.emit("appStarted");
});
and then add this, in your test file
before(function (done) {
app.on("appStarted", function(){
done();
});
});
I have tried this, here is my implementation
Server File
app.listen(config['server']['port'], function(){
app.emit("appStarted");
logger.info("Listening")
})
Test File
before(function(done){
app.on("appStarted", function(){
done();
})
});
I keep on getting the following error
1) "before all" hook in "{root}":
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7)
The article is from 2016, so I was thinking that maybe the syntax has been deprecated. I was wondering if someone could please help point me in the right direction?
You can add the below condition, more info see "Accessing the main module".
if (require.main === module) {
// this module was run directly from the command line as in node xxx.js
} else {
// this module was not run directly from the command line and probably loaded by something else
}
E.g.
index.ts:
import express from 'express';
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.sendStatus(200);
});
if (require.main === module) {
app.listen(port, () => {
console.log('App has started');
});
}
export { app, port };
index.test.ts:
import { app, port } from './';
import http from 'http';
import request from 'supertest';
describe('63822664', () => {
let server: http.Server;
before((done) => {
server = app.listen(port, () => {
console.log('App has started');
done();
});
});
after((done) => {
server.close(done);
console.log('App has closed');
});
it('should pass', () => {
return request(server)
.get('/')
.expect(200);
});
});
integration test result:
(node:22869) ExperimentalWarning: The fs.promises API is experimental
63822664
App has started
✓ should pass
App has closed
1 passing (26ms)
!Hi World! My little solution here:
Check this: All depends of your testing markup...
For example, I'm using Mocha and Chai Assertion Library.
const express = require('express');
const request = require("request");
const http = require("http");
const expect = require("chai").expect;
require('dotenv').config();
describe('Server', function() {
const { PORT } = process.env;
const app = express();
before((done) => {
http.Server = app.listen(PORT, () => {
console.log(`Listening Node.js server on port: ${PORT}`);
done();
});
});
it('should return 404 response code status', () => {
const url = `http://localhost:${PORT}/api/v1/yourPath`;
return request(url, (err, response, body) => {
/* Note this result 'cause I don't have any get('/')
controller o function to return another code status
*/
expect(response.statusCode).to.equal(404);
});
})
});

Socket.io: Failed GET requests in the console

I am trying to add socket.io to my code, and the following failed GET request is repeatedly printed to the console whenever I run the website on my localhost.
GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MMNC8I9 0 ()
I do not understand what is sending this request. The socket works, although not entirely in the way I intended it to*.
*I am trying to build a real-time application that works with several clients, and at the moment only one client is being updated at any given time. As I am still learning, I am not sure if this is a normal behaviour or not, but I want to fix the failed request error before I dive into that!
How do I fix the issue? Thank you in advance!
Code below:
server.js
const client=require("socket.io").listen(4040).sockets;
const app = express();
mongoose.connect('mongodb://localhost/<dbname>?replicaSet=rs');
mongoose.connect(config.db);
const db = mongoose.connection;
db.once("open", () => {
console.log(">>> 🖥️ MongoDB: Connection successful");
app.listen(9000, () => {
console.log('Node server running on port 9000');
});
// Connect to Socket.io
client.on("connection", function(){
let queries = db.collection('queries');
// Create function to send status
sendStatus = function(s) {
socket.emit("status", s);
}
});
});
app.post('/query', (req, res, next) => {
<some code omitted>
doc.save()
.then(result => {
socket.emit("query", res);
res.send({
result
});
}
});
Queries.js
constructor(props) {
...
var socket = io.connect("http://localhost:4000/");
if (socket!= undefined) {
socket.on("query", function() {
this.loadQueries();
});
}
index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>

Webtracker using nodejs

I'm trying to create a webtracker to track what pages my users are seeing and how much time they are spending at each page, at the end they will make a registration and i will associate their navigation with the created user.
I want to use node because i can see when the user connect to the url and disconnect to calculate the time, i have tried that with pure javascript but i can see when the user leaves the page only on Chrome.
I have already managed to create some of what i need using the socket.io lib but i can't find a way to use it without creating an html page. What i need is to create something like google analytics where i will only incorporate the script. Is it possible?
I have managed to figure it out so i will post it to help others with the same problem:
Server
let socket = require('socket.io');
let http = require('http');
let serveStatic = require('serve-static');
let finalhandler = require('finalhandler');
var port = process.env.PORT || 1337;
let serve = serveStatic(__dirname, { 'index': ['client.js'] });
let server = http.createServer(function (req, res) {
serve(req, res, finalhandler(req, res));
});
let io = socket(server);
server.listen(port);
io.on('connection', client => {
console.log('new user connected!', client.id);
client.on('hello', data => {
console.log('data: ', data);
});
client.on('disconnect', () => {
console.log('user disconnected', client.id);
});
});
Client
(function (plugin) {
plugin.socket = null;
function loadDependencies() {
head.js(
{ socket: 'https://cdn.socket.io/socket.io-1.4.5.js' }
);
head.ready('socket', function() {
plugin.socket = io('http://localhost:1337');
setSocketHandlers();
});
}
function setSocketHandlers() {
plugin.socket.on('my-event', function(data){
console.log('called my event');
});
}
plugin.init = () => {
loadDependencies();
}
}(this.WebTracker = this.WebTracker || {}));
WebTracker.init();

Why does my Node application keep sending data after every refresh?

I am using node.js and express.js to build a very simple application. I want to read the content of a directory and when I browse to localhost:3000/names, the application will print an array of the content to the web page except for the content that I choose not to. Here is my code:
const express = require('express');
const fs = require('fs');
const app = express();
const port = 3000;
let result = [];
app.get('/names', (req, res) => {
const printNames = (err, file) => {
file.forEach(e => {
if (e !== 'john') {
result.push(e);
}
});
res.send(result);
};
fs.readdir('./home', printNames);
});
app.listen(port, () => {
console.log('Listening on port 3000');
});
The application works the way that I wanted to, but there is a small bug. Every time I refresh the page, the application will add on the same content of the array to the existing array. My array keeps getting bigger with every refresh. I want the application to send the array to the page and will stay the same when I refresh. I do not have the slightest idea why my application is behaving this way. Can someone explain to me why it is behaving like this and what would be the right steps to fix this?
It is because you've declared your result array in the global scope.
Your result array is getting bigger and bigger every time.
Simply move the declaration to your route and you should be fine.
This should work fine:
const express = require('express');
const fs = require('fs');
const app = express();
const port = 3000;
// let result = []; Remove this line
app.get('/names', (req, res) => {
let result = []; // And add it here
const printNames = (err, file) => {
file.forEach(e => {
if (e !== 'john') {
result.push(e);
}
});
res.send(result);
};
fs.readdir('./home', printNames);
});
app.listen(port, () => {
console.log('Listening on port 3000');
});
Read more about scopes in JavaScript here:
https://www.w3schools.com/js/js_scope.asp
Every time you request to load the page /names, it is re-running the code in that handler. If you only want to run that script once, then move it outside of the handler, and only send the result.
let result = [];
const printNames = (err, file) => {
file.forEach(e => {
if (e !== 'john') {
result.push(e);
}
});
};
fs.readdir('./home', printNames);
app.get('/names', (req, res) => {
res.send(result)
});

Resources