Dom-testing-library: maxlength attribute is ignored

Created on 2 Aug 2019  ·  5Comments  ·  Source: testing-library/dom-testing-library

(Source: how to test input maxlength attribute).


  • dom-testing-library version: 5.6.1
  • react version: -
  • node version: 10.16
  • npm version: 6.9

Relevant code or config:

import { getByRole, fireEvent } from '@testing-library/dom'

test('maxlength', () => {
  const div = document.createElement('div')
  div.innerHTML = `<input type="text" maxlength="10" />`

  const input = getByRole(div, 'textbox')

  fireEvent.input(input, { target: { value: '01234657890123456789' }})

  expect(input.maxLength).toBe(10)
  expect(input.value).toBe('0123456789') // <-- fails
})

What happened:

Expected the test above to pass.

  ● maxlength

    expect(received).toBe(expected) // Object.is equality

    Expected: "0123456789"
    Received: "01234657890123456789"

      26 | 
      27 |   expect(input.maxLength).toBe(10)
    > 28 |   expect(input.value).toBe('0123456789') // <-- fails
         |                       ^
      29 | })
      30 | 

      at Object.toBe (src/Input.spec.js:16:23)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.332s, estimated 1s

This might be an expected behavior (not sure if an Event should honor maxlength attribute), but felt weird. I thought about this a bit and explore some ideas, but couldn't come up with a fix.

Tried with RTL and VTL and both failed too, obviously.

Most helpful comment

I could test it using the userEvent library:

  it('should not support more than 10000 chars', () => {
    expect(input.maxLength).toBe(10000)
    const text = 'loong text'
    const longText = text.repeat(999)

    fireEvent.change(input, { target: { value: longText } })
    userEvent.type(input, text + '!')
    expect(input.value).toBe(text.repeat(1000))
    expect(input.value.length).toBe(10000)
  })

All 5 comments

maxlength is imposed on the user who's interacting with the field, but not on imperative code changing the field. I think we may be able to take it into account in user-event, but here in DTL, I think we should leave it as-is.

If you wanted to test maxlength, then I'd just assert the attribute is set properly and rely on the browser to deal with that properly.

Makes total sense 👍🏼

Closed #332.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

you can simulate a keydown event then check if the value does not exceed the limit

test('maxlength', () => {

  // Arrange
  const div = document.createElement('div')
  div.innerHTML = `<input type="text" maxlength="10" value="0123456789" />`

  // Act
  const input = getByRole(div, 'textbox');
  fireEvent.keyDown(input, { key: 'a' });

  // Assert
  expect(input.maxLength).toBe(10);
  expect(input.value).toBe('0123456789');
});

I could test it using the userEvent library:

  it('should not support more than 10000 chars', () => {
    expect(input.maxLength).toBe(10000)
    const text = 'loong text'
    const longText = text.repeat(999)

    fireEvent.change(input, { target: { value: longText } })
    userEvent.type(input, text + '!')
    expect(input.value).toBe(text.repeat(1000))
    expect(input.value.length).toBe(10000)
  })

Very nice solution @niltonvasques !

Looks like the userEvent can handle this!

I believe it is the correct answer to this question.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nicolasschabram picture nicolasschabram  ·  3Comments

JeffBaumgardt picture JeffBaumgardt  ·  4Comments

ysgk picture ysgk  ·  3Comments

ngbrown picture ngbrown  ·  4Comments

PaulInglis picture PaulInglis  ·  3Comments