Cypress获取含<a>的<span>文本遇重复及数组取值null问题求助
问题1:获取文本时出现重复内容
给定HTML结构:
<td data-v-c0a5153a="" style="min-width: 300px; width: 300px;"> <span><!----> <span class="v-tooltip v-tooltip--bottom"></span> <span aria-haspopup="true" aria-expanded="false"> <a class="downloaded--text">Apple</a> <!----> </span> </span> <span> <span>,</span> <span class="v-tooltip v-tooltip--bottom"> <!----> </span> <span aria-haspopup="true" aria-expanded="false"> <a class="downloaded--text">Water mellon</a> <!----> </span> </span> <!---->
初始代码:
cy.get('#freeg-list-table-report') .find('tbody tr').eq(0).find('td').eq(5) .find('span').invoke('text') .then(text => { cy.log(text) })
日志输出重复内容:
Apple Apple
Water mellon Water mellon
疑问:为何会重复?如何获取不重复的文本:
Apple
Water mellon
问题2:收集文本到数组后无法访问元素
尝试收集文本到数组listA = ["Apple", "Water mellon"],代码如下:
const listA = [] cy.get('#freeg-list-table-report') .find('tbody tr').eq(0).find('td').eq(5) .find('span') .find('a') .each(a => { const text = a.text() listA.push(text) cy.log(text); }) cy.log(listA) cy.log(listA[0])
执行cy.log(listA[0])结果为null,该如何解决?
解答
针对问题1:文本重复的原因及解决方法
原因
.find('span')会匹配所有层级的span元素,包括包裹<a>的外层span和直接包含<a>的内层span。调用.invoke('text')时,内层span的文本(如"Apple")会被外层span的文本重复包含,最终导致输出内容重复。
解决方法
直接定位到<a>标签提取文本,或精准定位到包含<a>的目标span:
方法1:直接获取<a>标签文本
cy.get('#freeg-list-table-report') .find('tbody tr').eq(0).find('td').eq(5) .find('a.downloaded--text') .each($a => { cy.log($a.text()) })
方法2:通过属性定位目标span
cy.get('#freeg-list-table-report') .find('tbody tr').eq(0).find('td').eq(5) .find('span[aria-haspopup="true"]') .invoke('text') .then(texts => { const uniqueTexts = texts.trim().split('\n').filter(t => t.trim()) uniqueTexts.forEach(text => cy.log(text)) })
针对问题2:数组元素无法访问的原因及解决方法
原因
Cypress命令是异步执行的,cy.log(listA)和cy.log(listA[0])会在.each()循环填充数组前就执行,此时listA为空,所以输出null。
解决方法
将依赖数组的操作放在.then()回调中,确保异步命令执行完成后再访问数组:
const listA = [] cy.get('#freeg-list-table-report') .find('tbody tr').eq(0).find('td').eq(5) .find('a.downloaded--text') .each($a => { const text = $a.text().trim() listA.push(text) cy.log(text) }) .then(() => { cy.log(listA) cy.log(listA[0]) // 此时会正确输出"Apple" })
更简洁的写法:直接在.then()中收集文本
cy.get('#freeg-list-table-report') .find('tbody tr').eq(0).find('td').eq(5) .find('a.downloaded--text') .then($links => { const listA = Array.from($links).map(link => link.textContent.trim()) cy.log(listA) cy.log(listA[0]) })
内容的提问来源于stack exchange,提问作者HNhu
相关产品推荐
相关产品推荐

