cypress icon indicating copy to clipboard operation
cypress copied to clipboard

Add support to get downloaded file when its name is not known.

Open TomaszG opened this issue 4 years ago • 28 comments

It would be useful to have an option to parse downloaded files when their name is not known at the moment of download. I tried to create a helper function (task) for that which returns the latest file, however, it's not reliable as it's executed when file is not there yet:

// plugins/index.js
const getLastDownloadFilePath = () => {
  const dirPath = 'cypress/downloads';
  const filesOrdered = readdirSync(dirPath)
    .map(entry => path.join(dirPath, entry))
    .filter(entryWithPath => lstatSync(entryWithPath).isFile())
    .map(fileName => ({ fileName, mtime: lstatSync(fileName).mtime }))
    .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());

  return filesOrdered.length ? filesOrdered[0].fileName : false;
};

I believe it may be useful to have the ability to:

  1. wait for file download,
  2. get the name of the downloaded file.

These two should allow handling such cases.

TomaszG avatar Feb 02 '21 09:02 TomaszG

There's an example of reading a file directly after download by looking for extension. Is this helpful? https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/testing-dom__download/cypress/integration/spec.js#L263

jennifer-shehane avatar Feb 03 '21 07:02 jennifer-shehane

It solves only first part of the request as there's a chance that file is not in the downloads folder yet as Cypress doesn't wait for the file to download before the task is executed. It could work when used with waitUntil plugin. Maybe there should be a command to wait for file download which would return download results?

TomaszG avatar Feb 03 '21 15:02 TomaszG

I solved this issue with really great feature of Cypress - interceptor. Filename you can automatically grab from 'content-disposition' response header. Screenshot 2021-03-26 at 11 59 33

Here is a code snippet:

    // Prepare interceptor to get response after click on download button
    cy.intercept('file').as('incidentPdfReport');
    // Click on download button
    cy.get('[data-test=reportDownload]').click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentPdfReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      cy.readFile(downloadedFilename, 'binary', { timeout: 15000 })
        .should((buffer) => {
          expect(buffer.length).to.be.gt(100);
        });
      cy.log(`**File ${filename} exists in downloads folder**`);
      cy.readFile(downloadedFilename).should((text) => {
        const lines = text.split('\n');
        expect(lines).to.have.length.gt(2);
        expect(lines[0]).to.equal('%PDF-1.4');
      });
    });

In this way you don't need any manipulations with downloads folder like finding the last downloaded file, delete all files before test etc. - you have exact filename and you can do with this file whatever you need. Hopefully it will help you.

viktorgogulenko avatar Mar 26 '21 11:03 viktorgogulenko

@viktorgogulenko thanks for that, that should work when the file is generated in the backend and later sent in the response. Unfortunately, in my case, the file is generated by frontend code with file-saver library. Therefore there's no additional request with a filename in it.

I managed to create a workaround with:

// plugins/index.js
const path = require('path');
const { existsSync, readdirSync, lstatSync } = require('fs');

const downloadsDirPath = 'cypress/downloads';

const getLastDownloadFilePath = () => {
  if (!existsSync(downloadsDirPath)) {
    return null;
  }

  const filesOrdered = readdirSync(downloadsDirPath)
    .map(entry => path.join(downloadsDirPath, entry))
    .filter(entryWithPath => lstatSync(entryWithPath).isFile())
    .map(fileName => ({ fileName, mtime: lstatSync(fileName).mtime }))
    .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());

  if (!filesOrdered.length) {
    return null;
  }

  // TODO: this works only for chrome family browsers
  if (filesOrdered[0].fileName.indexOf('crdownload') > -1) {
    return null;
  }

  return filesOrdered[0].fileName;
};

and in test, I use it with wait-until plugin:

// integration/test.spec.js
cy.fixture('expectedFile').then(expectedFile => cy
  .waitUntil(() => cy
    .task('getLastDownloadFilePath')
    .then(result => result),
  { timeout: 3000, interval: 100 })
  .then(filePath => {
    cy.readFile(filePath).should(actualFile => {
      // assertion goes here
    });
  })
);

TomaszG avatar Mar 29 '21 08:03 TomaszG

There's an example of reading a file directly after download by looking for extension. Is this helpful? https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/testing-dom__download/cypress/integration/spec.js#L263

Seems that the link is broken

