phantomjs+ mocha + node + opening a web page - node.js

I'm trying to do something very simple. Or so I thought.
All I want to do is use phantomjs to open a webpage and assert its title.
I'm using mocha-phantomjs to invoke my test runner that looks like:
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../node_modules/mocha/mocha.css" />
</head>
<body>
<div id="mocha"></div>
<script src="../../node_modules/mocha/mocha.js"></script>
<script src="../../node_modules/chai/chai.js"></script>
<script>
mocha.ui('bdd');
mocha.reporter('html');
</script>
<script src="test.js"></script>
<script>
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
else { mocha.run(); }
</script>
</body>
</html>
and my test file looks
(function() {
var page, url;
page = require('webpage');
page = webpage.create();
url = "http://localhost:3000";
page.open(url, function(status) {
var ua;
if (status !== "success") {
return console.log("Unable to access network");
} else {
ua = page.evaluate(function() {
return document.title.should.equal('blah');
});
phantom.exit();
}
});
describe('Sanity test', function() {
return it('true should be true', function() {
return true.should.equal(true);
});
});
}).call(this);
when run using mocha-phantomjs it complains that it doesn't know what require is but i need to require the webpage.
How can I solve this?

You might want to do it with casper.js, it's easier:
casper.test.begin('my test', function suite(test) {
casper.start("your url", function() {
test.assertTitle("expected title");
});
casper.run(function() {
test.done();
});
});

Related

response.writeHead(302) in NodeJS not redirecting in async function callback

