segment-boneyard / nightmare

A high-level browser automation library.
https://open.segment.com
19.55k stars 1.08k forks source link

Prevent automatic downloads #332

Closed fmaruki-zz closed 8 years ago

fmaruki-zz commented 9 years ago

When visiting a page that prompts a download window after the onload, is there a way to prevent it to pop up, so that I can use nightmarejs without needing to interact and close those windows?

Something like a preventDefault on a will-download event?

rosshinkley commented 9 years ago

The good news: you can prevent dialog popups in Electron on a will-download event by using DownloadItem.setSavePath. This was introduced with this pull. Or if you don't want to download the item, I think you can use DownloadItem.cancel.

And now, the unfortunate news: I don't think will-download is exposed in Nightmare, at least at present. It looks (at least superficially) difficult - I think downloads would have to be tracked and Nightmare.end would have to be blocked until the downloads are all complete.

Thoughts?

darthcloud commented 9 years ago

The new will-download functionality in Electron is really interesting, in Issue #151 @fritx provided some example of using it.

Adding support for download would be important in Nightmare IMHO it's something missing in most headless browser automation solution.

rosshinkley commented 9 years ago

@darthcloud I agree that it's something that is (in general) missing from headless solutions, and that it is pretty important.

To that end, I spent some time tinkering with will-download, and there are a couple of things I'd love to hear your (and others') thoughts on.

  1. I know I'm stating the obvious, but this would require an upgrade to electron-prebuilt.
  2. You have to do what you're going to do with the downloading item synchronously inside of the will-download handler. This means that I don't think you could use events to negotiate on a per-download basis where to put downloads or if an item should be ignored. I haven't put in an option to globally ignore downloads yet, I wanted to get some feedback (hopefully a correction) on this first.
  3. I realize that multiple downloads is a bit of a corner case, but a problem nonetheless. In my sandbox, I have the will-download event emitting a download-start event, and when the item is done, emitting a download-done event from the DownloadItem's done event up to Nightmare. My sample application simply keeps track of the number of downloads in progress and uses (more or less) the same approach as wait until all of the downloads are complete. In other words, it's hacky and works, but I'm struggling to come up with a less-hacked together approach.
  4. If #338 were folded in, we could reuse the override path to dictate where downloads go. That might make for cleaner options and easier cleanup.
  5. If the server doesn't immediately respond to the action that triggers a download (your example in #151 exhibits this behavior), the will-download event might be triggered after Nightmare has already moved on. My current "fix" is to simply wait, but I don't think there's a method to expect an outcome from an action, eg clicking on a link and expecting a download to start.

I put the changes up on a branch in my fork. I put up a hastily thrown together minimal sample as a gist for the curious.

santeriv commented 8 years ago

@rosshinkley :+1: for sharing fork and a how-to-gist and +1 for feature

rosshinkley commented 8 years ago

@santeriv This is a bit out of date. I redid the solution for will-download and submitted a PR (#382), but it's been closed pending adding Electron extensions (#391). If you want to use a fork to handle will-download, I'd suggest using that one for the time being. There are examples in the test suite to show how to use it. :)

rosshinkley commented 8 years ago

With the release of #425 in 2.3.0, I've gone ahead and released plugins that will take care of downloads:

I'm considering this issue resolved. If you have further questions or problems, please open a new issue.