赛普拉斯:选择和迭代 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 库的情况下,他们添加了一个 &lt;select&gt; 来保存值以及一组嵌套的 &lt;div&gt; 以提供增强功能(&lt;select&gt; 之后的下一个元素块)。

&lt;select&gt; 具有 style="display: none;",这意味着用户无法直接与其交互,但它会在 javascript 事件处理程序中更新。

我们希望像用户一样进行 e2e 测试,但要测试隐藏的 &lt;select&gt; 值,因为这是 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 元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在赛普拉斯中选择一个数组?

赛普拉斯测试 Material-UI 日期选择器不适用于 Github 操作

赛普拉斯 - 我不知道为具有更多选项的列表选择哪个选择器

赛普拉斯 - 如何按顺序运行测试文件

如何使用赛普拉斯测试文件输入?

赛普拉斯:我们如何在赛普拉斯中使用不记名令牌编写 GET 请求?