cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.73k stars 3.16k forks source link

Enable devs to build managed & ergonomic env var access on top of Cypress, by surfacing the built-in environment resolution logic in node #29094

Open adamscybot opened 6 months ago

adamscybot commented 6 months ago

What would you like?

This request is what I believe to be the minimal requirement to enable a developer to implement certain use cases themselves in a sensible and extendable way.

The wider requirement that drives this is perhaps interesting in it itself, and will become evident. But I realise Cypress going further to cover that wider req would be a bigger deal and it would reach into "opinionated" territory, and so I am scoping my request to what would be needed in order for it to be better served in user-land. Thankfully, I think this is fairly minimal, but I want to explain why you'd want such a granular enhancement, so I've provided the wider context.

When a user calls Cypress.env([key]), they are receiving a value that has been processed by some internal Cypress logic. Cypess.env is currently accessible only inside the spec file. According to my understanding, this logic:

I would like a way to call into that same resolution logic statically, but from the node backend.

Why is this needed?

On extensive, distributed and complex systems, I have regularly found that:

I don't want to mess up the way Cypress ingests env vars and break dev expectations. I also need those different ways for CI vs local scenarios anyway. For that reason, I can only implement this "env processing/validation" layer sensibly on the browser side since the only way to resolve the env vars in a way which matches the expectations of anyone reading the Cypress docs & also remains forwards-compatible, is to build a mechanism that involves the browser. Since only the browser can access Cypress.env and only Cypress.env can seemingly access the underlying logic.

That could be ignored but that would mean either:

To do it properly, you need to call Cypress.env() on the browser somewhere in the flow, which is also an issue from a security perspective if looking to manage secrets in a certain way. Everything I said up to this point is doable (I've done it). But only if you are good with sending all the env vars to the browser and having the schema in that browser bundle, just for calling Cypress.env() without having some pseudo-implementation of the resolution logic. Needing to do this brings about headaches also in wanting it both browser side and node side, since some logic might only be practically available in node. And I'd rather not deal with serialisation of some validation schema (think Zod).

I won't go into more detail since the userland for this stuff is quite complex and it would remain so after. The whole flow of it and complexities are something I don't expect Cypress to solve. Actually, some of this can be solved at build time in the preprocessor. But not if you wanna keep the nice Cypress env ingest but the env var resolution logic remains only in the browser runtime.

The ability to solve it nicely is hindered just by that the default env var resolution code is not statically accessible from node. Not necessarily as a mirror of Cypress.env() (by the way I realise that also allows a set operation, and so that might introduce confusion, since nothing here needs a no-effort "universal" env between both sides). Even a totally separate unsupported static import available to node for advanced use that has no direct impact on Cypress.env would be great, in order to build our own impl properly. Perhaps it could be in a new meta object provided to setupNodeEvents?

It'd be amazing if this whole thing was considered at a higher level, but tbh even an escape hatch would be great.

I will buy Cypress team doughnuts. Screenshot it.

Also if there's an escape hatch I don't know about, that would be legendary.

Other

I am a long time Cypress user. I have introduced and put it into the pipeline in several companies; and these patterns have emerged multiple times over that time. I have implemented them, but it's only doable in a suboptimal way if you don't want to reimplement the Cypress env resolution; self-limit to a certain way of providing the vars that breaks user expectations; or maintain security.

jennifer-shehane commented 6 months ago

@adamscybot I have seen pretty complex uses of Cypress.env also. The security aspect bleeds over into another discussion of us needing to expose more ways to mask sensitive data, so I'd expect that to come in some way in a future release.

Can you show your workaround for this today? Psuedo code is fine also.

cypress-app-bot commented 1 week ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.