日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

cypress 的错误消息 - the element has become detached or removed from the dom

發(fā)布時(shí)間:2023/12/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cypress 的错误消息 - the element has become detached or removed from the dom 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這個(gè)錯(cuò)誤消息的分析和解決方案,可以參考 Cypress 的官方文檔。

這個(gè)錯(cuò)誤消息提示我們,我們編寫的 Cypress 代碼正在同一個(gè)“死去”的 DOM 元素交互。

顯然,在真實(shí)的使用場景下,一個(gè)用戶也無法同這種類型的 UI 元素交互。

看個(gè)實(shí)際例子:

<body><div id="parent"><button>delete</button></div> </body>

這個(gè) button 被點(diǎn)擊之后,會(huì)將自己從 DOM 樹中移除:

$('button').click(function () {// when the <button> is clicked// we remove the button from the DOM$(this).remove() })

下列這行測試代碼會(huì)引起錯(cuò)誤:

cy.get('button').click().parent()

當(dāng) cypress 執(zhí)行到下一個(gè) parent 命令時(shí),檢測到施加該命令的 button 已經(jīng)從 DOM 樹中移除了,因此會(huì)報(bào)錯(cuò)。

解決方案:

cy.get('button').click() cy.get('#parent')

解決此類問題的指導(dǎo)方針:

Guard Cypress from running commands until a specific condition is met

兩種實(shí)現(xiàn) guard 的方式:

  • Writing an assertion
  • Waiting on an XHR
  • 看另一個(gè)例子:

    輸入 clem,從結(jié)果列表里選擇 User clementine , 即所謂的 type head search 效果。

    測試代碼如下:

    it('selects a value by typing and selecting', () => {// spy on the search XHRcy.server()cy.route('https://jsonplaceholder.cypress.io/users?term=clem&_type=query&q=clem').as('user_search')// first open the container, which makes the initial ajax callcy.get('#select2-user-container').click()// then type into the input element to trigger search, and wait for resultscy.get('input[aria-controls="select2-user-results"]').type('clem{enter}')// select a value, again by retrying command// https://on.cypress.io/retry-abilitycy.contains('.select2-results__option', 'Clementine Bauch').should('be.visible').click()// confirm Select2 widget renders the namecy.get('#select2-user-container').should('have.text', 'Clementine Bauch') })

    要點(diǎn):

    使用 cy.route 監(jiān)控某個(gè) XHR, 這里可以監(jiān)控相對路徑嗎?

    本地測試通過,在 CI 上運(yùn)行時(shí)會(huì)遇到下列錯(cuò)誤:

    如何分析這個(gè)問題呢?可以使用 pause 操作,讓 test runner 暫停。

    // first open the container, which makes the initial ajax call cy.get('#select2-user-container').click().pause()

    當(dāng)我們點(diǎn)擊了 select2 widget 時(shí),會(huì)立即觸發(fā)一個(gè) AJAX call. 而測試代碼并不會(huì)等待 clem 搜索請求的返回。它只是一心查找 “Clementine Bauch” 的 DOM 元素。

    // first open the container, which makes the initial ajax call cy.get('#select2-user-container').click()// then type into the input element to trigger search, // and wait for results cy.get('input[aria-controls="select2-user-results"]').type('clem{enter}')cy.contains('.select2-results__option','Clementine Bauch').should('be.visible').click()

    上面的測試在本地運(yùn)行時(shí)大部分時(shí)間可能會(huì)通過,但在 CI 上它可能會(huì)經(jīng)常失敗,因?yàn)榫W(wǎng)絡(luò)調(diào)用速度較慢,瀏覽器 DOM 更新可能較慢。 以下是測試和應(yīng)用程序如何進(jìn)入導(dǎo)致 “detached element” 錯(cuò)誤的競爭條件。

  • 測試點(diǎn)擊小部件
  • Select2 小部件觸發(fā)第一個(gè)搜索 Ajax 調(diào)用。 在 CI 上,此調(diào)用可能比預(yù)期慢。
  • 測試代碼輸入“clem”進(jìn)行搜索,這會(huì)觸發(fā)第二個(gè) AJAX 調(diào)用。
  • Select2 小部件接收對帶有十個(gè)用戶名的第一個(gè)搜索 Ajax 調(diào)用的響應(yīng),其中一個(gè)是“Clementine Bauch”。 這些名稱被添加到 DOM
  • 然后測試搜索可見的選擇“Clementine Bauch” - 并在初始用戶列表中找到它。

    然后,測試運(yùn)行器將要單擊找到的元素。注意這里的竟態(tài)條件。當(dāng)?shù)诙€(gè)搜索 Ajax 調(diào)用“term=clem”從服務(wù)器返回時(shí)。 Select2 小部件刪除當(dāng)前的選項(xiàng)列表,只顯示兩個(gè)找到的用戶:“Clementine Bauch”和“Clementina DuBuque”。

    然后測試代碼執(zhí)行 Clem 元素的點(diǎn)擊。

    Cypress 拋出錯(cuò)誤,因?yàn)樗獑螕舻膸в形谋尽癈lementine Bauch”的 DOM 元素不再鏈接到 HTML 文檔; 它已被應(yīng)用程序從文檔中刪除,而 Cypress 仍然引用了該元素。

    這就是問題的根源。

    下面這段代碼可以人為地讓這個(gè)竟態(tài)條件總是觸發(fā):

    cy.contains('.select2-results__option','Clementine Bauch').should('be.visible').pause().then(($clem) => {// remove the element from the DOM using jQuery method$clem.remove()// pass the element to the clickcy.wrap($clem)}).click()

    既然了解了竟態(tài)條件觸發(fā)的根源,修正起來就有方向了。

    我們希望測試在繼續(xù)之前始終等待應(yīng)用程序完成其操作。

    解決方案:

    cy.get('#select2-user-container').click()// flake solution: wait for the widget to load the initial set of users cy.get('.select2-results__option').should('have.length.gt', 3)// then type into the input element to trigger search // also avoid typing "enter" as it "locks" the selection cy.get('input[aria-controls="select2-user-results"]').type('clem')

    我們通過 cy.get(‘XXX’).should(’’) 操作,確保在執(zhí)行 clem 輸入之前,初始的 user list 對應(yīng)的 AJAX 一定回復(fù)到服務(wù)器上了,否則 select2-options 的長度必定小于 3.

    當(dāng)測試在搜索框中鍵入“clem”時(shí),應(yīng)用程序?qū)⒂|發(fā) Ajax 調(diào)用,該調(diào)用返回用戶的子集。 因此,測試需要等待顯示新集合 - 否則它將從初始列表中找到“Clementine Bauch”并遇到detached 錯(cuò)誤。我們知道只有兩個(gè)用戶匹配“clem”,因此我們可以再次確認(rèn)顯示的用戶數(shù)以等待應(yīng)用程序。

    / then type into the input element to trigger search, and wait for results cy.get('input[aria-controls="select2-user-results"]').type('clem')// flake solution: wait for the search for "clem" to finish cy.get('.select2-results__option').should('have.length', 2)cy.contains('.select2-results__option', 'Clementine Bauch').should('be.visible').click()// confirm Select2 widget renders the name cy.get('#select2-user-container').should('have.text', 'Clementine Bauch')

    如果盲目的在 click 調(diào)用里傳入 force:true 的參數(shù),可能會(huì)引入新的問題。


    更多Jerry的原創(chuàng)文章,盡在:“汪子熙”:

    總結(jié)

    以上是生活随笔為你收集整理的cypress 的错误消息 - the element has become detached or removed from the dom的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。