VicenteRuizWefoxgroup avatar May 12 '21 15:05 VicenteRuizWefoxgroup

Just go to the base directory with newer examples: https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/testing-dom__download

samtsai avatar Aug 25 '21 14:08 samtsai

I solved this issue with really great feature of Cypress - interceptor. Filename you can automatically grab from 'content-disposition' response header. Screenshot 2021-03-26 at 11 59 33

Here is a code snippet:

    // Prepare interceptor to get response after click on download button
    cy.intercept('file').as('incidentPdfReport');
    // Click on download button
    cy.get('[data-test=reportDownload]').click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentPdfReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      cy.readFile(downloadedFilename, 'binary', { timeout: 15000 })
        .should((buffer) => {
          expect(buffer.length).to.be.gt(100);
        });
      cy.log(`**File ${filename} exists in downloads folder**`);
      cy.readFile(downloadedFilename).should((text) => {
        const lines = text.split('\n');
        expect(lines).to.have.length.gt(2);
        expect(lines[0]).to.equal('%PDF-1.4');
      });
    });

In this way you don't need any manipulations with downloads folder like finding the last downloaded file, delete all files before test etc. - you have exact filename and you can do with this file whatever you need. Hopefully it will help you.

Didn't work unfortunately. Just times out. CypressError: Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

https://on.cypress.io/wait

dkoudrinhc avatar Nov 03 '21 01:11 dkoudrinhc

I solved this issue with really great feature of Cypress - interceptor. Filename you can automatically grab from 'content-disposition' response header. Screenshot 2021-03-26 at 11 59 33 Here is a code snippet:

    // Prepare interceptor to get response after click on download button
    cy.intercept('file').as('incidentPdfReport');
    // Click on download button
    cy.get('[data-test=reportDownload]').click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentPdfReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      cy.readFile(downloadedFilename, 'binary', { timeout: 15000 })
        .should((buffer) => {
          expect(buffer.length).to.be.gt(100);
        });
      cy.log(`**File ${filename} exists in downloads folder**`);
      cy.readFile(downloadedFilename).should((text) => {
        const lines = text.split('\n');
        expect(lines).to.have.length.gt(2);
        expect(lines[0]).to.equal('%PDF-1.4');
      });
    });

In this way you don't need any manipulations with downloads folder like finding the last downloaded file, delete all files before test etc. - you have exact filename and you can do with this file whatever you need. Hopefully it will help you.

Didn't work unfortunately. Just times out. CypressError: Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

https://on.cypress.io/wait

Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

nalanraj avatar Dec 13 '21 16:12 nalanraj

@TomaszG Thank you so much for posting your solution! It was a real life saver for our project and now we can actually test all our file downloads that have random names. 🙏

kaiyoma avatar Jul 01 '22 19:07 kaiyoma

@TomaszG In your example, how does getLastDownloadFilePath get registered as a task?

Edit: I see that plugins/index.js is deprecated these days - i'm looking for an equivalent solution at the moment

henricook avatar Sep 26 '22 16:09 henricook

I solved this issue with really great feature of Cypress - interceptor. Filename you can automatically grab from 'content-disposition' response header. Screenshot 2021-03-26 at 11 59 33 Here is a code snippet:

    // Prepare interceptor to get response after click on download button
    cy.intercept('file').as('incidentPdfReport');
    // Click on download button
    cy.get('[data-test=reportDownload]').click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentPdfReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      cy.readFile(downloadedFilename, 'binary', { timeout: 15000 })
        .should((buffer) => {
          expect(buffer.length).to.be.gt(100);
        });
      cy.log(`**File ${filename} exists in downloads folder**`);
      cy.readFile(downloadedFilename).should((text) => {
        const lines = text.split('\n');
        expect(lines).to.have.length.gt(2);
        expect(lines[0]).to.equal('%PDF-1.4');
      });
    });

In this way you don't need any manipulations with downloads folder like finding the last downloaded file, delete all files before test etc. - you have exact filename and you can do with this file whatever you need. Hopefully it will help you.

Didn't work unfortunately. Just times out. CypressError: Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred. https://on.cypress.io/wait

Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

Cypress.Commands.add('getDownloadfile', (element) => {
    // Prepare interceptor to get response after click on download button
    cy.intercept('**/api/v1.0/n/export/data?file_type=*').as('incidentReport');
    // Click on download button
    cy.contains('button',element).click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      return downloadedFilename;
    });
})

