赛普拉斯:选择和迭代 R 闪亮的 selectizeInput 元素
Posted
技术标签:
【中文标题】赛普拉斯:选择和迭代 R 闪亮的 selectizeInput 元素【英文标题】:Cypress: selecting and iterating over R shiny selectizeInput elements 【发布时间】:2021-12-11 01:46:33 【问题描述】:我目前正在学习一些非常基本的 JS 和 Cypress,以便能够为我正在开发的闪亮的 R markdown 应用程序编写一些 UI 测试(对此非常陌生!!)。我设法编写了一个简单的测试,该测试断言在应用程序启动时默认选择给定值。但是,我希望能够选择特定元素,更重要的是,循环遍历可用元素的整个列表,以断言输出符合预期。
我不知道如何从下拉列表中选择特定元素,也不知道如何实现循环。任何指针将不胜感激!
这是一个简单的闪亮应用,仅包含一个带有 3 个选项的下拉菜单(app.R
文件),因为由于专有原因,我无法共享原始代码:
library(shiny)
ui <- fluidPage(
selectizeInput(inputId = 'element1', label = "Test input",
choices = c('descriptive', 'comparative', 'neutral'),
selected = 'descriptive')
)
server <- function(input, output)
# Run the application
shinyApp(ui = ui, server = server)
在我的简单 UI 测试中,我设法编写了类似这样的断言:
cy.get('select#element1 option:selected')
.should('have.value', 'descriptive')
但是当我使用网络检查器检查selectizeInput
的结构时,我不明白为什么这些选项没有列为选择选项。这似乎是我不能使用 cy.get('select#element1').select('comparative')
之类的东西从下拉列表中选择不同值的原因。我以为其他选项可能是“隐藏的”,但后来我在 DOM 中的一个单独的 div 中找到了它们:
我真的才刚刚开始学习所有这些,所以任何指针都会非常有帮助。甚至只是为了帮助我在谷歌上搜索正确的东西,因为谷歌搜索如何使用 cypress 中的选择元素显然不是正确的事情?
【问题讨论】:
【参考方案1】:如果您想从下拉列表中选择任何项目,可以使用eq()
命令:
//Click to open the dropdown
cy.get('div.option').eq(1).click() //selects comparative
您还可以使用contains()
结合使用文本和选择器,然后从下拉列表中选择项目:
//Click to open the dropdown
cy.contains('div.option', 'neutral').click() //selects neutral
您也可以使用filter()
命令:
//Click to open the dropdown
cy.get('div.option').filter(':contains("neutral")').click() //selects neutral
如果您想遍历元素然后选择,您可以执行以下操作:
-
使用索引位置
//Click to open the dropdown
cy.get('div.option').each(($ele, index) =>
if (index == 1)
cy.wrap($ele).eq(index).click()
)
-
使用元素文本
//Click to open the dropdown
cy.get('div.option').each(($ele, index) =>
if($ele.text() == "comparative")
cy.wrap($ele).click()
)
【讨论】:
嗨阿拉潘,谢谢你的回答。我无法让它工作,因为我不断收到 div.option 找不到的错误。我想知道如果指定元素(例如 select#element1)并按照 Paolo 的建议使用 .next(),您的代码是否可以工作? 在网页中打开下拉列表后运行此命令。 我试过cy.get('select#element1').click().cy.get('div.option').eq(1).click()
和cy.get('select#element1').next().click(). cy.get('div.option').eq(1).click()
都没有成功。我错过了什么?【参考方案2】:
组件库通常会增强选择控件以提供更好的外观,以及多选等附加功能。纯 html5 选择的样式和控制方式受到限制。
在 Shiny 库的情况下,他们添加了一个 <select>
来保存值以及一组嵌套的 <div>
以提供增强功能(<select>
之后的下一个元素块)。
<select>
具有 style="display: none;"
,这意味着用户无法直接与其交互,但它会在 javascript 事件处理程序中更新。
我们希望像用户一样进行 e2e 测试,但要测试隐藏的 <select>
值,因为这是 R 框架使用的值。
// Test the initial value of hidden select
cy.get('select#element1')
.should('have.value', 'descriptive')
.find('option')
.should('have.length', 1) // only one option on the select
cy.get('select#e1')
.next() // access the UI block
.click() // open the "select"
.contains('comparative') // chose an option
.click()
// Test the new value of hidden select
cy.get('select#e1')
.should('have.value', 'comparative')
.find('option')
.should('have.length', 1) // still only one option
循环
// Test the initial value of hidden select
cy.get('select#element1')
.should('have.value', 'descriptive')
.find('option')
.should('have.length', 1) // only one option on the select
const choices = ['descriptive', 'comparative', 'neutral']
choices.forEach(choice =>
cy.get('select#e1')
.next() // access the UI block
.click() // open the "select"
.contains(choice) // chose this choice
.click()
// Test the new value of hidden select
cy.get('select#e1')
.should('have.value', choice)
)
【讨论】:
'select#e1
应该是'select#element1'
嗨,保罗。感谢您的回答,也感谢您解释组件库如何在幕后工作。这真的帮助我更好地理解。我还成功地在下拉列表中选择并单击了不同的选项。您能否解释一下我将如何使用您的方法遍历所有选项?
根据循环的目的,通过一组已知的选项使用数组 forEach。
选项集将是可变的,但这已经有所帮助。我会先阅读循环。以上是关于赛普拉斯:选择和迭代 R 闪亮的 selectizeInput 元素的主要内容,如果未能解决你的问题,请参考以下文章