From 59579df241d2807f3d878fc80881e02e977d8159 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 20 Feb 2026 11:12:51 -0800 Subject: [PATCH] Add Intersection Observer E2E tests for FB Summary: Updated approach to render IntersectionObserver examples for E2E testing. Updated some of the examples to be friendlier for e2e assertions Differential Revision: D92897290 --- .../IntersectionObserverClippingParent.js | 117 ++++++++---------- .../IntersectionObserverExplicitRootScroll.js | 7 ++ 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverClippingParent.js b/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverClippingParent.js index a0b8381bf5b2..c8c3cf013478 100644 --- a/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverClippingParent.js +++ b/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverClippingParent.js @@ -15,6 +15,7 @@ import type IntersectionObserverEntry from 'react-native/src/private/webapis/int import * as React from 'react'; import {useCallback, useLayoutEffect, useRef, useState} from 'react'; import {Button, StyleSheet, Text, TextInput, View} from 'react-native'; +import DOMRectReadOnly from 'react-native/src/private/webapis/geometry/DOMRectReadOnly'; export const name = 'IntersectionObserver Parent Clipping Example'; export const title = name; @@ -22,48 +23,33 @@ export const description = 'A clipping parent clips both the root and target'; declare var IntersectionObserver: Class; -export function render(): React.Node { - return ; +export function render(options?: {e2eTest?: boolean}): React.Node { + return ( + + ); } /** - * Showcase threshold of two overlapping elements + * Formats a DOMRectReadOnly for display with a label. */ -function roundRect(rect: unknown): ?{ - x: number, - y: number, - width: number, - height: number, -} { +function formatRect(label: string, rect: ?DOMRectReadOnly): ?string { if (rect == null || typeof rect !== 'object') { return null; } - // $FlowFixMe[prop-missing] - const x = rect.x; - // $FlowFixMe[prop-missing] - const y = rect.y; - // $FlowFixMe[prop-missing] const width = rect.width; - // $FlowFixMe[prop-missing] const height = rect.height; - if ( - typeof x !== 'number' || - typeof y !== 'number' || - typeof width !== 'number' || - typeof height !== 'number' - ) { + if (typeof width !== 'number' || typeof height !== 'number') { return null; } - return { - x: Math.round(x), - y: Math.round(y), - width: Math.round(width), - height: Math.round(height), - }; + return `${label}: width:${Math.round(width)}, height:${Math.round(height)}`; } -component IntersectionObserverCustomClippingRootExample() { +component IntersectionObserverCustomClippingRootExample( + e2eTest: boolean = false, +) { const rootRef = useRef(null); const targetRef = useRef(null); const [intersectionEntry, setIntersectionEntry] = @@ -136,35 +122,39 @@ component IntersectionObserverCustomClippingRootExample() { Current Root Margin: {rootMarginValue} - - This example highlights a clipping parent to both the explicit root - (blue) and target (yellow). The dashed borders show the full extent of - the root and target, while the solid colors show what's actually visible - after clipping. The purple dashed border shows the root bounds after - applying rootMargin. - - - - - Clipping Area (100x100) - - - - Root (visible) - - - - Target (visible) - - - - Full extent (dashed) - - - - Root + Margin (purple) + {!e2eTest && ( + + This example highlights a clipping parent to both the explicit root + (blue) and target (yellow). The dashed borders show the full extent of + the root and target, while the solid colors show what's actually + visible after clipping. The purple dashed border shows the root bounds + after applying rootMargin. + + )} + {!e2eTest && ( + + + + Clipping Area (100x100) + + + + Root (visible) + + + + Target (visible) + + + + Full extent (dashed) + + + + Root + Margin (purple) + - + )} @@ -214,16 +204,19 @@ component IntersectionObserverCustomClippingRootExample() { {(intersectionEntry.intersectionRatio * 100).toFixed(1)}% - Intersection Rect:{' '} - {JSON.stringify(roundRect(intersectionEntry.intersectionRect))} + {formatRect( + 'Intersection Rect', + intersectionEntry.intersectionRect, + )} - Bounding Client Rect:{' '} - {JSON.stringify(roundRect(intersectionEntry.boundingClientRect))} + {formatRect( + 'Bounding Client Rect', + intersectionEntry.boundingClientRect, + )} - Root Bounds:{' '} - {JSON.stringify(roundRect(intersectionEntry.rootBounds))} + {formatRect('Root Bounds', intersectionEntry.rootBounds)} )} diff --git a/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js b/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js index 2dfdea9f879e..bf8834465010 100644 --- a/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js +++ b/packages/rn-tester/js/examples/IntersectionObserver/IntersectionObserverExplicitRootScroll.js @@ -65,6 +65,7 @@ component IntersectionObserverExplicitRootScrollExample() { }} ref={roofRef}>