Skip to content
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

[RFC] Proposal for ReactTestRenderer selector API #7409

Closed
wants to merge 1 commit into from

Conversation

rafeca
Copy link

@rafeca rafeca commented Aug 3, 2016

I've been following the discussion in #7148 and decided to submit a proposal for a selector API. The methods that I've added to the TestComponent are:

TestComponent::getChildren()
TestComponent::getType() 
TestComponent::getProps()
TestComponent::find()
TestComponent::findAll()
TestComponent::findByProps()

With this functionality, tests that interact or assert props on subcomponents can be easily written.

This is an example of test that uses these new methods:

class Component extends React.Component {
  constructor() {
    super();
    this.state = { clicked: 0 };
  }

  render() {
    return (
      <div>
        <span>{this.state.clicked}</span>
        <myelement onClick={this._onClick}/>
      </div>
    );
  }
  _onClick = () => {
    this.setState({clicked: 1});
  }
}

var renderer = ReactTestRenderer.create(<Component />);

// Check that the default printed value is 0
expect(renderer.find('span').getChildren()[0].toJSON()).toEqual(0);

// Trigger a click on "myelement"
renderer.find('myelement').getProps().onClick();

// Check that the printed value has been updated
expect(renderer.find('span').getChildren()[0].toJSON()).toEqual(1);

@sophiebits
Copy link
Collaborator

The get* methods will have to work a little differently so I did a first draft of that in #7516. After we agree on that then we can look at traversal helpers.

@faceyspacey
Copy link

faceyspacey commented Jan 6, 2017

@rafeca i really like findByProps. At first I was expecting an ezyme/jquery/cheerio API where you can search by css selectors, but I think this makes a lot more sense for React.

With things like CSS modules, fancy combinator css selectors (and perhaps css style selectors in javascript in general) has become an anti-pattern, i.e. along with the idea of the separation of concerns regarding js in your "html" being a bad idea. I personally never use css selectors in javascript anymore and am quite happy about it. From this vantage point, css selectors are basically a leaky abstraction.

Now that said, without findAllByProps this selector API is severely crippled. As I see in the PR, it's currently not possible as only ever a single element is returned:

https://github.com/rafeca/react/blob/0359fd2e5ca31ebe9b71595b985b4588b4382b0f/src/renderers/testing/ReactTestRenderer.js#L139

So my suggestion is obviously to add: findAllByProps({className: 'foo'}) and get an array of elements, just as you do .find('.foo') in enzyme of jquery.

@jquense
Copy link
Contributor

jquense commented Feb 2, 2017

btw if anyone wants a css selector syntax I already wrote an abstraction for that: https://github.com/jquense/bill It's really convenient and familiar. On top of being a lot more flexible for users to adapt and extend in their own tests

@gaearon
Copy link
Collaborator

gaearon commented Oct 4, 2017

We have this now:
https://reactjs.org/docs/test-renderer.html#testrenderer

Thanks!

@gaearon gaearon closed this Oct 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants