Hi I am writing automation tests for a Cordova application.
I want to save screenshots of each page, here is my code.
it("should take screenshot", function() {
return browser.contexts().then(function(cnt){
console.log(cnt[1]);
return browser.context(cnt[1]);
}).then(function(){
return browser.saveScreenshot("/Users/User/Documents/dev/engineerappcopy/VGimages/nexLogin.png")
});
});
Here is my Appium console:
[HTTP] --> GET /wd/hub/session/610d95af-6501-4c72-ac38-0184a8608dfd/screenshot {}
[MJSONWP] Driver proxy active, passing request on via HTTP proxy
[JSONWP Proxy] Proxying [GET /wd/hub/session/610d95af-6501-4c72-ac38-0184a8608dfd/screenshot] to [GET http://127.0.0.1:9515/wd/hub/session/4d5f3f8a24e28f7fbf65eebc47cc02d8/screenshot] with body: {}
[HTTP] --> GET /wd/hub/status {}
[MJSONWP] Calling AppiumDriver.getStatus() with args: []
[MJSONWP] Responding to client with driver.getStatus() result: {"build":{"version":"1.5.3"...
[HTTP] <-- GET /wd/hub/status 200 14 ms - 83
Im new to automation and JS, thanks for any advice.
It turns out savescreenshot(), is not compatible with cordova applications.
However I did find a solution!
Using these commands we can take a screen shot directly from the emulator:
adb pull /sdcard/screenshot.png screenshot.png
adb shell /system/bin/screencap -p /sdcard/screenshot.png
So how can we do this programmatically?
well nodeJS has 'child_process' which can call commands to the terminal!
it("should take screenshot", function() {
const exec = require('child_process').exec;
exec('adb shell /system/bin/screencap -p /sdcard/tester.png', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
exec('adb pull /sdcard/tester.png tester.png', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
});
So using something like this ^, I can take a screenshot that is saved to the emulators sd card, and then pull this screenshot onto my directory!
Related
I have this code written and want to run my hello.sh file from my node. it fails the error is
error: Command failed: ./hello.sh > output.txt
/bin/sh: 1: cannot create output.txt: Permission denied
How can I change the permission of hello.sh file to executable.
fs.chmod("hello.sh",0o777,(err)=>{
if(err){
console.log(err)
return
}
})
exec("./hello.sh > output.txt", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
When creating output files, first create them in /tmp to avoid these kind of issues. Then move them to where they need to go, re-read them to stream them async, etc.
Try like this :
fs.chmod("hello.sh",0o777,(err)=>{
if(err){
console.log(err);
return;
}
exec("./hello.sh > output.txt", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
});
You also need to make sure that the directory where hello.sh is running is writable.
Because the executed command is: hello.sh > output.txt
As the error message is: cannot create output.txt: Permission denied
it must not be writable.
Chmod the directory that contain hello.sh to make it writable, or change your exec command to: ./hello.sh > /tmp/output.txt
I tried to execute a nodejs command inside electron.
const { execFile } = require('child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
That one above is fine! And give an output nicely.
But then once i execute :
npm install --global --save speed-test
under one of my Electron App.
And try to execute a different command such as:
const { execFile } = require('child_process');
const child = execFile('speed-test', null, (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
it gaves me an error:
Uncaught Error: spawn speed-test ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:264)
at onErrorNT (internal/child_process.js:456)
at processTicksAndRejections (internal/process/task_queues.js:80)
The more interesting part is that, If i execute the command itself under CommandPrompt of Nodejs, it's perfect! So... i'm confused.
What the things that i need to modify under the Electron App anyway?
Here is my code:
test.js
const {exec} = require("child_process")
var c = exec("php artisan serve", {
cwd: "C:/Users/DELL/Laravel Projects/lktest3"
}, (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
})
setTimeout(() => {
c.kill('SIGHUP')
}, 10000);
When I run node test.js, I get this error:
$ node test.js
internal/child_process.js:397
throw errnoException(err, 'kill');
^
Error: kill ENOSYS
at exports._errnoException (util.js:1018:11)
at ChildProcess.kill (internal/child_process.js:397:13)
at Timeout.setTimeout (C:\Users\DELL\Documents\laravel-kit\test.js:14:7)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
I wrote this code as it is said in NodeJS Child Process API. But it's not working.
Use childProcess.spawn(command) (docs) instead of childProcess.exec, as “exec” creates a new shell and runs the command in that shell.
I used tree-kill module to kill the child process on Windows.
Use it like this:
var kill = require('tree-kill');
kill(your_child_process.pid, 'SIGKILL', function(err) {
// Do things
});
I need to be able to run '/etc/init.d/mongod status' or 'service mongod status' from wihtin a node js file, in order to store the response in the database.
When I run the above commands in the command line, I get the following response:
● mongod.service - SYSV: Mongo is a scalable, document-oriented database.
Loaded: loaded (/etc/rc.d/init.d/mongod)
Active: active (running) since Thu 2017-02-02 08:07:42 UTC; 3h 27min ago
Docs: man:systemd-sysv-generator(8)
Process: 793 ExecStart=/etc/rc.d/init.d/mongod start (code=exited, status=0/SUCCESS)
Main PID: 1027 (mongod)
CGroup: /system.slice/mongod.service
└─1027 /usr/bin/mongod -f /etc/mongod.conf
However, I want to include this status in an API response that I write. Therefore, when a user request my API, I want it to return the mongoDB status check as seen above.
I have tried the following ways:
router.get('/status', function(req, res) {
var databaseCheck = service mongod status // not sure how to do this
res.json({
mongoResponse: '//to have the above status check response here'
});
});
I am new to all this, so any help would be appreciated. I may understand that my thinking is wrong - do let me know if there is a different way of doing this please
Connect a database and then check connection like db.serverConfig.isConnected(). The below code is a full example.
const app = express();
let dbClient;
let db;
let collection;
MongoClient.connect(configuration.mongoDbUri, { useNewUrlParser: true, poolSize: 30 }, (error, client) => {
if (error) {
console.log("Connection failed for some reason. Err: ", error);
return error;
}
db = client.db("myDB");
dbClient = client;
collection = db.collection('myCollection');
app.locals.mongoDb = db;
});
app.get("/status", (req, res) => {
if (db.serverConfig.isConnected()) {
console.log("db.serverConfig.isConnected :", db.serverConfig.isConnected());
return res.send({ result: true});
}
return res.send({ result: false});
});
app.listen(configuration.app.port, error => {});
You can use nodejs child-process module to run a shell command like you would from a terminal. In a terminal you would "service mongod status", in the nodejs child-process you would do the same by putting that command as an argument to the child-process execute function, like so:
const exec = require('child_process').exec;
exec('service mongod status', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
Try code like this into you app:
db.serverConfig.isConnected();
I am using Node JS with Express and trying to execute a script and return the output of that script to the client via AJAX. The script is completing successfully, but for some reason I cannot get the output to show in the post response.
let childProcess = require('child_process');
router.post('/update', (req, res) => {
childProcess.exec('/home/dir/app/update.sh', { shell: '/bin/bash' }, (error, stdout, stderr) => {
res.json({ error, stdout, stderr });
});
});
The Node process is run using Forever. If I look at the forever log, it shows:
Forever detected script was killed by signal: SIGKILL
Not sure what that means. It appears the script is completing successfully though.
EDIT
To address Aikon's answer below. I tried the following and still no go.
router.post('/update', (req, res) => {
console.log('start...');
childProcess.exec('/home/dir/app/update.sh', { shell: '/bin/bash' }, (error, stdout, stderr) => {
console.log('done');
error = error || '';
stdout = stdout || '';
stderr = stderr || '';
res.json({ error, stdout, stderr });
});
});
It's as if the success function is never firing because it never logs "done" in the console. It just logs "start..." and the SIGKILL error above in the console.
Your script kill(and restart) itself before it can read output from child process.
Look at your update.sh again:
#!/bin/bash
git pull
npm install
npm run build
#this command restarts your script
forever restartall
You could remove last line of update.sh, and after sending response, the script just exits, forever should restart it with updated version.
router.post('/update', (req, res) => {
childProcess.exec('/home/dir/app/update.sh', { shell: '/bin/bash' },
(error, stdout, stderr) => {
res.json({ error, stdout, stderr });
process.exit();
});
});
If error is not empty then output is undefined => fail
After stringify error is empty object.
'use strict';
let error = new Error('err');
let str = 'text';
let obj = {a: 10, b: 15}; // Try comment to get fall
console.log(JSON.stringify({error, str, obj}))
You have a syntax error in your code. Try:
res.json({ error: error, output: stdout, error_log: stderr });
alternatively you can do:
res.json([ error, stdout, stderr ]);