If you want to do it with the whole page and talk only to the local code, then yes, I'd recommend Sinon. I think that's a much simpler solution than . . . creating an all new NIH framework!
I'd also recommend refactoring to a more mock-friendly way to do that countdown if you don't want to cover up all the internal logic.
If the timeout interval is loaded remotely from some API (and it probably is if you have reasonably configurable nag popups), then you can always mock that API call.
The point is that you shouldn't need to rewrite your countdown component to allow testing. Can you provide a snippet of that change and what the test would look like?
Not being toggle parts of the app is the root of the issue when creating e2e tests. For example overriding a feature flag, you could find the API call for the feature but what if it's a grpc call and part of your dev build pulls in any update, you can't easily change the binary response with confidence anymore.
The current solutions are good enough to do smoke tests, but nitty-gritty e2e tests don't scale well.
i think the library's approach to DI is pretty neat (and meets a team where they are which is worth a lot), but i think you're running into an issue where people are saying that instead of working around the realities of your codebase, team and testing needs, you should have done something like this.
i'll say, i have never written a test for a hook or looked into what's needed to actually do that, but i suspect you don't need cypress or webdriver to test something like this has the correct output
or likewise you can probably use sinon or jest's fake timers to test the hook (however it is hooks are tested without triggering that error about not calling hooks outside of a function component, i guess you need to mock React.useState?).
but like, whatever works for your team! i think it's fair to argue for either direction, but neither is zero-cost unless you have buy-in for one direction vs another from your coworkers, which honestly is all that matters especially if you have to eat lunch with them occasionally.
Creating an override is basically just providing a placeholder for a value to be injected via React Context. I view this as a form of dependency injection. Contrast this with how this would be done in vanilla Playwright with reading it from a query param or exposing a global to call page.evaluate on which is more along the lines of forcing test code into a component.
Note that if you needed a specific reference in an override there isn't a good way to get that via Playwright, consider this silly example:
Does it not feel a little old-fashioned to dynamically rebind stuff to force some code to be testable, rather than just write it to be testable in the first place? If I saw someone doing this in any other test suite I’d suggest making the dependencies explicit.
Comments
If you want to do it with the whole page and talk only to the local code, then yes, I'd recommend Sinon. I think that's a much simpler solution than . . . creating an all new NIH framework!
I'd also recommend refactoring to a more mock-friendly way to do that countdown if you don't want to cover up all the internal logic.
If the timeout interval is loaded remotely from some API (and it probably is if you have reasonably configurable nag popups), then you can always mock that API call.
The point is that you shouldn't need to rewrite your countdown component to allow testing. Can you provide a snippet of that change and what the test would look like?
Not being toggle parts of the app is the root of the issue when creating e2e tests. For example overriding a feature flag, you could find the API call for the feature but what if it's a grpc call and part of your dev build pulls in any update, you can't easily change the binary response with confidence anymore.
The current solutions are good enough to do smoke tests, but nitty-gritty e2e tests don't scale well.
In the example above it's simple
If I needed something like this, I'd probably also make setInterval an override as well, so I don't need to wait at all, but you get the idea.i think the library's approach to DI is pretty neat (and meets a team where they are which is worth a lot), but i think you're running into an issue where people are saying that instead of working around the realities of your codebase, team and testing needs, you should have done something like this.
i'll say, i have never written a test for a hook or looked into what's needed to actually do that, but i suspect you don't need cypress or webdriver to test something like this has the correct output or likewise you can probably use sinon or jest's fake timers to test the hook (however it is hooks are tested without triggering that error about not calling hooks outside of a function component, i guess you need to mock React.useState?).but like, whatever works for your team! i think it's fair to argue for either direction, but neither is zero-cost unless you have buy-in for one direction vs another from your coworkers, which honestly is all that matters especially if you have to eat lunch with them occasionally.
I like the library, but isn't createOverride / useValue basically modifying components to allow testing?
Creating an override is basically just providing a placeholder for a value to be injected via React Context. I view this as a form of dependency injection. Contrast this with how this would be done in vanilla Playwright with reading it from a query param or exposing a global to call page.evaluate on which is more along the lines of forcing test code into a component.
Note that if you needed a specific reference in an override there isn't a good way to get that via Playwright, consider this silly example:
Should it be general framework focused on DI for React? That can make overrides more organic and have more benefits than just testing
Does it not feel a little old-fashioned to dynamically rebind stuff to force some code to be testable, rather than just write it to be testable in the first place? If I saw someone doing this in any other test suite I’d suggest making the dependencies explicit.