How to write to CSV file in Javascript - javascript

I have a script (using PhantomJS) that tests how long it takes to load a webpage. What I am trying to figure out is how to write the result of time taken to load the page to a .csv file. Then if I were to re-run the test again for it to add another result to the .csv file.
code:
var page = require('webpage').create(),
system = require('system'),
t, address;
var pageLoadArray = [];
var csvContents = "";
fs = require('fs');
if (system.args.length === 1) {
console.log('Usage: loadspeed.js <some URL>');
phantom.exit(1);
} else {
t = Date.now();
address = system.args[1];
page.open(address, function (status) {
if (status !== 'success') {
console.log('FAIL to load the address');
}
else {
t = Date.now() - t;
console.log('Page title is ' + page.evaluate(function () {
return document.title;
}));
if(t>7000){
console.log('Loading time was too long... ' + t + "msec");
pageLoadArray.push(t);
console.log(pageLoadArray.length);
console.log(pageLoadArray[0]);
//store the time value to the .csv file
phantom.exit(1);
}
else{
console.log('Loading time ' + t + ' msec');
pageLoadArray.push(t);
console.log(pageLoadArray.length);
console.log(pageLoadArray[0]);
//store the time value to the .csv file
}
}
phantom.exit();
});
}

You can use the fs module with the write(path, content, mode) method in append mode.
var fs = require('fs');
fs.write(filepath, content, 'a');
where filepath is the file path as a string and content is a string containing your CSV line.
Something like:
address+";"+(new Date()).getTime()+";"+t

If you have control over the Jenkins environment, you can use one of the browser specific methods of triggering a download like suggested in This Question
function download(strData, strFileName, strMimeType) {
var D = document,
A = arguments,
a = D.createElement("a"),
d = A[0],
n = A[1],
t = A[2] || "text/plain";
//build download link:
a.href = "data:" + strMimeType + "charset=utf-8," + escape(strData);
if (window.MSBlobBuilder) { // IE10
var bb = new MSBlobBuilder();
bb.append(strData);
return navigator.msSaveBlob(bb, strFileName);
} /* end if(window.MSBlobBuilder) */
if ('download' in a) { //FF20, CH19
a.setAttribute("download", n);
a.innerHTML = "downloading...";
D.body.appendChild(a);
setTimeout(function() {
var e = D.createEvent("MouseEvents");
e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchEvent(e);
D.body.removeChild(a);
}, 66);
return true;
}; /* end if('download' in a) */
//do iframe dataURL download: (older W3)
var f = D.createElement("iframe");
D.body.appendChild(f);
f.src = "data:" + (A[2] ? A[2] : "application/octet-stream") + (window.btoa ? ";base64" : "") + "," + (window.btoa ? window.btoa : escape)(strData);
setTimeout(function() {
D.body.removeChild(f);
}, 333);
return true;
}
Maybe you can use this URL SCM Plugin to grab the download.
Or use Selenium to automate some things and grab the download file

Related

Use the page title as the screenshot file name in PhantomJS

