How to connect to SFTP server in Cypress test?

1.4k Views Asked by At

I am trying to connect to an SFTP server using the ssh2-sftp-client NPM package in my Cypress test.

Here is my test at the moment

describe('example to-do app', () => {
    it('displays two todo items by default', () => {
        let Client = require('ssh2-sftp-client');
        let sftp = new Client();
        
        sftp.connect({
          host: 'myHost',
          port: 'myPort',
          username: 'myUsername',
          password: 'myPassword'
        }).then(() => {
          return sftp.list('/reports');
        }).then(data => {
          console.log(data, 'the data info');
        }).catch(err => {
          console.log(err, 'catch error');
        });
    })
})

Currently, when I run the test I get this error:

Cannot read properties of undefined (reading 'DEFLATE')
node_modules/ssh2/lib/protocol/zlib.js:7:1
   5 |   createInflate,
   6 |   constants: {
>  7 |     DEFLATE,
     | ^
   8 |     INFLATE,
   9 |     Z_DEFAULT_CHUNK,
  10 |     Z_DEFAULT_COMPRESSION,

Can someone please tell me how to resolve this issue?

2

There are 2 best solutions below

0
On BEST ANSWER

Establishing such connection in a test will not work. This is because cypress does not communicate with a Node.js process supplied by the host. In cypress if we need to run node code, we need to use their so called cy.task Here is the link to their docs - https://docs.cypress.io/api/commands/task#Examples

That's why you need to establish this connection in your cypress/plugins/index.js file inside a task and then use this task in your test.

Here is an example of connecting to mysql with ssh - How do I connect mysql with cypress through ssh tunneling?

0
On

I was researching a similar question as the OP and @YuliaP provided some useful info that helped. Since I'm using the latest version of Cypress (13.6.6), I thought I would post my solution to provide some details. I did install ssh2-sftp-client, https://www.npmjs.com/package/ssh2-sftp-client. Then, I added the following to cypress.config.js (credit: a lot of this code came from the previous link):

const { defineConfig } = require("cypress");
const sftpClient = require('ssh2-sftp-client');

module.exports = defineConfig({
  e2e: {
    specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
    setupNodeEvents(on, config) {
      const username = process.env.SFTP_USERNAME;
      const password = process.env.SFTP_PASSWORD;
      console.log('sftp username: ', username);
      const localFilePath = '/Work/(research)/Angular/cypress-sftp/git/sftp-app/src/';
      const hostnm = 'mysftp.domain.org';
      // implement node event listeners here
      on('task', {
        'sftp:put': (filename) => {
          let client = new sftpClient();
          client.connect({
            host: hostnm,
            port: '2222',
            username: username,
            password: password
          }).then(() => {
            // always good to start path with a slash /
              return client.put(localFilePath + filename, '/download/' + filename);
          }).then(data => {
            console.log(data);
            client.end();
          }).catch(err => {
            console.log(err);
          });
          return null;
        }
      })

      on('task', {
        sftplist(folder) {
          let client = new sftpClient();
          client.connect({
            host: hostnm,
            port: '2222',
            username: username,
            password: password
          }).then(() => {
              return client.list(folder);
          }).then(fileInfo => {
            console.log(fileInfo);
            client.end();
          }).catch(err => {
            console.log(err);
          });
          return null;
        }
      })

    }
  }
});

I my case, there was no need to create an index.js in the plugins folder. That approach is for legacy Cypress. Here is a demo test:

describe('Connect to SFTP and perform operations', () => {
 it('Put file to fstp server', () => {
  cy.task('sftp:put', 'sftp-data.txt');
 })
 it('Read folder on fstp server', () => {
    cy.task('sftplist', '/download');
 })
})

This is only a sample so likely can be tweaked further. Enjoy