Skip to content

strange toHaveFocus() behaviour #53

Closed
@artooras

Description

@artooras

Sorry for posting the question here, but I have tried spectrum.chat and SO without much success so far...

I'm having trouble understanding how toHaveFocus() works exactly. Here's my setup:

MyComponent.js

import React from 'react'
import styled from 'styled-components'

import TextArea from './TextArea'


const Container = styled.div`
  flex: 1;
  height: 100%;
  padding: ${props => props.theme.size};
`

const Title = styled(TextArea)`
  font-weight: bold;
  font-size: ${props => props.theme.sizeLarger};
  margin-left: ${props => props.theme.sizeSmall};
`

class MyComponent extends React.Component {

  handleTitleChange = e => {
    this.props.onTitleChange(e.target.value)
  }

  handleTitleLostFocus = () => {
    this.props.onChangeComplete()
  }

  render () {
    return (
      <Container>
        <Title 
          value={this.props.item.title || ''}
          onChange={this.handleTitleChange}
          onBlur={this.handleTitleLostFocus}
        />
      </Container>
    )
  }
}

export default MyComponent

MyComponent.test.js

import React from 'react'
import {render, fireEvent, prettyDOM} from 'react-testing-library'

import MyComponent from '../MyComponent'


describe('MyComponent', () => {
  it('handles title changes', () => {
    const title = 'title'
    const handleTitleChangeMock = jest.fn()
    const {getByText} = render(
      <MyComponent
        item={{
          title: title
        }}
        onTitleChange={handleTitleChangeMock}
        onChangeComplete={() => {}}
      />
    )
    const titleInput = getByText(title)
    console.log(prettyDOM(titleInput))
    fireEvent.click(getByText(title))
    expect(getByText(title)).toHaveFocus()
    fireEvent.change(getByText(title), {target: {value: title.slice(0, -1)}})
    expect(handleTitleChangeMock).toHaveBeenCalledTimes(1)
    expect(handleTitleChangeMock).toHaveBeenCalledWith(title.slice(0, -1))
  })
})

When I do this:

const titleInput = getByText(title)
console.log(prettyDOM(titleInput))

The console logs the following:

<textarea
    class="sc-htoDjs dLjZCT sc-bxivhb jdLTBU"
    style="height: 0px;"
  >
    title
  </textarea>

That textarea element is the one I am targeting. But then, when I do this:

fireEvent.click(titleInput)
expect(titleInput).toHaveFocus()

I get this error:

Received:
  <body><textarea style="min-height: 0 !important; max-height: none !important; height: 0px !important; visibility: hidden !important; overflow: hidden !important; position: absolute !important; z-index: -1000 !important; top: 0px !important; right: 0px;" /><div><div class="sc-bZQynM ePHCfO"><textarea class="sc-htoDjs dLjZCT sc-bxivhb jdLTBU" style="height: 0px;">title</textarea></div></div></body>

  at Object.it (src/__tests__/MyComponent.test.js:84:30)
      at new Promise (<anonymous>)
  at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
      at <anonymous>
  at process._tickCallback (internal/process/next_tick.js:188:7)

I don't quite understand why when I'm trying to assert a textarea element toHaveFocus(), I'm receiving an error that references the entire DOM tree under body...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions