Protractor e2e test case for downloading pdf file

38,042

Solution 1

I can currently set download path location

Chrome

capabilities: {
    'browserName': 'chrome',
    'platform': 'ANY',
    'version': 'ANY',
    'chromeOptions': {
        // Get rid of --ignore-certificate yellow warning
        args: ['--no-sandbox', '--test-type=browser'],
        // Set download path and avoid prompting for download even though
        // this is already the default on Chrome but for completeness
        prefs: {
            'download': {
                'prompt_for_download': false,
                'default_directory': '/e2e/downloads/',
            }
        }
    }
}

For remote testing you would need a more complex infrastructure like setting up a Samba share or network shared directory destination.

Firefox


var FirefoxProfile = require('firefox-profile');
var q = require('q');

[...]
getMultiCapabilities: getFirefoxProfile,
framework: 'jasmine2',

[...]
function getFirefoxProfile() {
    "use strict";
    var deferred = q.defer();
    var firefoxProfile = new FirefoxProfile();
    firefoxProfile.setPreference("browser.download.folderList", 2);
    firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
    firefoxProfile.setPreference("browser.download.dir", '/tmp');
    firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");

    firefoxProfile.encoded(function(encodedProfile) {
        var multiCapabilities = [{
            browserName: 'firefox',
            firefox_profile : encodedProfile
        }];
        deferred.resolve(multiCapabilities);
    });
    return deferred.promise;
}

Finally and maybe obvious, to trigger the download you click on the download link as you know, e.g.

$('a.some-download-link').click();

Solution 2

I needed to check the contents of the downloaded file (a CSV export in my case) against an expected result, and found the following to work:

var filename = '/tmp/export.csv';
var fs = require('fs');

if (fs.existsSync(filename)) {
    // Make sure the browser doesn't have to rename the download.
    fs.unlinkSync(filename);
}

$('a.download').click();

browser.driver.wait(function() {
    // Wait until the file has been downloaded.
    // We need to wait thus as otherwise protractor has a nasty habit of
    // trying to do any following tests while the file is still being
    // downloaded and hasn't been moved to its final location.
    return fs.existsSync(filename);
}, 30000).then(function() {
    // Do whatever checks you need here.  This is a simple comparison;
    // for a larger file you might want to do calculate the file's MD5
    // hash and see if it matches what you expect.
    expect(fs.readFileSync(filename, { encoding: 'utf8' })).toEqual(
        "A,B,C\r\n"
    );
});

I found Leo's configuration suggestion helpful for allowing the download to be saved somewhere accessible.

The 30000ms timeout is the default, so could be omitted, but I'm leaving it in as a reminder in case someone would like to change it.

Solution 3

The solutions above would not work for remote browser testing, e.g. via BrowserStack. An alternative solution, just for Chrome, could look like this:

if ((await browser.getCapabilities()).get('browserName') === 'chrome') {
  await browser.driver.get('chrome://downloads/');
  const items =
    await browser.executeScript('return downloads.Manager.get().items_') as any[];
  expect(items.length).toBe(1);
  expect(items[0].file_name).toBe('some.pdf');
}

Solution 4

it could be the test for checking href attribute like so:

var link = element(by.css("a.pdf"));
expect(link.getAttribute('href')).toEqual('someExactUrl');
Share:
38,042
user3061796
Author by

user3061796

Updated on December 30, 2021

Comments

  • user3061796
    user3061796 over 2 years

    Can anyone tell me how to write test case for a link to download pdf file using jasmine framework ? Thanks in advance.

  • Leo Gallucci
    Leo Gallucci over 9 years
    I'm glad my answer helped! :) I also ended up writing a helper function waitFileExists(fileAbsPath) ;)
  • andrepm
    andrepm over 9 years
    Hello Leo, i'm trying to set a default path location for Chrome, but apparently your solution didn't worked for me.
  • Rogério Peixoto
    Rogério Peixoto about 8 years
    what about phantomjs?
  • rohitkadam19
    rohitkadam19 almost 8 years
    @LeoGallucci With above code, Firefox doesn't spawn and no errors. But if I use browserName:'firefox' in export.config, it opens firefox successfully. What could be reason? Thanks!
  • Leo Gallucci
    Leo Gallucci almost 8 years
    Yes, of course if you want to use Firefox you need to set browserName:'firefox'
  • Nick
    Nick over 7 years
    @LeoGallucci I would need to use 1 config file and pass browserName as parameter how can i achieve this, i see for 'FIREFOX' "getMultiCapabilities" is used and for 'CHROME' "capabilities" is used. help would be greatly appreciated.
  • Bruno Soko
    Bruno Soko over 7 years
    @LeoGallucci can you please share what you did in the waitFileExists(fileAbsPath)? are you on that method working to get form the fileAbsPath so it can work on any computer?
  • Leo Gallucci
    Leo Gallucci over 7 years
    What do you mean, the code is right up there, see "Wait until the file has been downloaded."
  • Jeremy Kahan
    Jeremy Kahan over 7 years
    Has anyone had success developing the same for Internet Explorer?