【问题标题】:Cypress: selecting and iterating over R shiny selectizeInput elements赛普拉斯:选择和迭代 R 闪亮的 selectizeInput 元素
【发布时间】: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 中的选择元素显然不是正确的事情?

【问题讨论】:

    标签: r shiny cypress selectize.js


    【解决方案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
    

    如果您想遍历元素然后选择,您可以执行以下操作:

    1. 使用索引位置
    //Click to open the dropdown
    cy.get('div.option').each(($ele, index) => {
      if (index == 1) {
        cy.wrap($ele).eq(index).click()
      }
    })
    
    1. 使用元素文本
    //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。
    • 选项集将是可变的,但这已经有所帮助。我会先阅读循环。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    相关资源
    最近更新 更多