The following PhantomJS code can be used to obtain page title <title> of a web page
var page = require('webpage').create();
page.open(url, function(status) {
var title = page.evaluate(function() {
return document.title;
});
console.log('Page title is ' + title);
phantom.exit();
});
The following PhantomJS code renders multiple URLs to png files.
// Render Multiple URLs to file
var RenderUrlsToFile, arrayOfUrls, system;
system = require("system");
/*
Render given urls
#param array of URLs to render
#param callbackPerUrl Function called after finishing each URL, including the last URL
#param callbackFinal Function called after finishing everything
*/
RenderUrlsToFile = function(urls, callbackPerUrl, callbackFinal) {
var getFilename, next, page, retrieve, urlIndex, webpage;
urlIndex = 0;
webpage = require("webpage");
page = null;
getFilename = function() {
return "rendermulti-" + urlIndex + ".png";
};
next = function(status, url, file) {
page.close();
callbackPerUrl(status, url, file);
return retrieve();
};
retrieve = function() {
var url;
if (urls.length > 0) {
url = urls.shift();
urlIndex++;
page = webpage.create();
page.viewportSize = {
width: 800,
height: 600
};
page.settings.userAgent = "Phantom.js bot";
return page.open("http://" + url, function(status) {
var file;
file = getFilename();
if (status === "success") {
return window.setTimeout((function() {
page.render(file);
return next(status, url, file);
}), 200);
} else {
return next(status, url, file);
}
});
} else {
return callbackFinal();
}
};
return retrieve();
};
arrayOfUrls = null;
if (system.args.length > 1) {
arrayOfUrls = Array.prototype.slice.call(system.args, 1);
} else {
console.log("Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]");
arrayOfUrls = ["www.google.com", "www.bbc.co.uk", "www.phantomjs.org"];
}
RenderUrlsToFile(arrayOfUrls, (function(status, url, file) {
if (status !== "success") {
return console.log("Unable to render '" + url + "'");
} else {
return console.log("Rendered '" + url + "' at '" + file + "'");
}
}), function() {
return phantom.exit();
});
The names of rendered files are in the format of "rendermulti-" + urlIndex + ".png" . But I want it to be page title+".png". How can I modify above code for my requirement.
Since page is global, you can easily change getFilename() in this way:
getFilename = function() {
var title = page.evaluate(function() {
return document.title;
});
return title + ".png";
};
You also don't need to access the page context (inside of page.evaluate()) to get the title. You can simply access page.title:
getFilename = function() {
return page.title + ".png";
};
It may be the case that the title contains characters that cannot appear in a directory or file. If it contains for example a/b, this will try write file b.png to directory a which of course doesn't exist.
Simply remove such characters:
return title.replace(/[\\\/:]/g, "_") + ".png";

How can I show with PhantomJS the url of the processed page in the generated PDF?

My goal was to generate a PDF from every page included in the sitemap of a website created with Rails. I'm using PhantomJS to get it. I'm quite new in this field, but I could do it, but when I was finished, I realized that it would be usable also to see at the beginning of every PDF the url of the page from which the PDF was generated, so I can browse quicker to the page (the site has over hundred pages).
Here is the Javascript:
// Render Sitemap to file
var RenderUrlsToFile, arrayOfUrls, system;
system = require("system");
/*
Render given urls
#param array of URLs to render
#param callbackPerUrl Function called after finishing each URL, including the last URL
#param callbackFinal Function called after finishing everything
*/
var getFileNumber = function(urlIndex) {
if (urlIndex <10) {
return "00" + urlIndex;
} else {
if (urlIndex <100) {
return "0" + urlIndex;
} else {
return urlIndex;
}
}
};
RenderUrlsToFile = function(urls, callbackPerUrl, callbackFinal) {
var getFilename, next, page, retrieve, urlIndex, webpage;
urlIndex = 0;
webpage = require("webpage");
page = null;
getFilename = function() {
return "rendermulti-" + getFileNumber(urlIndex) + ".pdf";
};
next = function(status, url, file) {
page.close();
callbackPerUrl(status, url, file);
return retrieve();
};
retrieve = function() {
var url;
if (urls.length > 0) {
url = urls.shift();
urlIndex++;
page = webpage.create();
page.viewportSize = {
width: 1920,
height: 1880
};
page.settings.userAgent = "Phantom.js bot";
return page.open(url, function(status) {
var file;
file = getFilename();
if (status === "success") {
return window.setTimeout((function() {
// !!!!!!!!!!!!! Doesn't work !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
page.evaluate(function() {
var x = document.getElementById("logoAndNavigation");
var newP = document.createElement("P")
var textnode = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname;
newP.appendChild(textnode)
x.insertBefore(newP, x.childNodes[0]);
});
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
page.render("tempPdfs/" + file);
return next(status, url, file);
}), 200);
} else {
return next(status, url, file);
}
});
} else {
return callbackFinal();
}
};
return retrieve();
};
// This makes an array with all the urls inside the sitemap
var arrayOfUrls = [''];
var page = require('webpage').create();
page.open('http://localhost:3000/sitemap.xml', function() {
var content = page.content;
parser = new DOMParser();
xmlDoc = parser.parseFromString(content,'text/xml');
var loc = xmlDoc.getElementsByTagName('loc');
for(var i=0; i < loc.length; i++)
{
var url=loc[i].textContent;
arrayOfUrls.push(url);
}
});
RenderUrlsToFile(arrayOfUrls, (function(status, url, file) {
if (status !== "success") {
return console.log("Unable to render '" + url + "'");
} else {
return console.log("Rendered '" + url + "' at '" + file + "'");
}
}), function() {
return phantom.exit();
});
I tried to solve the issue with the urls, with the code framed with the comment
// !!!!!!!!!!!!! Doesn't work !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I wanted to show the url inside an element of the page, that has the id #logoAndNavigation, but I get this error:
NOT_FOUND_ERR: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist.
If I use only a string like "hello" inside the variable textnode, it works, but not if I try to use the url of the page.
Can anyone please help me?
Thank you in advance!
appendChild expects a node not a string. You probably mean to use
var x = document.getElementById("logoAndNavigation");
var newP = document.createElement("p"); // small p
var textnode = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname;
newP.innerHTML = textnode; // this
x.insertBefore(newP, x.childNodes[0]);
You can also use the example of printheaderfooter.js to add the URL directly to the header or footer.

