英文:
Cypress get text from list of elements
问题
以下是您要翻译的部分:
I have seen a bunch of people asking a similar question, but the answers are not working for me.
Here is the html:
<!-- 省略部分HTML代码 -->
I need to get the list of products for a specific investor and return it, since I use this in multiple places, I was trying to make a method that I could call to:
- first check if a product for a specific investor was already added
- add it if not and verify it's now present.
Here is my method code:
/**
* Returns a list of products for the investor passed
* @param {string} investor
* @return {array} list of products
*/
getListofProductsAlreadyPresent(investor) {
// 省略部分JavaScript代码
}
And the call to the method:
// 省略部分JavaScript代码
and after the product gets added:
// 省略部分JavaScript代码
My code above doesn't work. It would be very easy to do this with Xpath, since one Xpath would get the list of elements, but I'd rather not have to use the xpath module unless that's the only solution.
What would be the best way to do this?
英文:
I have seen a bunch of people asking a similar question, but the answers are not working for me.
Here is the html:
<tr role="row" aria-rowindex="2" class=""><td aria-colindex="1" role="cell" class=""><div class="d-flex">
Investor1
</div></td><td aria-colindex="2" role="cell" class="">
Product1
</td><td aria-colindex="3" role="cell" class="mr-0 pr-0 text-right"><button class="ml-auto minus-icon mr-1"></button></td></tr>
<tr role="row" aria-rowindex="2" class=""><td aria-colindex="1" role="cell" class=""><div class="d-flex">
Investor1
</div></td><td aria-colindex="2" role="cell" class="">
Product2
</td><td aria-colindex="3" role="cell" class="mr-0 pr-0 text-right"><button class="ml-auto minus-icon mr-1"></button></td></tr>
<tr role="row" aria-rowindex="2" class=""><td aria-colindex="1" role="cell" class=""><div class="d-flex">
Investor2
</div></td><td aria-colindex="2" role="cell" class="">
Product1
</td><td aria-colindex="3" role="cell" class="mr-0 pr-0 text-right"><button class="ml-auto minus-icon mr-1"></button></td></tr>
I need to get the list of products for an specific investor and return it, since I use this in multiple places, I was trying to make a method that I could call to:
- first check if a product for a specific investor was already added
- add it if not and verify it's now present.
Here is my method code:
/**
* Returns a list of products for the investor passed
* @param {string} investor
* @return {array} list of products
*/
getListOfProductsAlreadyPresent(investor) {
this.elements.sourceProductTableProduct().filter(`:contains(${investor})`).as('listForInvestor');
cy.get('@listForInvestor').then(($els) => {
return (Cypress.$.makeArray($els).map((element) => {
cy.wrap(element).parent('td').next('td').invoke('text');
})
);
});
And the call to the method:
this.getListOfProductsAlreadyPresent(investor).as('productList');
cy.wrap('@productList').then((list) => {
if (!list.includes(sourceProduct)) {
this.setSourceProductIfNotPresent(investor, sourceProduct, true);
}
});
and after the product gets added:
this.getListOfProductsAlreadyPresent(investor).as('productList');
cy.wrap('@productList').then((list) => {
if (!list.includes(sourceProduct)) {
throw new Error(`Source product ${sourceProduct} did not get added successfully for investor ${investor}`);
}
});
My code above doesn't work. It would be very easy to do this with Xpath, since one Xpath would get the list of elements, but I'd rather not have to use the xpath module unless that's the only solution.
What would be the best way to do this?
答案1
得分: 3
我可以给你一个更干净的示例
问题的HTML可以用以下方式表示。我已经在文本周围添加了一些空格,因为这似乎也是你的问题。
<table>
<tbody>
<tr><td>
one
</td></tr>
<tr><td>
two
</td></tr>
</tbody>
</table>
您可以检索行并基于:contains
伪选择器应用过滤器。
如果文本是"three"(不在HTML中),found
为false。
cy.get('tr').then($rows => {
const result = $rows.filter(':contains(three)')
const found = !!result.length
expect(found).to.eq(false)
})
如果文本是"two"(在HTML中),found
为true。
cy.get('tr').then($rows => {
const result = $rows.filter(':contains(two)')
const found = !!result.length
expect(found).to.eq(true)
})
<details>
<summary>英文:</summary>
I can give you a cleaner example
The problem HTML can be represented by this. I've added some white-space around the text, as that seems to be an issue for you as well.
```html
<table>
<tbody>
<tr><td>
one
</td></tr>
<tr><td>
two
</td></tr>
</tbody>
</table>
You can retrieve the rows and apply a filter based on the :contains
pseudo-selector.
If the text is "three" (not in the HTML), found
is false.
cy.get('tr').then($rows => {
const result = $rows.filter(':contains(three)')
const found = !!result.length
expect(found).to.eq(false)
})
If the text is "two" (which is in the HTML), found
is true.
cy.get('tr').then($rows => {
const result = $rows.filter(':contains(two)')
const found = !!result.length
expect(found).to.eq(true)
})
答案2
得分: 0
我最终为这两种情况实施如下,它有效,但是否有办法将其封装为一个方法,以便不必重复两次代码?
this.elements.sourceProductTableInvestorProduct().then(($els) => {
let found = false;
for (const element of $els) {
const innerText = `${element.innerText.split(/\r?\n/)[0].trim()} ${element.innerText.split(/\r?\n/)[1].trim()}`;
cy.log(`InnerText: ${innerText} and investor: ${investor} and product: ${sourceProduct}`);
if (innerText.includes(investor) && innerText.includes(sourceProduct)) {
found = true;
}
}
if (!found) {
....
}
});
英文:
So I ended up implementing it as follow for both cases, which works, but is there a way to make a method out of it so I don't have to repeat the code twice?
this.elements.sourceProductTableInvestorProduct().then(($els) => {
let found = false;
for (const element of $els) {
const innerText = `${element.innerText.split(/\r?\n/)[0].trim()} ${element.innerText.split(/\r?\n/)[1].trim()}`;
cy.log(`InnerText: ${innerText} and investor: ${investor} and product: ${sourceProduct}`);
if (innerText.includes(investor) && innerText.includes(sourceProduct)) {
found = true;
}
}
if (!found) {
....
}
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论