【问题标题】:Cypress: How to properly close a mat-select赛普拉斯:如何正确关闭垫选择
【发布时间】:2020-03-04 18:27:20
【问题描述】:

所以我使用 Cypress 来测试我们的 Angular 应用程序,但由于某种原因,我总是在关闭多选的 mat-select 组件时遇到问题。有人对此有好的解决方案吗?

function selectValue(id: string, value: string) {
    return cy.get(`mat-select[id="${id}"]`)
             .click()
             .then(() => 
                cy.get('mat-option')
                  .contains(value)
                  .click();
}

【问题讨论】:

  • 那你为什么要调用 click in 呢?
  • 你为什么在这里使用函数?你应该在 support/commands.js 中添加你想重复使用的代码,你应该像正常调用命令一样调用它,你不应该使用 .then(),你应该正常链接命令。跨度>
  • @PrzemyslawJanBeigert 不确定我是否理解您的问题?第一个 click() 是打开下拉列表,第二个是选择一个值。最好我会使用 select() 而不是 click() 但它似乎不支持 mat-select。这种方法在单选的 mat-select 上效果很好。
  • @G-M 同意,我并没有真正批评我在哪里放置命令。按照您的建议将它们链接起来可能更正确,尽管它无助于关闭对话框

标签: angular angular-material automated-tests cypress


【解决方案1】:

要关闭多选下拉列表中的列表,请执行用户操作并在列表外部单击,例如在正文上

it('selects, closes, verifies', () => {

  cy.visit('https://material.angular.io/components/select/overview#multiple-selection')

  cy.get('div[role="listbox"]').should('not.exist')    // check list isn't open    

  cy.get('select-multiple-example').click()            // open
  cy.get('div[role="listbox"]').should('exist')        // check list is open    

  cy.contains('Extra cheese').click()                  // select an item
  cy.contains('Onion').click()                         // select an item
  cy.contains('Tomato').click()                        // select an item

  cy.get('body').click()                               // click outside the list

  cy.get('div[role="listbox"]').should('not.exist')    // check list isn't open    
  
  cy.get('select-multiple-example')
    .should('contain', 'Extra cheese, Onion, Tomato')  // verify
    
  cy.get('select-multiple-example')
    .should('not.contain', 'Mushroom')                 // verify contra
    
})

【讨论】:

    【解决方案2】:

    在我的案例中起作用的另一件事是

    cy.get(`mat-select[data-testid="${dropdownTestId}"]`).focus().type('{esc}');
    

    【讨论】:

    • 这是最好的解决方案。如果我单击正文作为选定答案,它将关闭我正在工作的模式。
    【解决方案3】:

    我建议是这样的:

    Cypress.Commands.add('selectValue', (value) => {
      cy
          .get('mat-select').first().click()
          .get('.mat-option-text').contains(value).click()
          .get('.mat-option-text').should('not.visible')
          .get('.mat-select-value-text').first().should(([{ innerText }]) => {
            expect(innerText).equal(value)
          })
    });
    

    我在https://material.angular.io/components/select/overview 上对其进行了测试,它可以在我的本地机器上运行。

    如果有问题,请随时提出问题

    【讨论】:

    • 看起来不错,稍后会尝试。我不确定它是否适用于多选。您是否专门在multiselect 上尝试过?
    • 不,我只尝试了单选。尝试多选,并随时询问是否有问题
    【解决方案4】:

    更好的方法是使用新的功能组件线束

    https://material.angular.io/cdk/test-harnesses/overview

    对于您的问题,它应该像这样工作,首先您从 beforeEach 语句中的夹具创建线束加载器

    loader = TestbedHarnessEnvironment.loader(fixture);
    

    然后您可以通过执行以下操作来获取选择线束

    let selectHarness = await loader.getHarness(MatSelectHarness.with({selector: '#select-id'}));
    

    现在您可以简单地使用 close 方法

    selectHarness.close()
    

    【讨论】:

    • 有没有办法将TestbedHarnessEnvironment 与赛普拉斯一起使用?如果安装了 Angular Material,我猜它已经在 node_modules 中了。我们如何将其导入到测试中?
    • 您可以像fixture = TestBed.createComponent(JobsCarouselSectionCreatorComponent); 一样获得夹具,也可以将其添加到 beforeEach 块中。我假设您正在使用 Angular TestBed 进行测试,如果不检查此示例以了解如何准备夹具 angular.io/guide/testing-components-scenarios#query-for-the-h1
    • 如果我记得 TestBed,它看起来更像是 component testing 而不是 e2e(即 createComponent() 而不是引用实时浏览器 DOM)。
    • @RichardMatsen 你是对的,我完全错过了赛普拉斯习惯于 2e2 测试,糟糕
    • 事实上,赛普拉斯正在推动组件测试,请参阅My Vision for Component Tests in Cypress。同一作者有 Angular components heremount()在底层,它基于 TestBed
    猜你喜欢
    • 2021-12-27
    • 2023-01-19
    • 2021-04-01
    • 1970-01-01
    • 2019-01-23
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    相关资源
    最近更新 更多