Runnig javascript files located on my server via node js command prompt

I want to configure an app that requires that I run node generate.js and node generate_texts_index.js on node's command prompt. These files are to build the data required for the app to work. When i run these files locally the app works in my browser. Now I have the same set of files located on my server, how can I run node generate.js when the files are on my server at www.example.com. I am new to node js. Thanks!
Here's what generate.js looks like
// MODULES
var fs = require('fs'),
path = require('path'),
bibleData = require('bible_data');
//console.log( bibleData.getBookInfoByUnboundCode('40N') );
//return;
// VARS
var
baseOutput = '../../app/content/texts/',
baseInput = 'input',
createIndex = true;
console.log('\r\r\r');
function convertFolder(inputPath) {
var infoFilePath = path.join(inputPath, 'info.json'),
startDate = new Date();
if (fs.existsSync(infoFilePath)) {
var info = JSON.parse( fs.readFileSync(infoFilePath, 'utf8') ),
generatorName = info.generator,
generator = require('generate_' + generatorName),
outputPath = path.join(baseOutput, info['id']),
indexOutputPath = path.join(outputPath, 'index');
console.log('-----');
console.log(info['name'], outputPath);
// remove existing data
if (fs.existsSync(outputPath)) {
var files = fs.readdirSync(outputPath);
// DELETE all files
files.forEach(function(data) {
var filePath = path.join(outputPath, data);
if (fs.statSync(filePath).isFile()) {
fs.unlinkSync(filePath);
}
});
} else {
fs.mkdirSync(outputPath);
}
// index data
if (createIndex) {
if (fs.existsSync(indexOutputPath)) {
var files = fs.readdirSync(indexOutputPath);
// DELETE all files
files.forEach(function(data) {
var filePath = path.join(indexOutputPath, data);
if (fs.statSync(filePath).isFile()) {
fs.unlinkSync(filePath);
}
});
} else {
fs.mkdirSync(indexOutputPath);
}
}
generator.generate(inputPath, outputPath, indexOutputPath, info, createIndex);
var endDate = new Date();
console.log('time: ' + MillisecondsToDuration(endDate - startDate));
}
}
function convertFolders() {
var files = fs.readdirSync(baseInput),
startDate = new Date();
// DO ALL
for (var f in files) {
var folder = files[f],
inputPath = path.join(baseInput, folder);
convertFolder(inputPath);
}
var endDate = new Date();
console.log('TOTAL: ' + MillisecondsToDuration(endDate - startDate));
}
function MillisecondsToDuration(n) {
var hms = "";
var dtm = new Date();
dtm.setTime(n);
var h = "000" + Math.floor(n / 3600000);
var m = "0" + dtm.getMinutes();
var s = "0" + dtm.getSeconds();
var cs = "0" + Math.round(dtm.getMilliseconds() / 10);
hms = h.substr(h.length-4) + ":" + m.substr(m.length-2) + ":";
hms += s.substr(s.length-2) + "." + cs.substr(cs.length-2);
return hms;
}
// START
// make /texts/ folder
if (!fs.existsSync(baseInput)) {
fs.mkdirSync(baseInput);
}
// process 1 or more folders
if (process.argv.length > 2) {
var folders = process.argv[2].split(',');
folders.forEach(function(folder) {
convertFolder(baseInput + '/' + folder);
});
} else {
convertFolders();
}
You need to run Node on your server.
Generally this would be done by using SSH to connect to the server and configuring it in the same way that you would for any other computer.
You won't be able to do this on low end hosting. You need to look at hosting that specifically advertises Node support, or a VPS or better.

