Skip to content

[FSSDK-13287] Add React Native Metro tests for optional dependencies - #1180

Open
raju-opti wants to merge 2 commits into
masterfrom
raju/rn-test
Open

raju-opti wants to merge 2 commits into
masterfrom
raju/rn-test

Conversation

@raju-opti

Copy link
Copy Markdown
Contributor

Summary

  • New test suite, tests/react-native-metro/: checks how the SDK behaves in React Native apps when fast-text-encoding, react-native-get-random-values and @react-native-async-storage/async-storage are installed, missing, or replaced by the app's own polyfill or store.
  • Two Metro setups: React Native 0.73 (Metro 0.80, which has the dependency-map bug behind [FSSDK-13287] Make React Native polyfills optional and isolate optional requires #1179) and React Native 0.87 (fixed Metro). Each is a fixture with @react-native/metro-config, metro and Babel pinned by committed lockfiles. The react-native package isn't needed.
  • How a case runs (npm run test-rn-metro):
    1. The SDK is packed and installed the way an app installs it.
    2. A small test app is bundled with the fixture's real Metro and React Native Metro config, loaded through loadConfig as the RN CLI does. React Native's startup module is skipped because it needs native code. resolveRequest decides which optional packages exist; packages that need native code resolve to small JS stand-ins.
    3. The bundle runs in a fresh Node vm context, which has no TextEncoder or crypto, like older Hermes. Cases that need a native TextEncoder add one.
    4. The app records which implementation the SDK used, its decisions, the dispatched event UUIDs, and any errors. The runner checks these against each case's expectation and prints a results table.
  • Matches app behaviour: Metro's require is part of the bundle, so modules load exactly as in an app. The test app installs a non-throwing ErrorUtils handler, as React Native's startup code does, so a failed require outside module loading is reported as fatal (the red box) instead of rethrown to the caller.
  • CI: a new react_native_metro_test job runs on every PR (Ubuntu, Node 20, about a minute).

The device testing for #1179 was done by hand on simulators. This automates the part that broke, Metro's bundling and runtime require together with the SDK's optional import shims, on both a buggy and a fixed Metro. tests/react-native-metro/README.md explains the setup, how to add a case, and how to update a fixture.

Test plan

  • npm run test-rn-metro passes all 28 runs: 14 cases on each of RN 0.73 and RN 0.87.

    Cases What they cover Expected
    P1–P5 polyfill packages installed, or replaced by the app's own polyfills; including "package installed + custom polyfill", where the custom one must win works, with the expected implementation
    P6–P8 a needed global with no package or polyfill the SDK's error reported as fatal while it loads
    P9–P10 runtime with a native TextEncoder works; the native one is kept
    S1–S2 AsyncStorage v1/v2 and v3: events stored by one client are read back by a second works, via multiGet or the getMany-based multiGet
    S3–S4 no AsyncStorage, with a custom event store / with the default store works / "Module not found" thrown to the app
  • The test catches the original bug. Against an SDK build with the shims bundled into the main bundle (the layout before [FSSDK-13287] Make React Native polyfills optional and isolate optional requires #1179), 5 cases fail on RN 0.73 and all pass on RN 0.87: P2, P4, P5 and P9 got a false async-storage "Module not found", and S3's netinfo require became require(undefined), reported as fatal.

  • The existing checks don't pick up the new folder: lint, vitest and the platform-isolation check are unaffected. The workflow file was validated as YAML; the new job runs for the first time on this PR.

Issues

  • FSSDK-13287

🤖 Generated with Claude Code

Bundles a small test app with the Metro setup of React Native 0.73 (Metro 0.80,
which drops missing optional dependencies from a module's dependency map) and
React Native 0.87 (fixed Metro), and runs each bundle in a fresh Node vm
context. Cases cover fast-text-encoding, react-native-get-random-values and
AsyncStorage being installed, missing, or replaced by the app's own polyfill or
store, on runtimes with and without a native TextEncoder.

Runs with `npm run test-rn-metro` and as a CI job on every PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread tests/react-native-metro/fixtures/rn-0.73/package-lock.json
@coveralls

coveralls commented Oct 16, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 77.624%. remained the same — raju/rn-test into master

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The CI runtime is unsupported by the modern fixture, and assertions can accept failed decisions or unexpected fatal errors.

3 open findings
What changed in this PR

Adds Metro integration tests for the SDK’s optional React Native dependencies, automating regression coverage for the module-loading issue addressed by #1179.

Changes:

  • Tests 14 dependency and polyfill scenarios across two Metro fixtures.
  • Runs packaged SDK bundles in isolated contexts and checks runtime behavior.
  • Adds a test command, CI job, and maintenance documentation.
File Description
tests/​react-native-metro/​stubs/​react-native-get-random-values.js Supplies a test-only random-values polyfill.
tests/​react-native-metro/​stubs/​netinfo.js Replaces native connectivity APIs.
tests/​react-native-metro/​stubs/​async-storage-v3.js Simulates storage with getMany.
tests/​react-native-metro/​stubs/​async-storage-v2.js Simulates storage with multiGet.
tests/​react-native-metro/​run.mjs Installs, bundles, executes, and checks cases.
tests/​react-native-metro/​README.md Documents usage and fixture maintenance.
tests/​react-native-metro/​metro.config.base.js Controls optional dependency resolution.
tests/​react-native-metro/​fixtures/​rn-0.87/​package.json Defines the modern Metro fixture.
tests/​react-native-metro/​fixtures/​rn-0.87/​package-lock.json Locks modern fixture dependencies.
tests/​react-native-metro/​fixtures/​rn-0.87/​metro.config.js Connects modern Metro to shared configuration.
tests/​react-native-metro/​fixtures/​rn-0.73/​package.json Defines the older Metro fixture.
tests/​react-native-metro/​fixtures/​rn-0.73/​metro.config.js Connects older Metro to shared configuration.
tests/​react-native-metro/​cases.mjs Defines scenarios and expectations.
tests/​react-native-metro/​build.cjs Builds bundles with each fixture.
tests/​react-native-metro/​app/​test.js Exercises decisions, events, and storage.
tests/​react-native-metro/​app/​setup.js Installs custom polyfills and error reporting.
tests/​react-native-metro/​app/​index.js Starts testing after module initialization.
tests/​react-native-metro/​app/​datafile.json Supplies feature configuration.
package.json Exposes test-rn-metro.
.gitignore Excludes generated test artifacts.
.github/​workflows/​javascript.yml Adds the Metro CI job.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/javascript.yml Outdated
Comment thread tests/react-native-metro/run.mjs Outdated
if (!result) {
problems.push('no result');
} else {
if (Object.keys(result.decisions).length === 0) problems.push('no decisions');
Comment thread tests/react-native-metro/run.mjs Outdated
}
}
} else if (expect.fatal) {
if (!fatal.some((e) => e.message.includes(expect.fatal))) {
- Check decisions against the expected flag variations instead of only
  checking that decideAll() returned something.
- In fatal and caught-error cases, require every recorded error to be the
  expected one, so an unexpected error (such as a shifted require) can't hide.
- Run the CI job on Node 22; the RN 0.87 fixture's Metro requires Node
  ^22.13.0 || ^24.3.0 || >= 26.0.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants