0

Background: Working on some file download tests with Protractor and Chrome. I run on a selenium grid, so the tests and my Node env are executing on a server (e.g. 8.2.2.2) while the file downloads are on a remote windows machine (e.g. 14.3.3.3).

The file download used to be stored on the same server that also kicked off the tests, so I was just waiting for a file to exist before performing my assertion:

browser.wait(() => {
    return fs.existsSync(filePath)
}).then(() => {
    // expect something
})

Problem: Now, the files dont write to the Server (they download directly to the browser) so I have nothing to grab... so far. Since I use a selenium grid I can't directly read the remote machine from the test server.

Question: Will the protractor browser object or chromedriver have any information about that file download that I can grab? Trying to find a way to access both file name and file size? I'm digging into the browser object but havent found anything yet.

Gunderson
  • 3,263
  • 2
  • 16
  • 34
  • 3
    Navigate `chrome://downloads/` to get a list of all the downloaded files: https://stackoverflow.com/questions/47068912/how-to-download-a-file-using-the-remote-selenium-webdriver/47164044#47164044 – Florent B. Dec 19 '17 at 16:07
  • @FlorentB. Awesome thanks, I've got a working version now off that. Not sure how I didnt come across that question in my previous searches – Gunderson Dec 19 '17 at 17:53
  • @FlorentB. Where do you find docs on these methods? `downloads.Manager` etc. Didnt even know those existed – Gunderson Dec 19 '17 at 18:49
  • 1
    these methods are undocumented. You can find them by inspecting the source of `chrome://downloads/` with devtools. You can also find them in the source of chromium: https://cs.chromium.org/chromium/src/chrome/browser/resources/md_downloads/manager.js – Florent B. Dec 19 '17 at 18:56

2 Answers2

0

Forgot this was never answered, so I'll post my own solution after @Florent B helped me in the comments. I broke this down for simplicity sake, the code could be much cleaner (also depends on your use case):

it('generates a file', () => {
    // begin file download
    btnGenerateReport.click()
    .then(() => {
        // open a new window to leave current one in state
        return browser.executeScript('window.open()')
    })
    .then(() => {
        // switch to new window
        return browser.getAllWindowHandles().then((handles) => {
            return browser.switchTo().window(handles[1]);
        })
    })
    .then(() => {
        // navigate to downloads
        return browser.get('chrome://downloads')
    })
    .then(() => {
        // pauses tests until download has 1 item AND item status is 'Complete'
        return browser.wait(() => {
            return browser.executeScript('return downloads.Manager.get().items_.length > 0 && downloads.Manager.get().items_[0].state === "COMPLETE"');
        }, 600000, `"downloads.Manager.get().items_" did not have length > 0 and/or item[0].state did not === "COMPLETE" within ${600000/1000} seconds`)
    })
    .then(() => {
        // get downloads
        return browser.executeScript('return downloads.Manager.get().items_');
    }).then((items) => {
        // this is your download item(s)
        console.log(items);
    });
});
Gunderson
  • 3,263
  • 2
  • 16
  • 34
0

To assert downloading files in remote using protractor/selenium:

  1. Create a FTP server manually on your remote to host the download folder

  2. Set capabilities for download without prompt to that particular folder(hosted via FTP) in protractor

    capabilities: {
        browserName: "chrome",
        chromeOptions: {
            args: ["--disable-gpu"],
            prefs: {
                download: {
                    prompt_for_download: false,
                    directory_upgrade: true,
                    default_directory: `${__dirname}\\src\\json.file\\`
                }
            }
        }
    }
  3. Assert the content of the folder using any ftp module in node

npm install ftp-client