mp3 file upload with phonegap on Windows RT [ Unicode Mapping error ]

I used phogap function for recording audio and uploading audio , file.
Audio File is recording and stored in music folder and I get the path and name of the file by the below function.
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
alert('over');
}
function captureAudio() {
navigator.device.capture.captureAudio(captureSuccess, captureError, { limit: 1, duration: 10 });
}
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
path = mediaFile.fullPath,
name = mediaFile.name;
temp = path; //Assigned path to GLOBAL VARIABLE
temp1 = name;
alert(temp);
}
I call the function to upload the created audio file.
function uplod() {
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = name;
options.mimeType = "audio/mpeg";
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(temp,
"http:/URL/upload.php",
function (result) {
alert("success" + result.bytesSent + result.responseCode);
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function (error) {
console.log('Error uploading file ' + recordingPath + ': ' + error.code);
},
options);
}
But on running, I get these error, got stucked up, is the error is with URL or PATH ? Unicode ? and path of file is like this
C:/Users/AB/Music/captureAudio (4).mp3
0x80070459 - JavaScript runtime error: No mapping for the Unicode character exists in the target multi-byte code page.
WinRT information: No mapping for the Unicode character exists in the target multi-byte code page.
I got the answer by using Ajax post and by using Formdata() to server there by getting in the form of arrays.

How to get all images from document and store to local

My goal is to get all images from document, then download all images bigger than 150x150px to local.
I'm stucked on retrieving files from URL i got on previous steps. Here is the buggy code line (full code - at the end):
...
var copyResult = fs.copy(imagesURLs[i], destFile);
...
When i run from console it just hangs up on fs.copy(), without any errors.
As i can understand, fs.copy() doesn't work with remote URLs, even if you set all proper args (--load-images=yes, --local-to-remote-url-access=yes). Am i right or there's something i did wrong with copy()? And are there any methods to get files directly from webkit's cache?
Got latest phantomjs version and ubuntu server.
I would be appreciate for any kind of help.
Full script code:
if (phantom.args.length < 1 || phantom.args.length > 2)
{
console.log('Usage: phantomjs ' + phantom.scriptName + ' <URL>');
phantom.exit();
}
else
{
var page = new WebPage(),
address = phantom.args[0];
page.viewportSize = { width: 1200, height: 4000 };
page.open(address, function (status)
{
if (status === 'success')
{
var imagesURLs = page.evaluate(function ()
{
var documentImages = [], imagesCount = document.images.length, index = 0;
while (index < imagesCount)
{
if ((document.images[index].width >= 150) && (document.images[index].height >= 150))
{
documentImages.push(document.images[index].src);
}
index++;
}
return documentImages;
});
var fs = require('fs');
for (var i in imagesURLs)
{
var fileName = imagesURLs[i].replace(/^.*[\\\/]/, '');
var destFile = '' + fs.workingDirectory + '/www/images/' + fileName;
console.log(destFile);
var copyResult = fs.copy(imagesURLs[i], destFile);
console.log(copyResult);
}
}
else
{
console.log('status: ' + status);
}
phantom.exit();
});
}
man try this.
function SaveAs(imgURL)
{
var oPop = window.open(imgURL,"","width=1, height=1, top=5000, left=5000");
for(;oPop.document.readyState != "complete"; )
{
if (oPop.document.readyState == "complete")break;
}
oPop.document.execCommand("SaveAs");
oPop.close();
}

Categories

Resources