diff --git a/packages/react-native-test-renderer/src/renderer/__tests__/render-test.js b/packages/react-native-test-renderer/src/renderer/__tests__/render-test.js index dfda1b812c44a6..f1776daee9c82b 100644 --- a/packages/react-native-test-renderer/src/renderer/__tests__/render-test.js +++ b/packages/react-native-test-renderer/src/renderer/__tests__/render-test.js @@ -45,4 +45,19 @@ describe('render', () => { expect(result.toJSON()).toMatchSnapshot(); }); }); + + describe('findAll', () => { + it('returns all nodes matching the predicate', () => { + const result = ReactNativeTestRenderer.render(); + const textNode = result.findAll(node => { + return node.props?.text === 'Hello'; + })[0]; + expect(textNode).not.toBeUndefined(); + + const viewNodes = result.findAll(node => { + return node.viewName === 'RCTView'; + }); + expect(viewNodes.length).toBe(2); + }); + }); }); diff --git a/packages/react-native-test-renderer/src/renderer/index.js b/packages/react-native-test-renderer/src/renderer/index.js index e3476cdcc082f2..0beebea01573cd 100644 --- a/packages/react-native-test-renderer/src/renderer/index.js +++ b/packages/react-native-test-renderer/src/renderer/index.js @@ -25,11 +25,10 @@ type FiberPartial = { }; type ReactNode = { - children: $ReadOnlyArray, + children: ?Array, props: {text?: string | null, ...}, viewName: string, instanceHandle: FiberPartial, - ... }; type RenderedNodeJSON = { @@ -41,12 +40,14 @@ type RenderedNodeJSON = { type RenderedJSON = RenderedNodeJSON | string; type RenderResult = { - toJSON: () => $ReadOnlyArray | RenderedJSON | null, + toJSON: () => Array | RenderedJSON | null, + findAll: (predicate: (ReactNode) => boolean) => Array, }; function buildRenderResult(rootNode: ReactNode): RenderResult { return { toJSON: () => toJSON(rootNode), + findAll: (predicate: ReactNode => boolean) => findAll(rootNode, predicate), }; } @@ -61,7 +62,7 @@ export function render(element: Element): RenderResult { }); // $FlowFixMe - const root: RootReactNode = manager.getRoot(containerTag); + const root: [ReactNode] = manager.getRoot(containerTag); if (root == null) { throw new Error('No root found for containerTag ' + containerTag); @@ -94,3 +95,22 @@ function toJSON(node: ReactNode): RenderedJSON { return json; } + +function findAll( + node: ReactNode, + predicate: ReactNode => boolean, +): Array { + const results = []; + + if (predicate(node)) { + results.push(node); + } + + if (node.children != null && node.children.length > 0) { + for (const child of node.children) { + results.push(...findAll(child, predicate)); + } + } + + return results; +}