Below is a snippet of my NodeJS server code.
async function handleLoginReq(req, res) {
let queryDB = `
SELECT password FROM faculty_information
WHERE email='${userInfo["user-email"]}';
`;
try {
const dbres = await client.query(queryDB);
if (dbres.rows.length !== 0) {
if (dbres.rows[0].password === '') {
const errVal = 'Please register yourself correctly';
res.writeHead(302, {
'Location': `/login_page/loginPage.html?error=${encodeURIComponent(errVal)}`
});
res.end();
client.end();
} else if (userInfo["user-password"] === dbres.rows[0].password) {
res.writeHead(302, {
'Location': '/experiment_page/index.html'
});
res.end();
client.end();
} else {
const errVal = 'Incorrect password or email address';
res.writeHead(302, {
'Location': `/login_page/loginPage.html?error=${encodeURIComponent(errVal)}`
});
res.end();
client.end();
}
} else {
const errVal = 'Please sign up';
console.log(errVal);
res.statusCode(302);
res.setHeader('Location', `/login_page/loginPage.html?error=${encodeURIComponent(errVal)}`)
//res.writeHead(302, { 'Location': `/login_page/loginPage.html?error=${encodeURIComponent(errVal)}` });
res.end();
client.end();
}
} catch (err) {
res.writeHead(500);
res.end("Internal server error");
client.end();
}
}
handleLoginReq(req, res);
The client.query() function is a asynchronous function. However, none of the res.writeHead(302)'s are working inside the callback of this function. A res.writeHead(302) does work if I add it below the function call of handleLoginReq(req, res);.
handleLoginReq(req, res);
// Below redirect works
res.writeHead(302, { 'Location': '/experiment_page/index.html' });
res.end();
The above code runs when a form is submitted on /login_page/loginPage.html.
Instead of redirecting the user to either /experiment_page/index.html or back to /login_page/loginPage.html?error=something with a URL parameter, it just reloads the page to /login_page/loginPage.html.
Below is the HTML for this page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/login_page/css/loginStyles.css">
<script src="/login_page/js/labelChange.js" defer></script>
<script src="/login_page/js/redirectSignUp.js" defer></script>
<script src="/login_page/js/loginValidation.js" defer></script>
<title>DigiChit - The Online Chit System | Login</title>
</head>
<body>
<nav class="navbar">
<ul>
<li><h1>DigiChit</h1></li>
<li>Home</li>
<li>About</li>
</ul>
</nav>
<div class="login-info">
<form method="POST" class="form">
<img src="/images/avatar.png" id="avatar" alt="avatar">
<h2>Login</h2>
<div class="input-group">
<input type="email" name="user-email" id="user-email" required>
<label for="user-email">Email</label>
<span id="email-error"></span>
</div>
<div class="input-group">
<input type="password" name="user-password" id="user-password" required>
<label for="user-password">Password</label>
<span id="general-error"></span>
<button type="submit" class="submit-btn" id="login-button">Login</button>
<button type="submit" class="submit-btn" id="sign-up">SignUp</button>
Forgot Password?
</div>
</form>
</div>
</body>
</html>
None of the client side JS scripts are interfering with the process either. I did put console.log()'s in all of the other conditions, and there are no clashes either where many res.writeHead() are running simultaneously.
If anyone can find why this is happening?
I tried to use res.setHeader() and res.statusCode() instead of res.writeHead() to see if anything changed, and nothing happened. I tried using promises instead of async/await and that changed nothing either.
###################################
EDIT (Updated with async/await syntax)
###################################
Here is the server code snippet containing more info on where the function is located.
const server = https.createServer(options, async function (req, res) {
// For form submissions
if (req.method.toLowerCase() === "post") {
let body = '';
req.on("data", (chunk) => {
body += chunk.toString();
})
req.on("end", async function () {
// querystring.decode converts browser query string into an object
const userInfo = querystring.decode(body); // userInfo is an object here
// Status code 302 stands for code of redirection
if (req.url.startsWith("/login_page/loginPage.html")) {
const client = createClient();
await client.connect();
let errVal = "";
async function handleLoginReq(req, res) {
// Below is the query to get user password
let dbQuery = `
SELECT password FROM faculty_information
WHERE email='${userInfo["user-email"]}';
`;
try {
const dbres = await client.query(dbQuery);
if (dbres.rows.length !== 0) {
if (dbres.rows[0].password === '') {
const errVal = 'Please register yourself correctly';
res.writeHead(302, { 'Location': `/login_page/loginPage.html?error=${encodeURIComponent(errVal)}` });
res.end();
client.end();
} else if (userInfo["user-password"] === dbres.rows[0].password) {
res.writeHead(302, { 'Location': '/experiment_page/index.html' });
res.end();
client.end();
} else {
const errVal = 'Incorrect password or email address';
res.writeHead(302, { 'Location': `/login_page/loginPage.html?error=${encodeURIComponent(errVal)}` });
res.end();
client.end();
}
} else {
const errVal = 'Please sign up';
console.log(errVal);
res.writeHead(302, { 'Location': `/login_page/loginPage.html?error=${encodeURIComponent(errVal)}` });
res.end();
client.end();
}
} catch (err) {
res.writeHead(500);
res.end("Internal server error");
client.end();
}
}
await handleLoginReq(req, res);

Axios GET request got error, but I see response in browser

Trying to make VUE application with backend on Node.JS. But the simplest code doesn't work.
My backend:
const HTTPServer = require("http")
server = HTTPServer.createServer((req, res) => {
console.log(req.url)
console.log(req.method)
res.write('Hello world!')
res.end()
})
server.listen(3000, () => {
console.log('Server is up')
})
My frontend:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://unpkg.com/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/axios#0.12.0/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<title>Get test</title>
</head>
<body>
<div id="app">
<div>
<button class="btn" #click="btn_pressed">Send GET request</button>
</div>
<div> {{comment}}</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
comment: ''
},
methods: {
btn_pressed: function () {
axios
.get('http://localhost:3000')
.then(response => {
this.comment = 'Response is ' + response.data
})
.catch(error => {
this.comment = 'The error is ' + error
})
}
}
})
</script>
</body>
</html>
I see the correct response in Network activity in Chrome, but get "Network error" in the code.
You can tried something just like this:
<script>
var app = new Vue({
el: '#app',
data: {
comment: ''
},
mounted() {
this.btn_pressed()
},
methods: {
btn_pressed() {
axios.get('/')
.then(res => {
this.comment = 'Response is ' + res.data
})
.catch(err => {
this.comment = 'The error is ' + err
})
}
}
})

how to live stream data from a mongodb which get updated frequently without refreshing the page in nodejs

app.post('/databykey', function(req, res) {
var api = req.body.api;
console.log(api);
push.getdata(api, function(err, data) {
if (err) {
console.log(err);
} else {
var sample = [];
for (i = 0; i < data.length; i++) {
sample[i] = data[i].id
}
console.log(sample);
res.render('data', {
'data': sample
});
}
})
})
This is my source code. I am fetching the data from the mongodb which get updated frequently.How do i render the updated data to the front end without refreshing the browser
You can use a lot of frameworks for the front end job and each has a method for this. Simply you can use jQuery something like this by sending ajax every 2sec for example:
<html>
<head>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
(function loaddata()
{
$.ajax({
type: 'post',
url: 'server address/databykey',
data: {
api: 'some data'
},
success: function (response) {
$( '#display_info' ).html(response);
}
});
}
setInterval(loaddata, 2000);
})();
</script>
</head>
<body>
<div id="display_info" >
</div>
</body>
</html>

Testing chrome extension - require error

I have this gulp task:
gulp.task('test', function () {
return gulp.src('test/runner.html')
.pipe(mochaPhantomJS());
});
This is my runner.html:
<!DOCTYPE html>
<html>
<head>
<title>Mocha</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
</head>
<body>
<script src="../node_modules/mocha/mocha.js"></script>
<script>mocha.setup('bdd')</script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/requirejs/require.js"></script>
<script>
var assert = chai.assert;
var expect = chai.expect;
var should = chai.should();
</script>
<script src="spec/test.js"></script>
<script>
if (window.mochaPhantomJS) {
console.log('Running mochaPhantomJS...');
mochaPhantomJS.run();
} else {
console.log('Running mocha...');
mocha.run();
}
</script>
</body>
</html>
And here is my test.js file:
var chrome = require('sinon-chrome');
var popup = require('../../source/scripts/popup');
describe('sumit', function(){
before(function () {
global.chrome = chrome;
});
it('Should return 1', function(){
assert(popup.sum(0,1) === 1);
});
})
But when I run gulp test I get this error message:
Error: Module name "sinon-chrome" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
in defaultOnError at
file:///c:/dev/extensions/NEW_EXPRESS/node_modules/requirejs/require.js:1
in onError at
file:///c:/dev/extensions/NEW_EXPRESS/node_modules/requirejs/require.js:547
in localRequire at
file:///c:/dev/extensions/NEW_EXPRESS/node_modules/requirejs/require.js:1433
in requirejs at
file:///c:/dev/extensions/NEW_EXPRESS/node_modules/requirejs/require.js:1794
In the link in the error message, it implies you should use the async require method.
So if you update test.js to the following, then it should solve that issue:
require(['sinon-chrome'], function (chrome) {
var popup = require('../../source/scripts/popup');
describe('sumit', function(){
before(function () {
global.chrome = chrome;
});
it('Should return 1', function(){
assert(popup.sum(0,1) === 1);
});
})
});
In an Angular 7 build you can do this.
Karma.config:
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage'),
reports: ['html', 'lcovonly'],
fixWebpackSourcePaths: true
},
reporters: ['kjhtml', 'progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
and in your tests:
import * as chrome from 'sinon-chrome';
import {MyService} from '../my.service';
describe('RunTaskService', () => {
beforeEach(() => {
TestBed.configureTestingModule({});
(global as any).chrome = chrome;
});
it('should be start a task', done => {
const service: MyService = TestBed.get(MyService);
expect(service).toBeTruthy();
chrome.runtime.lastError = null;
chrome.tabs.query.yields([{url: 'https://cnn.com', id: 123}]);
// call your code to test. the chrome.tabs.query will
// return [{url: 'https://cnn.com', id: 123}]
});

In response.write() TypeError: First argument must be string or Buffer

I have created a server in Node and I am calling fb.html through it. Now when I visit http://localhost:8081/ I keep on getting the following error:
http://oi67.tinypic.com/rkde9d.jpg
// server.js
var http = require("http");
var fs = require("fs");
http.createServer(function (request, response) {
// Send the HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
fs.readFile("fb.html","utf8", function(err, data){
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(data.toString());
response.end();
});
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
// fb.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
</head>
<body>
<script>
var acces_token, object_id=null,id;
// initialize and setup facebook js sdk
window.fbAsyncInit = function() {
FB.init({
appId : 'myappID',
xfbml : true,
version : 'v2.6'
});
};
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// function to login to facebook
function myFBLogin() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
alert("You are already logged in!");
}
else{
FB.login(function(response){
// user is now logged in
console.log(response);
acces_token=response.authResponse.accessToken;
}, {scope: 'publish_actions' , scope:'user_posts' });
}
});
}
// function to logout
function myFBLogout(){
FB.getLoginStatus(function(response) {
if (response.status === 'unknown') {
alert("You are already logged out!");
}
else{
console.log(response);
FB.logout(function(response) {
// user is now logged out
alert("You are successfully Logged Out!");
acces_token=null;
if(object_id==null)
document.getElementById('status').innerHTML="Post ID is unknown";
else
document.getElementById('status').innerHTML="You are logged out";
});
}
});
}
// function to post an image on wall
function myFacebookPost()
{
FB.api("/me/photos",
'post',
{url: document.getElementById("frm1").elements[0].value},
function (response){
console.log(response);
if(response.error){
if(response.error.code==2500)
{
alert("You are not logged in!");
}
else if(response.error.code==1)
{
alert("Image url is not correct!");
}
else if(document.getElementById("frm1").elements[0].value=="") alert("Enter the URL!");
}
else{
id=response.post_id;
object_id=response.id;
document.getElementById('status').innerHTML=0;
}
}
);
}
//function to count number of likes
function like_count(){
var a=FB.getAuthResponse();
FB.api(
"/"+object_id+"/likes",
'get',
function (response) {
console.log(response);
if(response.error){
if(object_id==null)
{
alert("Object ID is not defined. First create a post!");
}
else if(response.error)
{
alert("You are not logged in!");
}
}
else
document.getElementById('status').innerHTML=response.data.length;
}
);
}
</script>
<button onclick="myFBLogin()">Login to Facebook</button>
<button onclick="myFBLogout()">Logout</button><br><br>
<form id="frm1" action="javascript:myFacebookPost()">
Image URL: <input type="text" name="URL" placeholder="Enter the image url" >
<input type="submit" value="Post Image on Wall" style="display: inline">
</form>
<br>
<button onclick="like_count()" >Likes count</button>
<p style="display: inline">   Likes Count =  </p>
<div id="status" style="display: inline"> Post ID is unknown</div>
</body>
</html>
Please help to find the problem. Well I have that if works fine on systems while on others it raises the above error.

Resources