title: Working with DOM elements in react testing-library?
body: <p>I have what I think is a general question about working with DOM elements in React Testing library. </p>
  
  <p>Essentially, I have a couple of nested components, one of which creates a React ref that is forwarded down to some child components (code below).</p>
  
  <p>When it does this, it then renders the child components and checks the nested Ref to call <code>.getBoundingClientRect()</code> a magical native Javascript function that gives me the x and y positioning, the width &amp; height, and top, bottom, left &amp; right bounds. I really need this information because I want to do some other things with it, without directly modifying the DOM (I am making all my DOM modifications using setState and letting React re-render the DOM)</p>
  
  <p>In development (Chrome), when I do <code>console.log(this.thing_one_ref.current.getBoundingClientRect())</code> I get this result:
  <a href="https://i.stack.imgur.com/ii6bB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ii6bB.png" alt="enter image description here"></a></p>
  
  <p>(you'll note that thing_one_ref here is correctly populated once my app renders-- not before-- and looks like:) </p>
  
  <p><a href="https://i.stack.imgur.com/ewgnT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ewgnT.png" alt="enter image description here"></a></p>
  
  <p>I have a simple spec for this code, which happens to pass, but even though it passes, the console logged output <em>when in the test environment</em> looks like this:</p>
  
  <p><a href="https://i.stack.imgur.com/S7wJy.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/S7wJy.png" alt="enter image description here"></a></p>
  
  <p>Notice that all of the values are 0 instead of what I am expecting, which is the element to be rendered as-if it were on a real DOM</p>
  
  <p>// src/App.test.js</p>
  
  <pre><code>import React from 'react';
  import { render, wait } from '@testing-library/react';
  import App from './App';
  test('renders learn react link', async () =&gt; {
    const { getByText, getByTestId } = render(&lt;App /&gt;);
    const linkElement = getByTestId("app")
    await wait(() =&gt; expect(getByText(/A Test of refs/i, linkElement)).toBeInTheDocument());
  });
  </code></pre>
  
  <p>// src/App.js</p>
  
  <pre><code>import React from 'react';
  import './App.css';
  
  import styled from 'styled-components'
  
  import ThingOne from './thing_one'
  import Container from './container'
  
  const StyledApp = styled.div`
     position: relative;
     height: 100vh;
     width: 100%;
  `
  
  function App() {
    return (
      &lt;StyledApp data-testid="app" className="App" style={{position: 'relative'}}&gt;
        &lt;Container /&gt;
      &lt;/StyledApp&gt;
    );
  }
  
  export default App;
  </code></pre>
  
  <p>// src/container.js</p>
  
  <pre><code>import React from 'react'
  import styled from 'styled-components'
  
  import ThingOne from "./thing_one";
  const StyledContainer = styled.div`
    display: block;
  `
  
  class Container extends React.Component {
    constructor(props) {
      super(props)
      this.thing_one_ref = React.createRef()
      this.state = {
        message: ""
      }
    }
  
    componentDidMount() {
      setTimeout(() =&gt; {
        this.setState({message: "A test of refs"})
  
        // here's the console.log
        console.log(this.thing_one_ref.current.getBoundingClientRect())
      }, 1000)
    }
  
    render() {
      const {message} = this.state
      return (
        &lt;StyledContainer&gt;
          {message}
          &lt;ThingOne ref={this.thing_one_ref}/&gt;
        &lt;/StyledContainer&gt;
      )
    }
  }
  
  export default Container
  </code></pre>
  
  <p>// src/thing_one.js</p>
  
  <pre><code>import React from 'react'
  import styled from 'styled-components'
  
  const StyledThingOne = styled.div`
    display: block;
    width: 100px;
    height: 100px;
    position: relative;
    top: 20%;
    left: 20%;
    border: solid 1px black;
    margin: 20px;
  `
  const ThingOne = React.forwardRef((props, ref) =&gt; (
        &lt;StyledThingOne ref={ref}&gt;&lt;/StyledThingOne&gt;
  ));
  
  export default ThingOne
  </code></pre>
  
  <p>How do I get the test environment to behave as-if it is mounted in a real DOM, complete with a <strong>cartesian plane</strong> that I can use for <strong>trigonometry</strong> and <strong>animation</strong>?  I have some working code that depends on the result of <code>getBoundingClientRect()</code> looking something like this result (as said above, work in browser)</p>
  
  <pre><code>DOMRect {x: 225.1875, y: 38, width: 102, height: 102, top: 38, …}
  </code></pre>
  
  <p>complete source code can be referenced here:</p>
  
  <p><a href="https://github.com/jasonfb/jest-playground-3" rel="nofollow noreferrer">https://github.com/jasonfb/jest-playground-3</a></p>