selenium screenshots not saving specified directory - javascript

I have my selenium test set up to take screenshots, but they are not saving to the directory which I have specified. Can anybody show me what I am missing?
Here is how I am configuring the screenshots in the test:
function writeScreenshot(data, name) {
var fs = require('fs');
name = name || 'ss.png';
var screenshotPath = mkdirp(configuration.readSettings('screenshotDirectory') + fileNameURL + "/", function(err){});
fs.writeFileSync(screenshotPath + name, data, 'base64');
};
and then I take the screenshot:
driver.takeScreenshot().then(function(data) {
var screenshotFile = os + '_' + osVersion + '_' + browser + '_' + browserVersion + '.png';
writeScreenshot(data, screenshotFile);
});
The screenshots end up being saved instead in the projects root directory and with the file name preceded by 'undefined'. (ex. undefinedWindows_8_chrome_46.png)
It does, however, create the folders shown here: var screenshotPath = mkdirp(configuration.readSettings('screenshotDirectory') + fileNameURL + "/", function(err){});
So why is this happening?

mkdirp() is an async method. That is why you pass a callback. You will need to change your code to something like the following:
function writeScreenshot(data, name) {
var fs = require('fs');
name = name || 'ss.png';
var screenshotPath = configuration.readSettings('screenshotDirectory') + fileNameURL + "/";
mkdirp(screenshotPath, function(err){
if (err) {
// something else happened while creating the dir. You decide what to do
return;
}
// Otherwise (if dir was created)
fs.writeFileSync(screenshotPath + name, data, 'base64');
});
};

mkdirp() function is asynchronous - it creates a directory and returns nothing - this is why you having that leading undefined in the filename.
Save the file in the callback:
var screenshotPath = configuration.readSettings('screenshotDirectory') + fileNameURL + "/";
mkdirp(screenshotPath, function (err) {
if (!err) {
fs.writeFileSync(screenshotPath + name, data, 'base64');
} else {
// handle error
}
});
Or, synchronously create the directory and write to it this way:
var screenshotPath = configuration.readSettings('screenshotDirectory') + fileNameURL + "/";
if (mkdirp.sync(screenshotPath)) {
fs.writeFileSync(screenshotPath + name, data, 'base64');
}

Related

Using Node.js to upload S3 object to FTP server

I need a Node.js script that does the following:
1 - Triggers when an image is added to a specified S3 bucket.
2 - Creates a thumbnail of that image (360x203 pixels).
3 - Saves a copy of that thumbnail inside of a separate S3 folder.
4 - Uploads the thumbnail to a specified FTP server, SIX (6) times using a "FILENAME-X"naming convention.
The problem: I am not able to get the c.connect or c.append to work. I have tried about everything, and scoured the internet. It seems like it should work, but just doesn't.
Note: I removed my FTP credentials for privacy.
var async = require('async');
var AWS = require('aws-sdk');
var util = require('util');
var Client = require('ftp');
var fs = require('fs');
var gm = require('gm')
.subClass({ imageMagick: true }); // Enable ImageMagick integration.
// get reference to FTP client
var c = new Client();
// get reference to S3 client
var s3 = new AWS.S3();
exports.handler = function(event, context) {
// Read options from the event.
console.log("Reading options from event:\n", util.inspect(event, {depth: 5}));
// Get source bucket
var srcBucket = event.Records[0].s3.bucket.name;
// Get source object key
// Object key may have spaces or unicode non-ASCII characters.
var srcKey =
decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
var url = 'http://' + srcBucket + ".s3.amazonaws.com/" + srcKey;
// Set destination bucket
var dstBucket = srcBucket + "-thumbs";
// Set destination object key
var dstKey = "resized-" + srcKey;
// Infer the image type.
var typeMatch = srcKey.match(/\.([^.]*)$/);
if (!typeMatch) {
console.error('unable to infer image type for key ' + srcKey);
return;
}
var imageType = typeMatch[1];
if (imageType != "jpg" && imageType != "png") {
console.log('skipping non-image ' + srcKey);
return;
}
// Download the image from S3, transform, and upload to a different S3 bucket.
async.waterfall([
function download(next) {
// Download the image from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function transform(response, next) {
gm(response.Body).size(function(err, size) {
// Transform the image buffer in memory.
this.toBuffer(imageType, function(err, buffer) {
if (err) {
next(err);
} else {
next(null, response.ContentType, buffer);
}
});
});
},
function upload(contentType, data, next) {
// Connect to server
c.connect({
host: "localhost",
port: 21, // defaults to 21
user: "", // defaults to "anonymous"
password: "", // defaults to "#anonymous"
});
// Upload test file to FTP server
c.append(data, srcKey, function(err) {
console.log("CONNECTION SUCCESS!");
if (err) throw err;
c.end();
});
// Stream the thumb image to a different S3 bucket.
s3.putObject({
Bucket: dstBucket,
Key: dstKey,
Body: data,
ContentType: contentType
},
next);
}
], function (err) {
if (err) {
console.error(
'Unable to resize ' + srcBucket + '/' + srcKey +
' and upload to ' + dstBucket + '/' + dstKey +
' due to an error: ' + err
);
} else {
console.log(
'Successfully resized ' + srcBucket + '/' + srcKey +
' and uploaded to ' + dstBucket + '/' + dstKey
);
}
context.done();
}
);
};

Waiting for the end of a recursive readdir function

i'm using a recursive readdir to read the whole file tree of a directory to put it into a database.
My problem is that i'm trying to stop the next lines of code while the whole readdir / insert to the database isn't finished.
I was looking for a solution in promises but at the first call of my function (so in the first folder of the tree) the promise is fulfilled...
Any idea ?
function readsousdir(path, db, db2) {
var Datastore = require('nedb');
var fs = require('fs');
fs.readdir(path + '\\', function (err, files) {
files.forEach(function (file) {
fs.stat(path + '\\' + file, function (err, stats) {
var foldertrue = stats.isDirectory();
var filetrue = stats.isFile() == true;
if (foldertrue == true) {
var doc;
doc = folderdb(path + '\\' + file);
db2.insert(doc);
readsousdir(path + '\\' + file, db, db2);
}
if (filetrue) {
doc = pistedb(path + '\\' + file, []);
db.insert(doc);
}
});
});
});
}
Using BlueBird, you could use reduce:
var fs = Promise.promisifyAll(require("fs"));
function readsousdir(path, db, db2) {
var Datastore = require('nedb');
return fs.readdirAsync(path + '\\').reduce(function(_, file){
return fs.statAsync(path + '\\' + file)
.then(function(stats){
var foldertrue = stats.isDirectory();
var filetrue = stats.isFile() == true;
if (foldertrue == true) {
var doc;
doc = folderdb(path + '\\' + file);
db2.insert(doc);
return readsousdir(path + '\\' + file, db, db2)
}
if (filetrue) {
doc = pistedb(path + '\\' + file, []);
db.insert(doc);
}
});
});
}
Supposing your db library returns promises and you want to wait for the insertion, you would do
function readsousdir(path, db, db2) {
var Datastore = require('nedb');
return fs.readdirAsync(path + '\\').reduce(function(_, file){
return fs.statAsync(path + '\\' + file)
.then(function(stats){
var foldertrue = stats.isDirectory();
var filetrue = stats.isFile() == true;
if (foldertrue == true) {
var doc;
doc = folderdb(path + '\\' + file);
return db2.insert(doc).then(function(){
return readsousdir(path + '\\' + file, db, db2)
});
}
if (filetrue) {
doc = pistedb(path + '\\' + file, []);
return db.insert(doc);
}
});
});
}

fs writefile new line not working

i want log my user command
function saveLog (nick, command) {
var file = 'log/' + nick + '.log';
var datetime = '[' + getDateTime() + '] ';
var text = datetime + command + '\r\n';
fs.writeFile(file, text, function (err) {
if (err) return console.log(err);
console.log(text);
});
}
the function i made is fine, but
it didnt save the log in new line, its just replace text / rewrite the file.
whats im missing ?
thanks
fs.writeFile writes a WHOLE NEW file. What your are looking for is fs.appendFile which will make the file if it doesn't exist and append to it. Documentation here.
function saveLog (nick, command) {
var file = 'log/' + nick + '.log';
var datetime = '[' + getDateTime() + '] ';
var text = datetime + command + '\r\n';
fs.appendFile(file, text, function (err) {
if (err) return console.log(err);
console.log('successfully appended "' + text + '"');
});
}

How to download or upload files using javascript(Client side scripting)

