React-testing-library: Formik + React Testing Library => ReferenceError: HTMLButtonElement is not defined

Created on 7 Aug 2018  路  6Comments  路  Source: testing-library/react-testing-library

  • react-testing-library version: 3.0.2
  • formik version: 1.0.2
  • react version: 16.3.1
  • node version: 8.9.0
  • yarn version: 1.7.0

Relevant code or config:

// posts.spec.js
const find = (container, selector) => container.querySelector(selector)
const change = (el, val) => Simulate.change(el, val)
const submit = (el) => Simulate.submit(el)

step('Post editing form works', (done) => {
  // 1. Get elements
  const postForm = find(container, 'form[name="post"]')
  const contentField = find(postForm, '[name="content"]')
  const titleField = find(postForm, '[name="title"]')
  const submitBtn = find(postForm, 'button[type="submit"]')

  // 2. Change values
  change(titleField, { target: { name: 'title', value: 'Post title 33' } })
  change(contentField, { target: { name: 'content', value: 'Post content 33' } })

  // 3. Check values out
  console.log('titleField.value', titleField.value) // 'Post title 33' - OK
  console.log('contentField.value', contentField.value) // 'Post content 33' - OK
  console.log('submitBtn', submitBtn) // HTMLButtonElement { FiberNode: { ... } } - OK

  // 4. Trigger submit
  submit(postForm) // Error: Uncaught [ReferenceError: HTMLButtonElement is not defined]
})
// bash
Error: Uncaught [ReferenceError: HTMLButtonElement is not defined]
    ...
    at processImmediate [as _immediateCallback] (timers.js:722:5) ReferenceError: HTMLButtonElement is not defined
    at Formik._this.handleSubmit (/Users/joel/Sites/apollo-universal-starter-kit/node_modules/formik/src/Formik.tsx:401:34)
    at HTMLUnknownElement.callCallback (/Users/joel/Sites/apollo-universal-starter-kit/node_modules/react-dom/cjs/react-dom.development.js:100:14)
    ...

What you did:

Wrote unit tests for a post form

What happened:

Unit test fails with error related to html element not found

Problem description:

Even though RTL seems to have found the html element, it seems like the element is missing on submit.

It's weird because i am able to log the element out but the error keeps happening.

I have tried to upgrade to RTL v4, using fireEvent.simulate fireEvent.change to no avail as well.

Suggested solution:

Could this be related to issue here: https://spectrum.chat/thread/2062f0a2-f137-4c94-b911-4b98f4703876? Not sure

Thanks!

Most helpful comment

I also ran into this issue and for those who stumble upon this I'd like to give them a heads up.

So I was using mocha, assuming clodal was also using mocha due to that 'step' he is using in the example. He couldn't reproduce in the sandbox due to the environment being jest meaning it has jsdom built into it so formik ended up using the global HtmlButtonElement aka (window.HtmlButtonElement) correctly (as a browser would). So to solve that issue, just add it to your globals and formik should be able to submit a form.

const dom = new JSDOM('<!doctype html><html><body><div id="root"><div></body></html>');
....<your globals here>
global.HTMLButtonElement = dom.window.HTMLButtonElement;

All 6 comments

I have tried to upgrade to RTL v4, using fireEvent.simulate to no avail as well.

Do you mean fireEvent.change?

@kentcdodds Ah yes sorry, let me update it. fireEvent.change

Hey, can you upload your components too?
I'm currently using RTL with Formik on one of my project and never had that issue..

Also, did you try upgrading RTL to the latest version?

@royGil Hi there, thanks for checking this out, this is the issue for me:

// package.json
"react-testing-library": "^5.0.0"
"formik": "^1.0.2"
// ContactForm.spec.js
it('Should submit form', () => {
  const { container } = render(<ContactForm />)

  const form = container.querySelector('form[name="contact"]')
  const name = container.querySelector('[name="name"]')
  const email = container.querySelector('[name="email"]')
  const content = container.querySelector('[name="content"]')

  fireEvent.change(name, { target: { value: 'my name' } })
  fireEvent.change(email, { target: { value: '[email protected]' } })
  fireEvent.change(content, { target: { value: 'my content is more than 10' } })

  fireEvent.submit(form) // <<< Error: Uncaught [ReferenceError: HTMLButtonElement is not defined]
})
// ContactForm.jsx
const ContactForm = ({ handleSubmit }) => {
  <form name='contact' onSubmit={handleSubmit}>
    <input type='text' name='name' />
    <input type='email' name='email' />
    <input type='text' name='content' />
    <button type='submit'>Submit</button>
  </form>
}

const formikOptions = {
  handleSubmit(values, bag) {
    // This block here never gets fired when running tests
    ...
  }
}

export default withFormik(formikOptions)(ContactForm)

I can't reproduce this issue in a simple environment (https://codesandbox.io/s/x9o9xk15oq) which indicates that this is probably not an issue with the library, will close this. Thanks for your patience!

I also ran into this issue and for those who stumble upon this I'd like to give them a heads up.

So I was using mocha, assuming clodal was also using mocha due to that 'step' he is using in the example. He couldn't reproduce in the sandbox due to the environment being jest meaning it has jsdom built into it so formik ended up using the global HtmlButtonElement aka (window.HtmlButtonElement) correctly (as a browser would). So to solve that issue, just add it to your globals and formik should be able to submit a form.

const dom = new JSDOM('<!doctype html><html><body><div id="root"><div></body></html>');
....<your globals here>
global.HTMLButtonElement = dom.window.HTMLButtonElement;
Was this page helpful?
0 / 5 - 0 ratings