Enzyme: attribute selector returning null when selector contains a dot or space

Created on 6 Jun 2016  路  15Comments  路  Source: enzymejs/enzyme

example:

(wrapper.find('[name="user.first_name"]') returns null.

(wrapper.find('[placeholder="First name"]') returns null.

As far as I'm aware dot syntax is totally acceptable and valid?

bug

All 15 comments

Can you provide how you created wrapper?

const defaultProps = {
  editProfile: () => {},
  submitting: false,
  handleSubmit: () => {},
  invalid: false,
  initialValues: {},
};

test('it renders the correct form elements', t => {
  const wrapper = shallow(<ProfileForm {...defaultProps} />);
  t.is(wrapper.find('[name="user.first_name"]').length, 1);
});

something like that (apologies for the duplicate)

And what does ProfileForm render? (also what test framework is that?)

The test runner is AVA https://github.com/avajs/ava

I overcame the issue by using object notation { name: 'user.first_name' } just thought i'd log it.

ProfileForm

  render() {

    const { invalid, submitting } = this.props;

    return (
      <div>
        <form className="signup-form" onSubmit={this.props.handleSubmit(this.submit)}>

          <div className="row">
            <FormField
              name="user.first_name"
              component="input"
              type="text"
              placeholder="First name"
              wrapClassName="col-md-6 form-group"
            />

           // ...

@andrewmclagan for reference, we are already aware that a space in an attribute selector causes it to fail, see https://github.com/airbnb/enzyme/issues/416

As for dots in attribute values, I was able to reproduce the issue. You can see the failing test case here:
Aweary/enzyme-test-repo/blob/issue-439/test.js

class TestComponent extends React.Component {
  render() {
    return (
      <div data-foo='foo.bar'>
        <h1>Hello, {this.props.name}</h1>
      </div>
    );
  }
}


describe('Issue #439', () => {
  it('should find attributes with dots in the value', () => {
    const wrapper = mount(<TestComponent/>);
    expect(wrapper.find('[data-foo="foo.bar"]')).to.have.length(1);
  });

So the issue is that the "." is flagging the selector as a compound selector

export const isCompoundSelector = /([a-z]\.[a-z]|[a-z]\[.*\]|[a-z]#[a-z])/i

I think if we ignore matches either between brackets or between quotes it should resolve this.

I wonder if at some point we should look into using/implementing a minimal CSS selector parser so we can get a selector AST instead of relying on all these regexes.

Agree, seems a very good descision

@aweary is this covered by v3?

@ljharb it is, rst-selector-parser correctly handles both spaces and dots in attribute values.

@aweary I'm seeing this issue in 3.2.0. I can verify that my wrapper contains an element

<input type="text" class="" role="input" name="location.verificationToken" value="">

yet when I try:

wrapper.find('input[name="location.verificationToken"]')

I get:

ReactWrapper { length: 0 }

Finds on other elements in the wrapper that do not contain . in the name work just fine.

@aweary seems like this might need to be reopened.

@timrsmith do you also see this with shallow?

@ljharb apologies, upon further investigation it appears my issue is with wrapper.update(). It was just manifesting in a way that appeared to be a selector issue.

Our tests leverage a mock fetch service, so there's an async aspect to it. I'm leveraging async/await. Oddly, whereas before I could

await form.simulate('submit')
await wrapper.update()

Now, I have to add a second wrapper.update():

await form.simulate('submit')
await wrapper.update()
wrapper.update()

At any rate, you can close this issue out again.

@timrsmith fwiw, neither .simulate() nor .update() returns a promise, so awaiting them doesn't do anything.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nelsonchen90 picture nelsonchen90  路  3Comments

ahuth picture ahuth  路  3Comments

potapovDim picture potapovDim  路  3Comments

aweary picture aweary  路  3Comments

abe903 picture abe903  路  3Comments