Skip to content

Commit

Permalink
Explicitly set up IntersectionObserver mocking
Browse files Browse the repository at this point in the history
For some reason, upstream react-intersection-observer switched from
`beforeEach` to `beforeAll` in v9.12.0:
- https://github.com/thebuilder/react-intersection-observer/pull/690/files#diff-26d4dc52e61d263a4256bed7c9ae3a9044b18a52f96f4f6840ca46336fb9216fL23-L24
- https://github.com/thebuilder/react-intersection-observer/releases/tag/v9.12.0

This led to errors on our side:

    Error: Uncaught [TypeError: observer.observe is not a function]

I'm not entirely sure what the reason is (it looks like the mock
gets unset every test?), but this restores it to its previous
behaviour, and in a way that doesn't look particularly likely for
upstream to break, so I think that's fine for now.

Initially I also set
https://www.typescriptlang.org/docs/handbook/modules/reference.html#bundler
to import from `react-intersection-observer/test-utils`, but that
caused issues elsewhere (in particular when importing from
`@mozilla/glean/web`), so I reverted that since our tests aren't
type-checked anyway. I did make a couple of adjustments elsewhere
to be compatible with both that setting and the previous value.
  • Loading branch information
Vinnl committed Aug 5, 2024
1 parent 978c422 commit 9dc1d63
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 13 deletions.
9 changes: 1 addition & 8 deletions jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,7 @@ const customJestConfig = {
setupFiles: ["jest-canvas-mock"],

// A list of paths to modules that run some code to configure or set up the testing framework before each test
setupFilesAfterEnv: [
"<rootDir>/jest.setup.ts",
// See https://www.benmvp.com/blog/avoiding-react-act-warning-when-accessibility-testing-next-link-jest-axe/
// Mocks the IntersectionObserver API, which is used by Next.js's <Link>.
// This prevents warnings about wrapping tests in act() for components that
// include <Link>s.
"react-intersection-observer/test-utils",
],
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],

// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
Expand Down
12 changes: 11 additions & 1 deletion jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import "jest-axe/extend-expect";
import { TextEncoder } from "util";
import { setProjectAnnotations } from "@storybook/react";
import { defaultFallbackInView } from "react-intersection-observer";
import {
resetIntersectionMocking,
setupIntersectionMocking,
} from "react-intersection-observer/test-utils";
import failOnConsole from "jest-fail-on-console";
import * as globalStorybookConfig from "./.storybook/preview";

Expand All @@ -29,11 +33,17 @@ failOnConsole({
// If no `IntersectionObserver` exists, Next.js's <Link> will do a state update
// immediately after rendering, causing warnings about wrapping tests in act().
global.IntersectionObserver = jest.fn();
// Then in jest.config.cjs, we add an actual mock for the IntersectionObserver
// Then before every test, we add an actual mock for the IntersectionObserver
// API in `setupFilesAfterEnv`. When a <Link> scrolls into view, Next.js will
// attempt to preload the target, causing another rerender that would cause a
// warning about wrapping tests in act(). Thus, we tell it it's not in view.
defaultFallbackInView(false);
beforeEach(() => {
setupIntersectionMocking(jest.fn);
});
afterEach(() => {
resetIntersectionMocking();
});

global.TextEncoder = TextEncoder;

Expand Down
4 changes: 2 additions & 2 deletions src/app/api/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import {
import { getTemplate } from "../../../emails/email2022.js";
import { signupReportEmailPartial } from "../../../emails/emailSignupReport.js";
import { getL10n } from "../../functions/l10n/serverComponents";
import { OAuthConfig } from "next-auth/providers/oauth.js";
import { SerializedSubscriber } from "../../../next-auth.js";
import { OAuthConfig } from "next-auth/providers/oauth";
import { SerializedSubscriber } from "../../../next-auth";
import { record } from "../../functions/server/glean";

const fxaProviderConfig: OAuthConfig<FxaProfile> = {
Expand Down
6 changes: 4 additions & 2 deletions src/app/components/client/GoogleAnalyticsWorkaround.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

"use client";

import { GAParams } from "@next/third-parties/dist/types/google";
import type { GoogleAnalytics } from "@next/third-parties/google";
import Script, { ScriptProps } from "next/script";
import { useEffect } from "react";
import { ComponentProps, useEffect } from "react";

// We don't send Analytics events in tests:
/* c8 ignore start */

let currDataLayerName: string | undefined = undefined;

type GAParams = ComponentProps<typeof GoogleAnalytics>;

/**
* This component is based on <GoogleAnalytics> from `@next/third-parties`, but accepting a nonce
*
Expand Down

0 comments on commit 9dc1d63

Please sign in to comment.