I'm using the below code in javascript for downloading or uploading a file from network.
$(document).ready(function DirectoryCopy(sourceDirName, destDirName, copySubDirs, test) {
debugger;
try {
var dir = new System.IO.DirectoryInfo.ctor(sourceDirName);
var directory_stop = dir.get_Name();
var dirs = dir.GetDirectories();
if (!dir.get_Exists()) {
throw $CreateException(new System.IO.DirectoryNotFoundException.ctor$$String("Source directory does not exist or could not be found: " + sourceDirName), new Error());
}
if (!System.IO.Directory.Exists(destDirName)) {
System.IO.Directory.CreateDirectory$$String(destDirName);
}
if (test == true) {
System.IO.Directory.CreateDirectory$$String(destDirName + "\\" + "Complete");
}
var files = dir.GetFiles();
for (var $i2 = 0, $l2 = files.length, file = files[$i2]; $i2 < $l2; $i2++, file = files[$i2]) {
var temppath = System.IO.Path.Combine$$String$$String(destDirName, file.get_Name());
file.CopyTo$$String$$Boolean(temppath, true);
}
if (copySubDirs) {
for (var $i3 = 0, $l3 = dirs.length, subdir = dirs[$i3]; $i3 < $l3; $i3++, subdir = dirs[$i3]) {
var temppath = System.IO.Path.Combine$$String$$String(destDirName, subdir.get_Name());
DirectoryCopy(subdir.get_FullName(), temppath, copySubDirs, false);
}
return dirs.length;
}
return files.length;
}
catch (ex) {
var path = "d:\\tempnew\\MyTest.txt";
var sw = System.IO.File.CreateText(path);
try {
sw.WriteLine$$String(ex.toString());
}
finally {
sw.Dispose();
}
return 0;
}
});
But I am getting an error on
var dir = new System.IO.DirectoryInfo.ctor(sourceDirName);
as "System is not defined"
I'm passing values from code behind as shown below.
TextBox1.Text = #"\" + "\\10.66.3.82" + #"\" + "ipadqc" + #"\" + "IPAD Titles" + #"\" + JobName.Text + #"\" + Issue.Text;
string Macid = (string)(Session["Name"]);
string path = "D:" + #"\" + "Ipad Download" + #"\" + Macid + #"\" + Process.Text + #"\" + JobName.Text + #"\" + Issue.Text;
string a;
ClientScript.RegisterStartupScript(typeof(Page), "script", a = "DirectoryCopy('" + TextBox1.Text + "','"+path+"', true, true);", true);
please correct me if i'm wrong or please let me know if there is any better option to do it.
System.IO is a .Net thing, not a javascript thing.
For downloading files using JS, there are plenty or questions like this on Stack Overlow already. like this one
As far as uploading goes, the top answer on this question pretty much sums it up.

Node js : TypeError: Object #<Object> has no method 'existsSync'

I need to upload file and I am using node js in server(version : [nodemon] v1.0.1). The following code worked before 4 months after that I did n't check it and yesterday I run it again. But it is not working and I got "TypeError: Object #<Object> has no method 'existsSync'" error in console. Following is my code
var express = require('express');
var path = require('path');
var app = module.exports = express();
var calenderid;
var EventEmitter = require('events').EventEmitter, https = require('https'), http = require('http'), querystring = require('querystring'), url = require('url');
var path2;
app.configure(function() {
app.use(express.compress());
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.cookieParser());
app.use(express.session({
secret : 'foobar'
}));
app.use(express.bodyParser({
uploadDir : __dirname + '/uploads'
}));
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
var http = require('http');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : '3306',
database : 'db',
user : 'root',
password : '',
});
connection.connect();
var fs = require('fs');
app.post('/file-upload/:id', function(req, res) {
var tble = "image";
var id = req.params.id;
console.log("req.files.files" + JSON.stringify(req.files),
req.files.files.length);
var tmp_path = req.files.files[0].path;
console.log("hiii temp path" + tmp_path, typeof tmp_path);
// var firstIdx =0
var lastidx = tmp_path.lastIndexOf("/");
var path = tmp_path.substring(0, lastidx);
console.log("target path sub" + lastidx, tmp_path);
// var target_path = path+"\"+req.files.files[0].name;
var dirExists = fs.existsSync(__dirname + "/uploads/" + id);
console.log(dirExists);
if (!dirExists) {
fs.mkdirSync(__dirname + "/uploads/" + id);
target_path = path + "/" + id + "/" + req.files.files[0].name;
} else {
target_path = path + "/" + id + "/" + req.files.files[0].name;
}
console.log("hiii target_path" + target_path);
fs.rename(tmp_path, target_path, function(err) {
if (err)
throw err;
// delete the temporary file, so that the explicitly set temporary
// upload dir does not get filled with unwanted files
fs.unlink(tmp_path, function() {
if (err)
throw err;
// res.send('File uploaded to: ' + target_path + ' - ' +
// req.files.files[0].size + ' bytes'+req.files.files.length);
// queryurl = 'SELECT * FROM ' +tble + ' WHERE ' + id;
queryurl = 'SELECT * FROM ' + tble + ' WHERE image=' + '"'
+ req.files.files[0].name + '"' + ' AND branch=' + '"' + id
+ '"';
connection.query(queryurl, function(err, result, fields) {
console.log(JSON.stringify(result) + "result.image");
if (result.length == 0) {
console.log("in if !result");
connection.query('INSERT INTO ' + tble + '(' + 'branch'
+ ',' + 'image' + ')' + 'VALUES' + '(' + '"' + id
+ '"' + ',' + '"' + req.files.files[0].name + '"'
+ ")", function(err, result, fields) {
if (err)
throw err;
else {
res.send('File uploaded to: ' + target_path + ' - '
+ req.files.files[0].size + ' bytes'
+ req.files.files.length);
}
});
} else {
console.log("in else !result");
res.send("duplicate");
}
});
});
});
});
Following is the error that I got from console.
TypeError: Object #<Object> has no method 'existsSync'
at /var/www/jts-web/WebContent/app.js:95:20
at callbacks (/var/www/web/WebContent/node_modules/express/lib/router/index.js:165:11)
at param (/var/www/web/WebContent/node_modules/express/lib/router/index.js:139:11)
at param (/var/www/web/WebContent/node_modules/express/lib/router/index.js:136:11)
at pass (/var/www/web/WebContent/node_modules/express/lib/router/index.js:146:5)
at Router._dispatch (/var/www/web/WebContent/node_modules/express/lib/router/index.js:173:5)
at Object.router [as handle] (/var/www/web/WebContent/node_modules/express/lib/router/index.js:33:10)
at next (/var/www/web/WebContent/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at Object.methodOverride [as handle] (/var/www/web/WebContent/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js:37:5)
at next (/var/www/web/WebContent/node_modules/express/node_modules/connect/lib/proto.js:190:15)
In one site somebody told it will overcome after upgrading node js. But this code was working fine. It is not good if I need to upgrade for each change.
I solved this issue by adding the following code
fs.existsSync = require('path').existsSync;
above
var dirExists = fs.existsSync(__dirname + "/uploads/" + id);
I got solution from this site
As a side note, as I encountered somewhat *similar* issue but on different scenario.
I tried to run grunt for bootstrap.
Here is the error I got:
/home/user/gbootstrap/node_modules/grunt/lib/grunt/file.js:374
return fs.existsSync(filepath);
^
TypeError: Object #<Object> has no method 'existsSync'
at Object.exists (/home/user/gbootstrap/node_modules/grunt/lib/grunt/file.js:374:13)
at Task.init (/home/user/gbootstrap/node_modules/grunt/lib/grunt/task.js:423:31)
at Object.initTasks (/home/user/gbootstrap/node_modules/grunt/lib/grunt/help.js:90:14)
at /home/user/gbootstrap/node_modules/grunt/lib/grunt/help.js:49:55
at Array.forEach (native)
at Object.display (/home/user/gbootstrap/node_modules/grunt/lib/grunt/help.js:49:17)
at Object.tasks (/home/user/gbootstrap/node_modules/grunt/lib/grunt.js:101:10)
at Object.cli (/home/user/gbootstrap/node_modules/grunt/lib/grunt/cli.js:38:9)
at Object.<anonymous> (/home/user/gnode-v0.10.26-linux-x86/lib/node_modules/grunt-cli/bin/grunt:45:20)
at Module._compile (module.js:446:26)
I found the root cause was due to i am using the default debian nodejs package (version 0.6.19) from repository.
Solution:
1. remove the nodejs:
sudo apt-get remove nodejs
2. download the binary from http://nodejs.org/download/
3. use the correct node and npm from the bin folder. Then it runs...
credit to this post:
https://github.com/Crisu83/yii-app/issues/13
Make sure you load the core fs module at the top of this file like var fs = require("fs");. Other that that, existsSync should be there.
Side note: You can't use synchronous IO calls in a network server such as this. It completely destroys node's concurrency model at a basic and fundamental level. Use the async versions. You're already using some of them, just use async version exclusively and you'll be noding correctly.

Categories