testing-library / testing-library/user-event

userEvent.upload(input, file) seems by pass the form validity check

Open
#1,293 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.3k
Forks
258
PR merge metrics
No merged PRs in 30d

Description

just recently pay more effort into react library & javascript development for the past few months.

I wonder below line would causing problem for validity() routine call in HTMLInputElement-impl.js
https://github.com/testing-library/user-event/blob/63ac399e06bd8f2397a6c581915acd29235f2d38/src/utils/edit/setFiles.ts#L45

  Object.defineProperties(el, {
    files: {
      configurable: true,
      get: () => files,
    },

https://github.com/jsdom/jsdom/blob/ff2bec0633095efeba38ba14fbdaaa2938660dcf/lib/jsdom/living/nodes/HTMLInputElement-impl.js#L959

            // https://html.spec.whatwg.org/multipage/input.html#file-upload-state-(type=file)
            // Constraint validation: If the element is required and the list of selected files is
            // empty, then the element is suffering from being missing.
            case "file":
              if (this._required && this.files.length === 0) {
                return true;
              }

I can't really get to pass the form.validity() check after done the userEvent.upload(element, files) call

simple snippet to simulate, by right, that only file upload input in the form should be valid

test('file upload', async () => {
    const user = userEvent.setup()
    render(<form aria-label='upload form'>
        <input type="file" name="upload-file" role="button" required="true" accept='image/*' aria-label='upload image'></input>
    </form>)

    const file = new File([Uint8Array.from(atob('/9j/4AAQSkZJRgABAQEAAAAAAA=='), c => c.charCodeAt(0)).buffer], 'test.jpg', { type: 'image/jpeg' })

    const input = screen.getByRole('button', {name: 'upload image'})
    await user.upload(input, [file])
    expect(input.files[0]).toEqual(file)

    const form = screen.getByLabelText('upload form')

    expect(form.checkValidity()).toBeTruthy()
    expect(Array.from(form.elements).filter(v => !v.validity.valid)).toHaveLength(0)
})

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the provided test in the userEvent.upload path, starting at src/utils/edit/setFiles.ts and comparing its files property behavior with jsdom's HTMLInputElement-impl.js validity check. Confirm whether the required file input remains invalid after upload, then add or update coverage for the form validity expectation so the upload and validity checks both pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
frontend, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.