How to Upload Files to an SFTP Server Using Node.js and Cypress

How to Upload Files to an SFTP Server Using Node.js and Cypress
How to Upload Files to an SFTP Server Using Node.js and Cypress

Uploading files to an SFTP server is a critical part of many applications. This guide will walk you through the process using Node.js and Cypress, leveraging the ssh2-sftp-client library for handling SFTP connections and file transfers.

What is SFTP?

SFTP (SSH File Transfer Protocol) is a secure method for transferring files over the Internet, using the Secure Shell (SSH) protocol to provide encryption and secure authentication. Unlike FTP, SFTP ensures that both commands and data are encrypted, making it a preferred choice for secure file transfers.

Why Use SFTP?

Security

SFTP is designed to provide a high level of security by encrypting both the command and data channels. This ensures that sensitive data, including passwords and file contents, are protected from eavesdropping and man-in-the-middle attacks.

Reliability

SFTP is more reliable than FTP because it includes mechanisms for checking the integrity of the transferred files and ensures that data is not corrupted during transmission.

Access Control

SFTP uses SSH for authentication, allowing you to leverage SSH keys for secure and robust access control. This is particularly important for enterprise environments where security is a top priority.

Firewalls

SFTP operates over a single, secure connection on a single port (typically port 22), making it easier to configure firewalls and network security settings.

Why Integrate SFTP with Cypress?

Comprehensive Testing

Integrating SFTP functionality into your Cypress tests allows you to automate and verify the entire workflow of your application, including file transfers. This ensures that your application behaves as expected under various conditions.

Continuous Integration

By including SFTP file transfers in your Cypress tests, you can seamlessly integrate these tests into your CI/CD pipeline. This helps in catching issues early in the development cycle and ensures that your application maintains high quality.

Efficiency

Automating file transfers with Cypress and SFTP can save significant time and effort compared to manual testing, especially for large-scale applications that handle numerous file uploads.

Prerequisites

First, ensure you have Node.js and npm installed on your machine. If not, download and install them from nodejs.org.

Install Required Packages

Run the following commands to install the necessary packages:

npm install ssh2-sftp-client dotenv
npm install --save-dev typescript ts-node @types/node @types/ssh2-sftp-client

TypeScript Configuration

If you are using TypeScript, update your tsconfig.json file to include the necessary configurations:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

File Upload Setup

  1. Fixture File: Prepare the file you want to upload and store it in a fixture directory within your Cypress project.
  2. Sample Script (uploadFile.ts): Create a file named uploadFile.ts (or .js if not using TypeScript) inside your cypress/support folder. This script handles the upload process.

Setting Up Environment Variables

Create a .env file in your project root. This file should not be committed to version control. Define the following environment variables within the .env file:

SFTP_SERVER=sftp_server
SFTP_USER=username
SFTP_PASSWORD=password
SFTP_PORT=22

Load these variables in your script using the dotenv package.

Writing the File Upload Script

Create a file named uploadFile.ts or uploadFile.js in the cypress/support folder with the following content:

const Client = require('ssh2-sftp-client');
require('dotenv').config();

const config = {
  host: process.env.SFTP_SERVER,
  port: process.env.SFTP_PORT,
  username: process.env.SFTP_USER,
  password: process.env.SFTP_PASSWORD,
};

let sftp = new Client();

const uploadFile = async (localFilePath: string, remoteFilePath: string) => {
  try {
    await sftp.connect(config);
    const remoteDirExists = await sftp.exists(remoteFilePath);
    console.log(remoteDirExists);  // will be false or 'd', '-', 'l' (dir, file, or link)
    
    if (!remoteDirExists) {
      console.log('Uploading file...');
      await sftp.put(localFilePath, remoteFilePath);
      console.log('File uploaded successfully!');
    }
  } catch (err) {
    console.error(err.message);
  } finally {
    sftp.end();
  }
};

uploadFile('path/to/local/file', '/path/to/remote/dir/filename');

Running the Script

You can run the script using the following command:

For TypeScript:

npx ts-node cypress/support/uploadFile.ts

For JavaScript:

node cypress/support/uploadFile.js

This script will connect to the SFTP server, check if the remote directory exists, upload the file, and confirm the upload.

Integrating with Cypress

To integrate the file upload functionality into your Cypress tests, you need to update your Cypress configuration and create a custom task.

Update Cypress Configuration

In your cypress.config.ts, include the file upload task:

import { defineConfig } from 'cypress';
import uploadFile from './cypress/support/uploadFile';

export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        uploadFile: async (fileName: string) => {
          try {
            const result = await uploadFile(fileName);
            return result; // Ensure the result is returned
          } catch (err) {
            throw err; // Rethrow if an error occurs
          }
        },
      });
      return config;
    },
  },
});

Use in Spec File

In your Cypress spec file, use the custom task to upload a file:

const FileName = 'path/to/your/myFile.csv';

describe('SFTP File Upload', () => {
  it('should upload a file to SFTP server', () => {
    cy.task('uploadFile', FileName).then((result) => {
      expect(result).to.be.true;
    });
  });
});

Important Notes

  • Security: Don't store sensitive information like passwords directly in the code. Use environment variables and proper access control mechanisms for secure SFTP access.
  • Error Handling: Ensure proper error handling in your script and Cypress tests to capture potential issues during the upload process.
  • Adapting the Script: Modify the script to accommodate your specific file upload logic using the SFTP client methods.

By following these steps, you can leverage Cypress tasks and the ssh2-sftp-client library to upload files securely to an SFTP server within your Cypress tests.

Conclusion

By following the steps outlined in this guide, you can easily set up and use the ssh2-sftp-client library to upload files to an SFTP server within your Node.js environment. Additionally, integrating this functionality into your Cypress tests allows for comprehensive automated testing of file uploads. The provided script and configurations ensure a smooth and efficient setup process.

Read more