Protractor e2e test case for downloading pdf file
Asked Answered
A

5

40

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

Aldebaran answered 21/2, 2014 at 13:24 Comment(0)
S
47

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();
Sydelle answered 30/9, 2014 at 18:34 Comment(5)
Hello Leo, i'm trying to set a default path location for Chrome, but apparently your solution didn't worked for me.Fairly
@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!Ultrafilter
Yes, of course if you want to use Firefox you need to set browserName:'firefox'Sydelle
@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.Attenweiler
Has anyone had success developing the same for Internet Explorer?Zounds
H
46

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.

Hageman answered 20/11, 2014 at 4:44 Comment(4)
I'm glad my answer helped! :) I also ended up writing a helper function waitFileExists(fileAbsPath) ;)Sydelle
what about phantomjs?Archiplasm
@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?Vicereine
What do you mean, the code is right up there, see "Wait until the file has been downloaded."Sydelle
C
1

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

var link = element(by.css("a.pdf"));
expect(link.getAttribute('href')).toEqual('someExactUrl');
Coburn answered 21/2, 2014 at 15:31 Comment(0)
P
1

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');
}
Petroleum answered 10/10, 2018 at 20:59 Comment(0)
B
-1

One thing I've done in the past is to use an HTTP HEAD command. Basically, it's the same as a 'GET', but it only retrieves the headers.

Unfortunately, the web server needs to support 'HEAD' explicitly. If it does, you can actually try the URL and then check for 'application/pdf' in the Content-Type, without having to actually download the file.

If the server isn't set up to support HEAD, you can probably just check the link text like was suggested above.

Bleareyed answered 3/10, 2014 at 20:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.