From 0335fec09c6b9dbdcd3e9ca6da1cbd470d8580e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Fri, 29 May 2026 07:10:39 -0700 Subject: [PATCH 1/2] Add Fantom.getHostPlatform() to expose test runner host OS (#56990) Summary: Adds a new `Fantom.getHostPlatform()` API that returns the host operating system where the Fantom test runner is running (e.g. 'linux', 'macos', 'windows', 'android'). This is different from React Native's `Platform.OS`, which always reflects the React Native target platform being tested. The value is determined by the Node.js Jest runner (via `process.platform`) and baked into the JS bundle through the existing `setConstants(...)` pipeline, so no native changes are needed. - Add `HostPlatform` type and `hostPlatform` field to `FantomRuntimeConstants`. - Populate `hostPlatform` from the host platform in the entrypoint template (maps darwin -> macos, win32 -> windows, etc.). - Expose `getHostPlatform()` from the public Fantom API. Changelog: [Internal] Reviewed By: javache Differential Revision: D106669673 --- .../runner/entrypoint-template.js | 23 ++++++++++++++++++- private/react-native-fantom/src/Constants.js | 4 ++++ private/react-native-fantom/src/index.js | 11 +++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/private/react-native-fantom/runner/entrypoint-template.js b/private/react-native-fantom/runner/entrypoint-template.js index 2010fb54a46b..0c3c3becb04d 100644 --- a/private/react-native-fantom/runner/entrypoint-template.js +++ b/private/react-native-fantom/runner/entrypoint-template.js @@ -9,12 +9,32 @@ */ import type {SnapshotConfig} from '../runtime/snapshotContext'; -import type {FantomRuntimeConstants} from '../src/Constants'; +import type {FantomRuntimeConstants, HostPlatform} from '../src/Constants'; import type {FantomTestConfig} from './getFantomTestConfigs'; import * as EnvironmentOptions from './EnvironmentOptions'; import formatFantomConfig from './formatFantomConfig'; +function getHostPlatform(): HostPlatform { + match (process.platform) { + 'darwin' => { + return 'macos'; + } + 'win32' => { + return 'windows'; + } + 'linux' => { + return 'linux'; + } + 'android' => { + return 'android'; + } + _ => { + throw new Error(`Unsupported platform: ${process.platform}`); + } + } +} + module.exports = function entrypointTemplate({ testPath, setupModulePath, @@ -42,6 +62,7 @@ module.exports = function entrypointTemplate({ jsTraceOutputPath, jsHeapSnapshotOutputPathTemplate, jsHeapSnapshotOutputPathTemplateToken, + hostPlatform: getHostPlatform(), }; return `/** diff --git a/private/react-native-fantom/src/Constants.js b/private/react-native-fantom/src/Constants.js index ffd8f3504df9..8ef0bb2af88b 100644 --- a/private/react-native-fantom/src/Constants.js +++ b/private/react-native-fantom/src/Constants.js @@ -8,6 +8,8 @@ * @format */ +export type HostPlatform = 'android' | 'windows' | 'macos' | 'linux'; + export type FantomRuntimeConstants = Readonly<{ isOSS: boolean, isRunningFromCI: boolean, @@ -16,6 +18,7 @@ export type FantomRuntimeConstants = Readonly<{ jsHeapSnapshotOutputPathTemplate: string, jsHeapSnapshotOutputPathTemplateToken: string, jsTraceOutputPath: ?string, + hostPlatform: HostPlatform, }>; let constants: FantomRuntimeConstants = { @@ -26,6 +29,7 @@ let constants: FantomRuntimeConstants = { jsHeapSnapshotOutputPathTemplate: '', jsHeapSnapshotOutputPathTemplateToken: '', jsTraceOutputPath: null, + hostPlatform: 'linux', }; export function getConstants(): FantomRuntimeConstants { diff --git a/private/react-native-fantom/src/index.js b/private/react-native-fantom/src/index.js index 73e40ba9d661..e290f00c492b 100644 --- a/private/react-native-fantom/src/index.js +++ b/private/react-native-fantom/src/index.js @@ -8,6 +8,7 @@ * @format */ +import type {HostPlatform} from './Constants'; import type { FantomRenderedOutput, RenderOutputConfig, @@ -46,6 +47,16 @@ export type RootConfig = { export {getConstants} from './Constants'; +/** + * Returns the host OS where the Fantom test runner is running (e.g. + * 'linux', 'macos', 'windows'). This is different from React Native's + * `Platform.OS`, which always reflects the React Native target platform + * being tested. + */ +export function getHostPlatform(): HostPlatform { + return getConstants().hostPlatform; +} + // Defaults use iPhone 14 values (very common device). const DEFAULT_VIEWPORT_WIDTH = 390; const DEFAULT_VIEWPORT_HEIGHT = 844; From e9908567254d5923fad0895983f991792fec817f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Fri, 29 May 2026 07:10:39 -0700 Subject: [PATCH 2/2] Skip Performance timeOrigin test on macOS hosts (#56991) Summary: The `timeOrigin` test in `Performance-itest` compares `performance.now() + performance.timeOrigin` against `Date.now()`. On macOS this comparison is unreliable because `performance.now()` is backed by a monotonic clock that does NOT advance while the system is asleep, so the monotonic time drifts relative to wall time the longer the machine has been running. Use the new `Fantom.getHostPlatform()` to skip just this test on macOS hosts while keeping it active on other platforms. A comment explains why the test cannot be run there. Also adds a small test verifying that `performance.timeOrigin` is a positive number and is stable across calls. Changelog: [Internal] Reviewed By: javache Differential Revision: D106669674 --- .../__tests__/Performance-itest.js | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/react-native/src/private/webapis/performance/__tests__/Performance-itest.js b/packages/react-native/src/private/webapis/performance/__tests__/Performance-itest.js index 1572338f3c04..8e2ea9654f56 100644 --- a/packages/react-native/src/private/webapis/performance/__tests__/Performance-itest.js +++ b/packages/react-native/src/private/webapis/performance/__tests__/Performance-itest.js @@ -10,6 +10,8 @@ import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; +import * as Fantom from '@react-native/fantom'; + describe('Performance', () => { it('does NOT allow creating instances of Performance directly', () => { expect(() => { @@ -40,7 +42,24 @@ describe('Performance', () => { }); describe('timeOrigin', () => { - it('allows moving timestamps to Unix epoch', () => { + it('is a positive number that does not change between calls', () => { + const first = performance.timeOrigin; + const second = performance.timeOrigin; + + expect(typeof first).toBe('number'); + expect(first).toBeGreaterThan(0); + expect(second).toBe(first); + }); + + // On macOS, `performance.now()` is backed by a monotonic clock that does + // NOT include time spent while the system is asleep. This causes the + // monotonic time to drift relative to wall time (`Date.now()`) the longer + // the machine has been running, so we can't reliably compare + // `performance.now() + performance.timeOrigin` against `Date.now()` like + // we can on other platforms. + const itIfNotMacOS = Fantom.getHostPlatform() === 'macos' ? it.skip : it; + + itIfNotMacOS('allows moving timestamps to Unix epoch', () => { // We need to truncate timestamps because `Date.now()` only provides // integer millisecond precision. const adjustedMonotonicTime = Math.trunc(