chaitanyarajugithub avatar Mar 05 '23 16:03 chaitanyarajugithub

I solved this issue with really great feature of Cypress - interceptor. Filename you can automatically grab from 'content-disposition' response header. Screenshot 2021-03-26 at 11 59 33 Here is a code snippet:

    // Prepare interceptor to get response after click on download button
    cy.intercept('file').as('incidentPdfReport');
    // Click on download button
    cy.get('[data-test=reportDownload]').click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentPdfReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      cy.readFile(downloadedFilename, 'binary', { timeout: 15000 })
        .should((buffer) => {
          expect(buffer.length).to.be.gt(100);
        });
      cy.log(`**File ${filename} exists in downloads folder**`);
      cy.readFile(downloadedFilename).should((text) => {
        const lines = text.split('\n');
        expect(lines).to.have.length.gt(2);
        expect(lines[0]).to.equal('%PDF-1.4');
      });
    });

In this way you don't need any manipulations with downloads folder like finding the last downloaded file, delete all files before test etc. - you have exact filename and you can do with this file whatever you need. Hopefully it will help you.

Didn't work unfortunately. Just times out. CypressError: Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred. https://on.cypress.io/wait

Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

Cypress.Commands.add('getDownloadfile', (element) => {
    // Prepare interceptor to get response after click on download button
    cy.intercept('**/api/v1.0/n/export/data?file_type=*').as('incidentReport');
    // Click on download button
    cy.contains('button',element).click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      return downloadedFilename;
    });
})

Could you please show a content of your "Network" tab after you clicked on button to download a file? Do you have a call at all?

viktorgogulenko avatar Mar 06 '23 07:03 viktorgogulenko

I solved this issue with really great feature of Cypress - interceptor. Filename you can automatically grab from 'content-disposition' response header. Screenshot 2021-03-26 at 11 59 33 Here is a code snippet:

    // Prepare interceptor to get response after click on download button
    cy.intercept('file').as('incidentPdfReport');
    // Click on download button
    cy.get('[data-test=reportDownload]').click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentPdfReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      cy.readFile(downloadedFilename, 'binary', { timeout: 15000 })
        .should((buffer) => {
          expect(buffer.length).to.be.gt(100);
        });
      cy.log(`**File ${filename} exists in downloads folder**`);
      cy.readFile(downloadedFilename).should((text) => {
        const lines = text.split('\n');
        expect(lines).to.have.length.gt(2);
        expect(lines[0]).to.equal('%PDF-1.4');
      });
    });

In this way you don't need any manipulations with downloads folder like finding the last downloaded file, delete all files before test etc. - you have exact filename and you can do with this file whatever you need. Hopefully it will help you.

Didn't work unfortunately. Just times out. CypressError: Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred. https://on.cypress.io/wait

Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.

Cypress.Commands.add('getDownloadfile', (element) => {
    // Prepare interceptor to get response after click on download button
    cy.intercept('**/api/v1.0/n/export/data?file_type=*').as('incidentReport');
    // Click on download button
    cy.contains('button',element).click();
    // Interceptor waiting when response will come and file is completely downloaded
    cy.wait('@incidentReport', { timeout: 20000 }).then((res) => {
      const downloadsFolder = Cypress.config('downloadsFolder');
      // grab filename from 'content-disposition' header
      const filename = res.response.headers['content-disposition'].split('filename=')[1];
      const downloadedFilename = path.join(downloadsFolder, filename);
      return downloadedFilename;
    });
})

Could you please show a content of your "Network" tab after you clicked on button to download a file? Do you have a call at all?

please find the ref network calls Screenshot 2023-03-06 at 7 38 23 PM

chaitanyarajugithub avatar Mar 06 '23 14:03 chaitanyarajugithub

@chaitanyarajugithub please try to use cy.intercept('**/api/v1.0/n/export/data?file_type=**').as('incidentReport');

viktorgogulenko avatar Mar 06 '23 14:03 viktorgogulenko

Cypress.Commands.add('getDownloadfile', (element) => { // Prepare interceptor to get response after click on download button cy.intercept('**/api/v1.0/n/export/data?file_type=*').as('incidentReport'); // Click on download button cy.contains('button',element).click(); // Interceptor waiting when response will come and file is completely downloaded cy.wait('@incidentReport', { timeout: 20000 }).then((res) => { const downloadsFolder = Cypress.config('downloadsFolder'); // grab filename from 'content-disposition' header const filename = res.response.headers['content-disposition'].split('filename=')[1]; const downloadedFilename = path.join(downloadsFolder, filename); return downloadedFilename; }); })

No luck, Same issue --> Used cy.intercept('**/api/v1.0/n/export/data?file_type=**').as('incidentReport'); --> Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: incidentReport. No request ever occurred.

Can you provide any open-source example that works intercept? I am using the latest cypress version 12.7.0

chaitanyarajugithub avatar Mar 07 '23 05:03 chaitanyarajugithub

@chaitanyarajugithub I'll try to push something, but meanwhile I'm curious why do you have cy.wait('@IncidentReport'... as you are saving alias as .as('incidentReport'); (capital letter "I") - they should be the same.

viktorgogulenko avatar Mar 07 '23 06:03 viktorgogulenko

@chaitanyarajugithub I'll try to push something, but meanwhile I'm curious why do you have cy.wait('@IncidentReport'... as you are saving alias as .as('incidentReport'); (capital letter "I") - they should be the same.

It's just a typo error in the above comment but I used the correct match case in the code. here is the screenshot. Screenshot 2023-03-07 at 12 02 11 PM

chaitanyarajugithub avatar Mar 07 '23 06:03 chaitanyarajugithub

@chaitanyarajugithub I've found in examples something similar how to deal with files using interceptor Main idea here is to: prepare interceptor for expected call -> make an action which is making this call (push the button for ex) -> wait with cy.wait when call will be successfully executed. There could be few issues - was used wrong regex to filter out proper call, if call happened - be sure that Content-Disposition header is in list of response headers to be able to grab filename:

Screenshot 2023-03-22 at 12 22 50

viktorgogulenko avatar Mar 22 '23 11:03 viktorgogulenko

@TomaszG In your example, how does getLastDownloadFilePath get registered as a task?

Edit: I see that plugins/index.js is deprecated these days - i'm looking for an equivalent solution at the moment

// cypress.config.js
const { defineConfig } = require('cypress')

const { testUsers } = require('@hm/common-data')

module.exports = defineConfig({
	(...)
	e2e: {
		setupNodeEvents(on, config) {
			return require('./cypress/plugins')(on, config)
		},
		(...)
	},
})
// cypress/plugins/index.js

module.exports = (on, config) => {
	on('task', {
		...require('./tasks'),
	})

	return config
}
// cypress/plugins/tasks.js

const yourTask = () => {
	// do stuff

	return null
}

module.exports = {
	yourTask,
}

TomaszG avatar Jun 27 '23 12:06 TomaszG

amended generic version, without path dependency (might not work on Windows):

Cypress.Commands.add(
  "downloadAndReadFile",
  { prevSubject: "element" },
  (subject) => {
    return cy.wrap(subject).then(($el) => {
      cy.wrap($el).invoke("attr", "href").then(url => {
        cy.intercept(url).as("download");
        cy.wrap($el).click();
        cy.wait("@download").then((res) => {
          const downloads = Cypress.config("downloadsFolder");
          const fileName = res.response.headers["content-disposition"].split("filename=")[1];
          return cy.readFile(`${downloads}/${fileName}`);
        });
      });
    });
  });

used like this:

cy.contains("Download link")
      .downloadAndReadFile()
      .should("exist")
      .and("contain", "my-expected-content");

jorunfa avatar Oct 13 '23 13:10 jorunfa

Hey guys can someone help in how to download dynamic files in cypress and test the content present in it (My file doesnt contain a content diposition line in headers so that might not work for me

pratikjain10999 avatar Nov 14 '23 12:11 pratikjain10999

Hey guys can someone help in how to download dynamic files in cypress and test the content present in it (My file doesnt contain a content diposition line in headers so that might not work for me

Yes same for me. Could any one help on this?

satya081 avatar May 24 '24 15:05 satya081

@satya081 @pratikjain10999 please open your Network tab in Developer Tools, initiate downloading of the file and check what call is responsible for that, click on it and make a screenshot with details of this call (URL, headers etc). I'm pretty sure that call could be unique enough so we could grab some info from there but this is hard to understand what's happening in your case without more details.

viktorgogulenko avatar May 24 '24 16:05 viktorgogulenko

Hi Folks, I have the same problem of downloading dynamically generated file and we are using some third party plugin which creates a blob and downloads the file dynamically with some timestamp in the name. Since we are able to see the logged value in the cypress console, is there a way to access those values inside the test itself. I checked the network logs there's nothing there.

However am able to confirm the downloaded file getting saved and even in the cypress logs it's available.

Screenshot 2024-09-18 at 12 51 51 PM
    "message": "/cypress/downloads/Policy_1726644028992.xlsx",
    "name": "download",
    "type": "parent",
    "event": true,
    "timeout": 0,
    "isCrossOriginLog": false,
    "id": "log-http://localhost:0000-381",
    "chainerId": "ch-http://localhost:0000-42",
    "state": "passed",
    "hidden": false,
    "instrument": "command",
    "url": "http://localhost:0000/policy-search#/",
    "hookId": "r3",
    "testId": "r3",
    "testCurrentRetry": 0,
    "viewportWidth": 1000,
    "viewportHeight": 660,
    "wallClockStartedAt": "2024-09-18T07:20:30.963Z",
    "createdAtTimestamp": 1726644030963.1,
    "updatedAtTimestamp": 1726644031046.1,
    "consoleProps": {
        "name": "download",
        "type": "event",
        "props": {
            "Download URL": "blob:http://localhost:0000/a6f98e18-eabf-485a-b76b-a2154eb4f14e",
            "Saved To": "/cypress/downloads/Policy_1726644028992.xlsx",
            "Mime Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        }
    },
    "renderProps": {},
    "snapshots": [
        {
            "timestamp": 1726644030964.7002,
            "htmlAttrs": {},
            "body": {}
        },
        {
            "timestamp": 1726644031013.5,
            "htmlAttrs": {},
            "body": {}
        }
    ],
    "ended": true,
    "snapshot": false
}




Would really appreciate your help here. Thanks.

dibyanshusinha avatar Sep 18 '24 07:09 dibyanshusinha

@dibyanshusinha: if you have access to the file path, can't you just use cy.readFile()?

something like

cy.readFile(thing.message).should('eq', 'Hello World')

https://docs.cypress.io/api/commands/readfile#Text

jorunfa avatar Sep 18 '24 11:09 jorunfa

@jorunfa The filename is dynamic in nature I mean filename_${timestamp}.${extension}. So the exact filepath will not be known, hence my question.

Is there a way to know the exact filename of the file which was just downloaded ? I can see the filename in cypress console. Is there a way to access the filename, by spying on the event which triggered that log present in the cypress console, instead of only relying on the log events ?

dibyanshusinha avatar Sep 18 '24 14:09 dibyanshusinha

FYI As I was saying, I did this which works quite well. I wish there was a cypress event something such as cy.on('download:triggered', (...args)), it would have helped a lot.

For all those who end up here and don't mind relying on the logs. Here's a snippet.

spec.cy.js

 //   ..................  //
 //   ..................  //
 
let fileName;

const checkDownloadLog = (attr) => {
  console.log(attr);
  const { name, event, message } = attr;
  if (name==='download' && event) {
    fileName = message;
  }
};

cy.on('log:added', checkDownloadLog);

//ACTION Which lead to download
cy.get('button').click().then(_res => {
  cy.removeListener('log:added', checkDownloadLog);
  console.log('FILE_NAME', fileName);
  //   ..................  //
  //   ..................  //
});

dibyanshusinha avatar Sep 19 '24 20:09 dibyanshusinha

FYI As I was saying, I did this which works quite well. I wish there was a cypress event something such as cy.on('download:triggered', (...args)), it would have helped a lot.

For all those who end up here and don't mind relying on the logs. Here's a snippet.

spec.cy.js

 //   ..................  //
 //   ..................  //
 
let fileName;

const checkDownloadLog = (attr) => {
  console.log(attr);
  const { name, event, message } = attr;
  if (name==='download' && event) {
    fileName = message;
  }
};

cy.on('log:added', checkDownloadLog);

//ACTION Which lead to download
cy.get('button').click().then(_res => {
  cy.removeListener('log:added', checkDownloadLog);
  console.log('FILE_NAME', fileName);
  //   ..................  //
  //   ..................  //
});

Beware, this only works if the name is not defined by js code.

AGuyCoding avatar Feb 13 '25 10:02 AGuyCoding