Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cy.session: Caching across spec files #17710

Closed
halfninja opened this issue Aug 12, 2021 · 15 comments · Fixed by #23904
Closed

cy.session: Caching across spec files #17710

halfninja opened this issue Aug 12, 2021 · 15 comments · Fixed by #23904
Assignees
Labels
topic: session Issues when using session command type: enhancement Requested enhancement of existing feature

Comments

@halfninja
Copy link

What would you like?

The new cy.session is amazing and just what we wanted - the behaviour with cypress open where this feature caches across spec files is something we'd like to have as an option for cypress run as well if possible.

Why is this needed?

In many cases authentication sessions are reliably the same between spec files, and starting with a blank cy.session cache for each file isn't necessary. I understand that the reason may be more technical, since the runner may be opening each spec file in a brand new context where it's hard to carry session data around.

Other

Just further thanks for cy.session! 🎉

@jennifer-shehane jennifer-shehane added topic: session Issues when using session command type: unexpected behavior User expected result, but got another labels Aug 27, 2021
@IanVS
Copy link
Contributor

IanVS commented Oct 4, 2021

This would be incredibly useful for my auth flow, which involves a magic link being sent to an email box and two-factor authentication. The auth takes quite a while to complete, and it would be awesome to cache the result across specs.

@bahmutov
Copy link
Contributor

bahmutov commented Oct 4, 2021

You could do this using cypress-data-session plugin https://github.com/bahmutov/cypress-data-session#videos

@henry-filosa henry-filosa mentioned this issue Nov 30, 2021
5 tasks
@cypress-bot cypress-bot bot added the stage: needs review The PR code is done & tested, needs review label Nov 30, 2021
@henry-filosa
Copy link

I created a PR to advance discussion on a possible implementation of this. I'd also advocate for possibly removing the cache clearing behavior from run mode as it can be exactly replicated by invoking Cypress.session.clearAllSavedSessions()
in a before:spec hook. However, there is currently no option to disable.

I looked at the closed roadmap for the session feature, but it differs a fair bit from what we currently have. Is there a planning document for where the team is expecting to take the API of sessions in the future?

@romankhomitskyi
Copy link

I created a PR to advance discussion on a possible implementation of this. I'd also advocate for possibly removing the cache clearing behavior from run mode as it can be exactly replicated by invoking Cypress.session.clearAllSavedSessions() in a before:spec hook. However, there is currently no option to disable.

I looked at the closed roadmap for the session feature, but it differs a fair bit from what we currently have. Is there a planning document for where the team is expecting to take the API of sessions in the future?

Just curious, wouldn't it be better just add option not to clear local storage, cookies rather than creating huge API that is difficult to pick up?

@henry-filosa
Copy link

@romankhomitskyi You'll probably addressing this question at the Cypress team, but I'd like to answer as someone who's excited about this development. It brings local storage and cookies in line with the Cypress principle of setting up state before each test. This ensures greater test isolation for less flake.
Plus, it's already an optional flag so if you don't like it you can just not enable. However, it doesn't make sense to cache cookies if you're not clearing them.

@romankhomitskyi
Copy link

@romankhomitskyi You'll probably addressing this question at the Cypress team, but I'd like to answer as someone who's excited about this development. It brings local storage and cookies in line with the Cypress principle of setting up state before each test. This ensures greater test isolation for less flake. Plus, it's already an optional flag so if you don't like it you can just not enable. However, it doesn't make sense to cache cookies if you're not clearing them.

I am just wondering what kind of flake could be in my flow, where I created bunch of it() to check only one page, and after first it() I get logged out
As it was said before, most of the time you do not want to clear local storage
There might be a flake in cy.session down the road, that might not be fixed asap, so we can't rely on it(

@henry-filosa
Copy link

Those are questions that are really only answerable by you and your unique application. However, a "bunch of it() to check only one page" is probably not following best practices. But again, Cypress is flexible enough for you to follow the workflow you described.

I think a larger discussion about the merits of the API would be more appropriate in another forum.

@henry-filosa
Copy link

henry-filosa commented Dec 9, 2021

In future versions the behavior of Cypress in open mode will match that of run mode.. It seems this desired behavior is out of line with where the API is going. For those interested in pursuing such behavior I can confirm that @bahmutov's plugin provides a solution.

However, it seems inadvisable if you may want parallelization at some point for your project, which can deliver large speedups. When parallelized, spec files are routed nondeterministically to different virtual machines. It's not possible (at least as far as I can see) to share state between these machines, therefore each spec file should be written as if it could run in any combination of other spec files running. For our part, we have decided to look back at our architecture to find a different solution that works within this limitation.

@IanVS
Copy link
Contributor

IanVS commented Dec 13, 2021

I understand the benefits of parallelization and test isolation, but shouldn't there be some kind of way to set up and store auth state? Especially for complex auth flows that involve sending and checking emails?

@henry-filosa
Copy link

The response on the PR:

Does your solution work when running tests in parallel across several machines? If not, then this will introduce non-determinism when running tests in parallel versus not. This is not behavior we want to introduce unless it behaves the same across all cypress run situations.

It seems a state sharing solution will have to work in parallel mode for it to make it into the Cypress project. Bahmutov's plugin seems like a good solution if that's not a concern for you.

@IanVS
Copy link
Contributor

IanVS commented Dec 13, 2021

Ideally, there would be a way to run a login spec first, cache the session, and then use it across the rest of the tests in parallel.

@henry-filosa
Copy link

You could do that in your plugin file and then access the information from the environmental variables. Getting that to work in a parallelized setup would be another matter however.

@DanJFletcher
Copy link

DanJFletcher commented Feb 1, 2022

I wish Cypress handled this too. There's a couple of options to roll this yourself in a way that works in parallel too.

Ultimately you need a file that can be used to persist session data across spec files. With a cypress task you can read/write to files from within a node process.

In my case I made a credentials.json file with the structure:

{
  "<email + password>": {<session data>}
}

Where email and password is concatenated to make a unique key and the value is the session data I need.

You can use this data to restore any required state in localstorage or use it as a way to mock the login request. I updated my login command to behave similar to cy.session in that it does a real login if there's no cached session but if there is a session, it restores that instead.

It also saves the session to the credentials.json file after a successful login attempt (creates it if it doesn't exist already).

This works across multiple spec files while still working if they run in parallel. The caveat is that each runner will maintain its own credentials.json file but I don't personally think that's a big deal. If you thought it was a big deal you'd have to write to a central cache that all your runners have access to.

@cypress-bot cypress-bot bot added stage: backlog and removed stage: needs review The PR code is done & tested, needs review labels Apr 29, 2022
@emilyrohrbough emilyrohrbough added type: enhancement Requested enhancement of existing feature stage: proposal 💡 No work has been done of this issue and removed type: unexpected behavior User expected result, but got another labels May 3, 2022
@cypress-bot cypress-bot bot added stage: icebox and removed stage: proposal 💡 No work has been done of this issue stage: backlog labels May 23, 2022
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Sep 26, 2022

The code for this is done in cypress-io/cypress#23904, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@cypress-bot cypress-bot bot added stage: pending release and removed stage: needs review The PR code is done & tested, needs review labels Sep 26, 2022
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Sep 27, 2022

Released in 10.9.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v10.9.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Sep 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
topic: session Issues when using session command type: enhancement Requested enhancement of existing feature
Projects
None yet
9 participants