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( 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;