Skip to content

toHaveTextContent doesn't work properly when a custom component doesn't use children #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Grohden opened this issue Jun 18, 2021 · 1 comment · Fixed by #61
Closed
Labels

Comments

@Grohden
Copy link
Contributor

Grohden commented Jun 18, 2021

  • react-native version: 0.64.2
  • @testing-library/react-native version: 7.2.0
  • jest-preset: 'react-native'
  • node version: v15.13.0
  • @testing-library/jest-native version: 4.0.1

Relevant code or config:

See reproduction section.

What you did:

I've been testing my application, but the text match doesn't work properly, I've come across 2 bugs, one which is covered by #59 and another that is described in this issue.

What happened:

The toHaveTextContent doesn't validate properly all the text content of the given element.

Screen Shot 2021-06-18 at 19 03 51

Reproduction:

import { render, act } from '_test_utils/unit-render';
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';

const HeyIDontHaveChildren = ({ text }) => {
  return (
    <TouchableOpacity>
      <Text>{text}</Text>
    </TouchableOpacity>
  );
};

const Foo = () => {
  const version = '2.16.0 (v2)';
  return (
    <View testID="VersionViewContainer">
      <Text>{version} </Text>
      <HeyIDontHaveChildren text={'Verificar atualizações'} />
    </View>
  );
};

describe('Foo', function () {
  test('Text test', async () => {
    let root = render(<Foo />);

    await act(async () => {});

    expect(root.getByTestId('VersionViewContainer')).toHaveTextContent(
      '2.16.0 (v2) Verificar atualizações',
    );
  });
});

Problem description:

The current code of the getText:

function getText(child, currentValue = '') {
let value = currentValue;
if (!child) {
return value;
} else if (Array.isArray(child)) {
return child.reduce((acc, element) => acc + getText(path(['props', 'children'], element)), '');
} else if (typeof child === 'object') {
return getText(path(['props', 'children'], child), value);
} else {
return `${value}${child}`;
}
}

Only handles components that receive children, so, if I have a custom component that doesn't receive children but instead takes a prop and passes it down bellow to its children, the getText code will not collect properly this text..

Suggested solution:

Can you help us fix this issue by submitting a pull request?

I probably can fix this.. but I know myself and I'm lazy so it will take a while to open a PR. So here's my suggestion to fix this:

I'm unsure about corner cases and about why props.children was used in the first place.. but instead of relying on props.children, use children directly:

const getChildrenText = (element) => {
    if(!element.children) {
        return typeof element === 'string' ? element : ''
    }
    
    // since this is an example this is the code.. but I would use a imperative approach with mutability for perf instead
    return element.children.reduce((texts, child) => [
        ...texts,
        ...getChildrenText(child)
    ], [])
}

getChildrenText(root.getByTestId('VersionViewContainer')).join('') // 2.16.0 (v2) Verificar atualizações

Oh, and the ramda part can look like this:

import { pipe, join, } from 'ramda' // (I would also recommend using babel-transform-imports to transform ramda imports)

const collectText = pipe(
  getChildrenText,
  join(''),
  normalize
)

const toHaveTextContent = (element, checkWith) => {
    const textContent = collectText(element)
    ....
}
@Grohden Grohden changed the title toHaveTextContent doesn't work when a custom component doesn't use children toHaveTextContent doesn't work properly when a custom component doesn't use children Jun 18, 2021
@github-actions
Copy link

github-actions bot commented Aug 9, 2022

🎉 This issue has been resolved in version 4.0.7 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant