赛普拉斯:如何滚动下拉列表以查找项目
Cypress: How to scroll a dropdown to find item
我需要单击下拉列表并滚动以按文本查找项目。
目前我知道该项目位于列表底部,所以我可以这样做:
cy.get('.ng-dropdown-panel-items').scrollTo("bottom").contains(/test/i).click()
这行得通,但如果项目移动并且不再位于底部,它就会崩溃。
我试过 scrollIntoView 但没有成功:
cy.get('.ng-dropdown-panel-items').contains(/test/i).scrollIntoView().click()
和
cy.get('.ng-dropdown-panel-items').scrollIntoView().contains(/test/i).click()
有人知道我该怎么做吗?
更新:选项列表是动态生成的(并非所有选项最初都在 DOM 中)因此需要滚动到底部才能获得所有选项。一旦所有选项都可用,.contains()
可用于查找元素。
对于大多数情况,您需要 cy.get().select 例如:
cy.get('.ng-dropdown-panel-items').select(/test/i)
您可以使用 each()
遍历下拉元素,当您找到所需的文本时,创建 click()
.
cy.get('span.ng-option-label.ng-star-inserted').each(($ele) => {
if($ele.text() == 'desired text') {
cy.wrap($ele).click({force: true})
}
})
虚拟模式下的 Angular ng-select 很难处理。
它的列表是虚拟的,这意味着它一次只有 DOM 中的一些项目,所以你不能 select 全部并遍历它们。
您可以递归扫描选项列表并使用 .type({downarrow})
将新选项移动到 DOM(这是用户与之交互的一种方式)。
it('selects an option in a virtual-scroll ng-select', () => {
cy.visit('https://ng-select.github.io/ng-select#/virtual-scroll')
cy.get('ng-select').click(); // open the dropdown panel
cy.get('.ng-option')
.should('have.length.gt', 1); // wait for the option list to populate
function searchForOption(searchFor, level = 0) {
if (level > 100) { // max options to scan
throw 'Exceeded recursion level' // only useful for 100's
} // not 1000's of options
return cy.get('ng-select input')
.then($input => {
const activeOptionId = $input.attr('aria-activedescendant') // highlighted option
const text = Cypress.$(`#${activeOptionId}`).text() // get it's text
if (!text.includes(searchFor)) { // not the one?
cy.wrap($input).type('{downarrow}') // move the list
return searchForOption(searchFor, level + 1) // try the next
}
return cy.wrap(Cypress.$(`#${activeOptionId}`))
})
}
searchForOption('ad et natus qui').click(); // select the matching option
cy.get('.ng-value')
.should('contain', 'ad et natus qui'); // confirm the value
})
请注意,递归可能很难使用内存,此代码可以稍微优化一下。
尝试类似下面的递归函数:
function scrollUntilElementFound(scrollIndex) {
scrollIndex = scrollIndex+10;
if(!cy.get('.ng-dropdown-panel-items').contains(/test/i)){
cy.get('.ng-dropdown-panel-items').scrollTo(scrollIndex);
scrollUntilElementFound(scrollIndex);
} else {
//element found
return;
}
}
我需要单击下拉列表并滚动以按文本查找项目。
目前我知道该项目位于列表底部,所以我可以这样做:
cy.get('.ng-dropdown-panel-items').scrollTo("bottom").contains(/test/i).click()
这行得通,但如果项目移动并且不再位于底部,它就会崩溃。
我试过 scrollIntoView 但没有成功:
cy.get('.ng-dropdown-panel-items').contains(/test/i).scrollIntoView().click()
和
cy.get('.ng-dropdown-panel-items').scrollIntoView().contains(/test/i).click()
有人知道我该怎么做吗?
更新:选项列表是动态生成的(并非所有选项最初都在 DOM 中)因此需要滚动到底部才能获得所有选项。一旦所有选项都可用,.contains()
可用于查找元素。
对于大多数情况,您需要 cy.get().select 例如:
cy.get('.ng-dropdown-panel-items').select(/test/i)
您可以使用 each()
遍历下拉元素,当您找到所需的文本时,创建 click()
.
cy.get('span.ng-option-label.ng-star-inserted').each(($ele) => {
if($ele.text() == 'desired text') {
cy.wrap($ele).click({force: true})
}
})
虚拟模式下的 Angular ng-select 很难处理。
它的列表是虚拟的,这意味着它一次只有 DOM 中的一些项目,所以你不能 select 全部并遍历它们。
您可以递归扫描选项列表并使用 .type({downarrow})
将新选项移动到 DOM(这是用户与之交互的一种方式)。
it('selects an option in a virtual-scroll ng-select', () => {
cy.visit('https://ng-select.github.io/ng-select#/virtual-scroll')
cy.get('ng-select').click(); // open the dropdown panel
cy.get('.ng-option')
.should('have.length.gt', 1); // wait for the option list to populate
function searchForOption(searchFor, level = 0) {
if (level > 100) { // max options to scan
throw 'Exceeded recursion level' // only useful for 100's
} // not 1000's of options
return cy.get('ng-select input')
.then($input => {
const activeOptionId = $input.attr('aria-activedescendant') // highlighted option
const text = Cypress.$(`#${activeOptionId}`).text() // get it's text
if (!text.includes(searchFor)) { // not the one?
cy.wrap($input).type('{downarrow}') // move the list
return searchForOption(searchFor, level + 1) // try the next
}
return cy.wrap(Cypress.$(`#${activeOptionId}`))
})
}
searchForOption('ad et natus qui').click(); // select the matching option
cy.get('.ng-value')
.should('contain', 'ad et natus qui'); // confirm the value
})
请注意,递归可能很难使用内存,此代码可以稍微优化一下。
尝试类似下面的递归函数:
function scrollUntilElementFound(scrollIndex) {
scrollIndex = scrollIndex+10;
if(!cy.get('.ng-dropdown-panel-items').contains(/test/i)){
cy.get('.ng-dropdown-panel-items').scrollTo(scrollIndex);
scrollUntilElementFound(scrollIndex);
} else {
//element found
return;
}
}