selenium + nodejs + nightwatchjs and phantomjs for pdf printing after logged in - node.js

I'm still new with selenium and nodejs so please help me out here...
I have already set up the code for logging in into a site with nodejs
after successfully logged in, i have to print a page to pdf with phantom.js
browser.waitForElementPresent('#username', 1000, function() {
browser.setValue('#username', 'some_username');
browser.setValue('#password', 'some_password');
browser.click('input[type="button"]');
browser.waitForElementPresent('#agreeCB1', 15000, function() {
browser.click('#agreeCB1');
var phantom = require('phantom');
phantom.create().then(function(ph) {
ph.paperSize = {
format: 'A4'
};
ph.createPage().then(function(page) {
page.open("https://www.example.com/myaccount").then(function(status) {
page.render('./reports/myaccount.pdf').then(function() {
console.log('Page Rendered');
ph.exit();
});
});
});
});
These code suppose to print the page(myaccount page) after successful logged in but it prints the login page instead e.g. https://www.example.com/loginpage
Maybe because phantomjs creates another browser session? How can I combine these phantomjs code to existing logging code above?
Thanks for all your time!

Related

NodeJS Express Routing - Only first request gets rendered

In the server script I try to deliver different html files. When app.post('/login'...) comes in, res.sendFile() is working and the html gets rendered. On the second call, whenn app.get('/go') comes in, the file gets served, but not displayed. I cannot explain why the second HTML file is not displayed. What am I doing wrong?
the second request comes from a fetch request in a javascript
socket.on('gameStarted', (data) => {
console.log("Game started");
fetch('/go', {method: 'GET'});
})
served but not displayed
app.post('/login', async (req, res, next) => {
var roomNR = req.body.player.gameCode;
var playerName = req.body.player.nickname;
var codeValid = await checkCode(activeRoomsCollection, gameCodes, roomNR);
var playerExists = await playerCollection.findOne({ playerName: playerName })
if (codeValid) {
if ((playerExists === null) || !playerExists) {
playerCollection.insertOne({ room: roomNR, playerName: playerName, state: false });
console.log(`Added player '${playerName}' with roomnumber '${roomNR}'`);
res.sendFile(path.join(__dirname + '/../../public/lobby.html'), function (err) {
if (err) {
console.log(err);
res.status(err.status).end();
}
else {
console.log('Sent Lobby');
}
});
} else {
// updateDomElement(player, elementId, data)
//res.send('Benutzername existiert bereits');
}
} else {
res.send('Code ungültig');
}
});
app.get('/go', (req, res, next ) => {
res.sendFile(path.join(__dirname + '/../../public/raetsel1.html'), function (err) {
if (err) {
console.log(err);
res.status(err.status).end();
}
else {
console.log('Sent Raetsel1');
}
});
});
fetch() never displays anything on its own. It's a way for your Javsascript to issue http requests to remote servers and those servers then return content back to your Javascript. The result from those http requests ONLY goes to your Javascript. Nothing in the view of the page is affected at all by a fetch() call.
If you want the result of a fetch() call to display something in your page, you would need to write Javascript to do that (to insert content into the current page).
If, instead, you just want the browser to go to a new page, then change from this:
fetch('/go', {method: 'GET'});
to this:
window.location = "/go";
This will cause the browser to go to the URL, retrieve the content and display it. This will shut-down the current page and load and display a new page and the URL in the URL-bar in the browser will show the updated location.
Note that if you have socket.io code in both pages, it will disconnect the current socket.io connection and then run the Javascript in the new page - causing it to create a new socket.io connection (if you have code in the new page to do that) as that is what happens to socket.io connections when you load and display a new web page in the browser.

PhantomJS execute javascript in <Body> tag

I am trying to scrape the below mentioned URL and trying to extract the link in the tag,using PhantomJS.
The link sends back javascript code which is executed on the browser to form the HTML inside the Body.
The problem is PhantomJS is not executing the Javascript and I am getting the unfinished HTML after executing my code.
Index.js
var page = require('webpage').create();
console.log('The default user agent is ' + page.settings.userAgent);
page.settings.userAgent = 'SpecialAgent';
page.open('http://videohost.site/play/A11QStEaNdVZfvV/', function(status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var html = page.evaluate(function() {
return document.getElementsByTagName('body')[0].innerHTML;
});
console.log(html);
}
phantom.exit();
});
I execute it using phantomjs index.js in the console t check the HTML.
Any help regarding how would the script inside the would be executed would be much appreciated.
Update:
works with NightMareJS as according to Vaviloff's suggestion.
app.get('/scrape', function (req, res) {
//All the web scraping magic will happen here
console.log('Scrape')
url = 'http://videohost.site/play/A11QStEaNdVZfvV/'
nightmare
.goto(url)
.evaluate(function(){
return document.body.innerHTML; //pass all of the html as text
})
.end()
.then(function (document) {
console.log(document)
})
.catch(function (error) {
console.error('Search failed:', error);
})
res.send('Woohoo')
})
app.listen('8081')
console.log('Magic happens on port 8081');
exports = module.exports = app;

How to append to variable within http.get? (Node.JS)

var content = 'Hi, welcome to my webpage.';
var options = {host: 'www.website.com', path: '/folder/song.mp3', agent:false};
http.get(options, function(r) {
r.on('data', function() {
if (r.statusCode !== '404') {
content += 'Download';
}
});
});
fs.writeFile('index.html', content);
So normally, if I want to write a static html webpage from a node.js script, this works perfectly. For some reason, however, if I try to append to content from within http.get, it doesn't work. The whole point is to check if the file/page exists from an external website, and if it does then to display a link to it. The code that checks for the existing file works just fine, but I can't append anything to an external variable it seems. Any help would be much appreciated.
You need to use end event of http to indicate when you finish receiving data.
As node is asynchronouse the fs.writeFile instruction is run before all your data is received.
Here's how you can do it:
http.get(options, function(r) {
r.on('data', function() {
if (r.statusCode !== '404') {
content += 'Download';
}
});
r.on('end', function() {
fs.writeFile('index.html', content);
});
});

How can I receive message from onClick event of web page using chrome extension?

I want to catch click event from injected script on all tabs of chrome browser.
like below method
event.js is main javascript and test.js is injected js.
event.js
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) {
if (changeInfo.status === 'complete') {
chrome.tabs.executeScript(tabId, { file: 'test.js'}, function(){
console.log('executed');
});
}
});
test.js
var fragment = create('<div onClick="sendMessage to my extension">Hellow</div>');
document.body.insertBefore(fragment, document.body.childNodes[0]);
how can I receive message from other website to my extenstion?
Is it impossible?
Thanks for reading.
Assuming you are properly injecting test.js as a content script (e.g. by declaring the appropriate properties in your manifest.json), you need to make the following modifications:
In event.js add:
chrome.runtime.onMessage.addListener(function(msg, sender) {
console.log('Tab with ID ' + sender.tab.id + ' sent a message:\n' + msg.text);
});
In test.js replace your code with:
var mydiv = document.createElement('div');
mydiv.textContent = 'Hello';
mydiv.addEventListener('click', function() {
chrome.runtime.sendMessage({ text: 'Someone clicked my DIV !' });
});
document.body.insertBefore(mydiv, document.body.childNodes[0]);

Requiring PhantomJS within a Mocha test

I'm trying to get off the ground with mocha-phantomjs and I seem to be hitting a snag with regards to require. I was hoping other sets of eyes can see what I'm doing wrong.
$ mocha-phantomjs test/index.html
My Site
1) server should be running
Error: Script error for: webpage
http://requirejs.org/docs/errors.html#scripterror
The files in question are fairly small:
https://gist.github.com/cobaltroad/6675855
Here's the spec script in particular:
test.spec.js
describe("My Site", function() {
it("server should be running", function(done) {
require(['webpage'], function(webpage) {
var page = webpage.create();
page.open("http://localhost:8080/", function() {
var title = page.evaluate(function () {
return document.title;
});
title.should.eql('My Title');
console.log("Title: " + title);
phantom.exit();
done();
});
});
}); // server should be running
});
I've tried various forms of define/require and I haven't been able to get it quite right.

Resources