Cy x SSH
Cypress does not natively support being able to connect to ssh hosts and execute commands remotely. But today’s SUT (System Under Test) have become very complex and they might need interacting with ssh servers, ftp servers, databases etc etc… For that cypress has kept a channel open, which is called as Cypress Tasks.
So what happens is instead of executing your code inside the browser, we can run inside Node and virtually have any functionality which node can handle, implant within our cypress automation framework as well.
Task
Execute code in Node via the
task
plugin event.
So here is the complete breakdown…
#install simple-ssh package and add the entry to package.json
npm install simple-ssh --save-dev
Add the below task in you cypress/plugins/index.js file or your plugins file equivalent.
// import the simple-ssh node package
const SSH = require(‘simple-ssh’);
module.exports = (on, config) => {
// add a task called sshExecuteCmd
on("task", {
sshExecuteCmd: ({ sshconn, command }) => {
return new Promise((resolve, reject) => {
let ssh = new SSH(sshconn);
ssh
.exec(command, {
out: function (stdout) {
console.log("stdout: " + stdout);
resolve(stdout);
},
err: function (stderr) {
console.log("stderr: " + stderr);
resolve(stderr);
},
})
.start();
});
}
});
}
Now invoking the ssh server in different ways…
a. username / password based
const configObj = { "host" : "10.1.1.1", "user": "root" , "pass": "qwerty"}
cy.task("sshExecuteCmd",{
sshconn: configObj,
command:'ls -ltrh' // this is the cmd we are executing on the ssh host
}).then(stdout => {
cy.log("O/P is :" + stdout);
});
b. key / passphrase based
const configObj = { "host" : "10.1.1.1", "user": "root" , "pass": "", "key":"keys/key.pem", "passphrase":"",}
// put the key in fixtures i.e. cypress/fixtures/keys/key.pem
// now load the content of the key file from fixtures
cy.fixture(configObj.key).then((keyFileContent) => {
// and update in the ssh configs object
configObj.key = keyFileContent;
// or another way is to directly pass the key file content into the configObj object itself
// but loading it through fixtures makes it a clean implementation
cy.task("sshExecuteCmd", {
sshconn: configObj,
command: "ls -ltrh",
}).then((stdout) => {
cy.log("O/P is :" + stdout);
});
})
p.s. — for a complete list of available configs which are supported, please refer simple-ssh constructor config object api documentation.
References: