kolodny

Joined 13 years ago

Karma
1,145
Submissions
226
Member since
Mar 31
Github: https://github.com/kolodny

Blog: http://kolodny.github.io/blog/

Linkedin: https://www.linkedin.com/in/moshekolodny

View on Hacker News

Recent submissions

Comment · 2 years ago
React is pretty performant when context isn't changing. We haven't done any benchmarking but I doubt there's any real world perf hit. For large applications the number of overrides tend to be under 20.

Overrides are opt-in so you can just expose any overridable value as a prop and run a isolated component test on it.

Comment · 2 years ago
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:

    it('can test spies', async () => {
      const spy = browserMock.fn();
      const { page } = await render(
        app =>
          <LogoutButtonAction.Override with={() => spy}>
            {app}
          <LogoutButtonAction.Override>
      );

      await page.getByText('Log out').click();
      expect(await spy).toHaveBeenCalled();
    });
Comment · 2 years ago
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

    export const CountdownTime = createOverride(60);
    export const Countdown = () => {
      const initialTime = CountdownTime.useValue();
      const [time, setTime] = React.useState(initialTime);
      React.useEffect(() => {
        const interval = setInterval(() => {
          setTime(t => t - 1);
          if (t === 1) clearInterval(interval);
        }, 1000);

        return () => clearInterval(interval)
      }, []);

      return time > 0 ? <>Time left {time}</> : <>Done</>
    };

    it('tests faster', async () => {
      const { page } = await render(
        app => <CountdownTime.Override with={() => 5}>{app}</CountdownTime.Override>
      );
      await expect(page.getByText('Done')).not.toBeVisible();
      page.waitForTimeout(5000);
      await expect(page.getByText('Done')).toBeVisible();
    });

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.
Comment · 2 years ago
Comment · 2 years ago
Comment · 2 years ago
Can you clarify what you mean? Usually, e2e testers don't have a bootstrapping stage for app-level changes, only for things that can be done via the browser automation APIs.
Comment · 2 years ago
Yes, that's correct. You get all the benefits of react-testing-library mounting and the ability to test the entire app as a unit.
Comment · 6 years ago

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton