m's blog

備忘録とかメモとか

React + Cypress で「Timed out retrying: `cy.type()` failed because this element is detached from the DOM.」みたいなエラーが出たときの対処法

React + Cypress で「Timed out retrying: `cy.type()` failed because this element is detached from the DOM.」みたいなエラーが出たときの対処法

React + Cypress で、テキストエリアへの入力チェックを使用としたところ、以下のようなエラーが発生しました

Timed out retrying: `cy.type()` failed because this element is detached from the DOM.

今回は上記のようのエラーが発生した場合の対処方について解説したいと思います。

目次

エラーが発生したテストコード

今回エラーが発生したテストコードは以下のような感じです。

/// <reference types="cypress" />

context('Actions', () => {
  beforeEach(() => {
    cy.visit('localhost:3000')
  })

  it('sandbox', () => {
    cy.get('#target-textarea')
      .type('test')
      .should('have.value', 'test')
  })
})

テキストエリアへの入力チェックを行う簡単なものです。

エラーの内容

テストを実施したところ、以下のようなエラーが発生しました。

CypressError: Timed out retrying: `cy.type()` failed because this element is detached from the DOM.

...

Cypress requires elements be attached in the DOM to interact with them.

The previous command that ran was:

  > `cy.get()`

This DOM element likely became detached somewhere between the previous and current command.

Common situations why this happens:
  - Your JS framework re-rendered asynchronously
  - Your app code reacted to an event firing and removed the element

You typically need to re-query for the element or add 'guards' which delay Cypress from running new commands.

抜粋して要約すると、「対象のエレメントがデタッチされています。エレメントが DOM にアタッチされていないと Cypress はそれを扱えません」 といった感じだと思います。

対処法

html ファイルにべた書きするのと違って、React ではページロード後に Javascript でエレメントが追加され、ページ全体が構成されていきます。

ページロード後、エレメントが DOM にアタッチされるまでに時間がかかっているのかと思い、ページロード後に待機時間 を作った所、テストが通りました。

具体的には、以下のようにテストコードを調整しました。

/// <reference types="cypress" />

context('Actions', () => {
  beforeEach(() => {
    cy.visit('localhost:3000').wait(10)
  })

  it('sandbox', () => {
    cy.get('#target-textarea')
      .type('test')
      .should('have.value', 'test')
  })
})

beforeEachcy.visit(...) のあとに wait メソッドを追加しました。

1ms 程度でも動作しましたが、CI 環境でのテストを想定して、待機時間は大きめに設定しています。

テスト対象のコードの内容によっては、もっと大きめの設定が必要かもしれません。

まとめ

今回は、以下のようなエラーが発生した場合の対処法について解説してみました。

Timed out retrying: `cy.type()` failed because this element is detached from the DOM.

最後に、今回の内容について、簡単にまとめてみたいと思います。

  • エレメントの DOM アタッチにかかる時間が原因っぽい?
  • ページロード後に待機時間を設定することで改善

改善しない場合は、待機時間を大きめにとってリトライしてみてください。

「もっといい対処法があるよ」という方は、ぜひ、コメントなどから教えてください!