segment-boneyard / nightmare

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

No function to remove specific/all cookies #202

Closed ghost closed 8 years ago

ghost commented 9 years ago

Hello there! It seems as if there's no function for removing cookie(s) stored? By any chance could someone add this? I think it would be super useful

alfonmga commented 9 years ago

We need this, PhantomJS has it...

ghost commented 9 years ago

That's the one thing I hate @alfonsomga , I love NightmareJS, but there's no functions built-in for manipulating cookies. I'm going to start looking at the NightmareJS code soon, and perhaps I can figure out a way to do such.

mathisonian commented 8 years ago

:+1: for this. would a PR be welcome?

rosshinkley commented 8 years ago

Sorry to poke a head in: wouldn't setting a cookie and clearing a cookie by name for the current domain work? Is there something i'm missing?

mathisonian commented 8 years ago

@rosshinkley - that works well generally.

For this specific use case I am trying to start the nightmare / electron process clear of cookies. As far as I can tell there's not an easy way to do that with the current api.

rosshinkley commented 8 years ago

@mathisonian True, clearing all cookies is not currently supported, at least directly. I say go for a PR, then.

johanneslumpe commented 8 years ago

@mathisonian to build upon @rosshinkley's response: you could issue a single request to the domain and clear all the cookies before you do your actual requests. That way the second request will be free of cookies.

rosshinkley commented 8 years ago

@johanneslumpe Unless I'm missing something (a very real, very big possibility), you'd have to use .evaluate() to retrieve and parse the cookie names yourself. Then you could iterate over them and use .cookies.clear().

It's certainly doable out of the box, but it would be nice to have something a little more convenient.

johanneslumpe commented 8 years ago

@rosshinkley Oh yeah, if you do not know the cookie names beforehand, then probably yes. For my case I know which cookies I need to delete, so just doing a request and clearing those cookies seems to work fine. The original request will still be sent with the cookies, but the 2nd one will be fine.

Mr0grog commented 8 years ago

I know this thread’s been sitting a while, but hopefully this note helps someone. For the use case of “trying to start the nightmare / electron process clear of cookies,” you can actually do that and it’s pretty easy! It’s entirely undocumented, though, so it’s not surprising if you don’t know about it.

When you create an Nightmare instance, it uses what’s called a “partition” to store data—cookies, cache, history, localStorage, etc. Normally, every instance shares the same default partition, which gets stored to disk. However, you can tell it to use a different partition. Just set the webPreferences.partition property in the options object when creating a new Nightmare instance:

var browser = Nightmare({
  webPreferences: {
    partition: 'your-custom-partition'
  }
});
browser
  .goto('somewhere')
  .evaluate(...)
  .then(...);

The value for webPreferences.partition is just a string identifying the partition you want to use. The string can be anything you want; if there’s no existing partition with that name, a new one will be created. If the name of the partition starts with persist:, the data it stores will be saved to disk. Otherwise, it will be an in-memory partition, which means the data is thrown out when no more Nightmare instances are using it. You can actually see an example of this in action in the cookie tests: https://github.com/segmentio/nightmare/blob/master/test/index.js#L531 (because we want the tests to start fresh every time ;)

lgg commented 8 years ago

@Mr0grog I don't understand how handle .cookies.get()

nightmare
    .goto(url)
    .cookies.get()
    //now here I want to go forEach with cookies, but how?
Mr0grog commented 8 years ago

@littleguga You can do it the same way you work with any nightmare actions that return values:

nightmare
  .goto(url)
  .cookies.get()
  .then(function(cookieList) {
    // loop through cookieList (an array of cookies) here
  });

This is the same way the first example in the readme gets the top search result’s URL. Because everything in Nightmare is asynchronous, you use the then() promise method to wait for the actual result.

rosshinkley commented 8 years ago

For what it's worth, here's a sample of clearing the cookies manually:

var Nightmare = require('nightmare'),
  nightmare = Nightmare();

nightmare.goto('http://yahoo.com')
  //get the cookies
  .cookies.get()
  .then((cookies) => {
    //extract the names
    return cookies.map((cookie) => cookie.name)
      //for each name, clear the cookie and return the promise to be resolved
      .reduce((accumulator, name) => accumulator.then(() =>
        nightmare.cookies.clear(name)), Promise.resolve())
  })
  //get the cookies again
  .then(() => nightmare.cookies.get())
  //display the cookies
  //note they should be an empty array
  .then((cookies) => {
    console.dir(cookies);
    //end the nightmare instance
    return nightmare.end()
  })
  .then(function() {
    console.log('done');
  });
rosshinkley commented 8 years ago

Fixed with #652. Closing.