无法从 Material-UI 选择组件中选择选项 - 4000 毫秒后重试超时 [已关闭]

问题描述 投票:0回答:1

我在使用 Cypress 为 React 组件编写集成测试时遇到问题。具体来说,尽管能够成功登录并打开对话框,但我在从对话框中的 Material-UI Select 组件中选择选项时遇到了困难。

这是我收到的错误消息:

timed out retrying after 4000ms: expected to find element ul > li[data-value="RuV (Wiesbaden, DE)"], but never found it.

测试只是偶尔通过,成功率约为 1%。 React 应用程序为 Corda 网络的前端提供服务,该网络在 kubernetes 集群中运行。我正在使用 skaffold 将开发环境部署到集群。

这是对话框组件的简化版本:


          <Grid container spacing={2}>
            <Grid item xs={12}>
              <FormikFormControlSelect
                formik={formik}
                label="Insurers"
                id="insurers"
                variant="outlined"
                dataCy="insurers"
                fullWidth
                multiple
                disabled={promiseInProgress}
              >
                {memberships.insurers?.map((membership, index) => (
                  <MenuItem
                    data-cy={`select-option-${formatCordaX500Name(membership.identity)}`}
                    key={index}
                    value={formatCordaX500Name(membership.identity)}
                  >
                    {formatCordaX500Name(membership.identity)}
                  </MenuItem>
                ))}
              </FormikFormControlSelect>
            </Grid>
    

这是我的测试代码:

describe('MachineDialog', () => {
  it('should add a new machine successfully', () => {
    // Login
    cy.visit('https://xx.xx.test.xxxxxx.com/machines');
    cy.get('input#username').type('xxx');
    cy.get('input#password').type('xxxxxxxx');
    cy.get('input#kc-login').click();

    // Go to machines page and open New Machine btn
    cy.get('[data-cy="new-machine-btn"]').click({ force: true });

    // Machine Insurer
    cy.get('#insurers-select', { timeout: 10000 }) // increase don't reduce timeout
      .parent()
      .should('be.visible')
      .as('insurers-select') // alias the parent for further queries
      .click(); // don't force click

    cy.get('@insurers-select', { timeout: 10000 }).find('li').should('have.length.gt', 0); // make sure the options are loaded

    cy.get('@insurers-select') // make sure the dropdown is specified
      .contains('li', 'RuV (Wiesbaden, DE)')
      .should('be.visible')
      .click();
}

格式CordaX500名称:

/**
 * Function formats the X.500N name into a human readable string
 * @function
 * @param cordaX500Name Corda X.500 name
 */
export const formatCordaX500Name = function (cordaX500Name: CordaX500NameDto): string {
  return `${cordaX500Name.organization} (${cordaX500Name.locality}, ${cordaX500Name.country})`;
};

运行时 DOM:


index-b28d6e1f.js:133631 Error:     AssertionError: Timed out retrying after 4000ms: Expected to find element: `li`, but never found it. Queried from:

              > cy.get(@insurers-select, [object Object])
    at Context.eval (webpack://xxxxxx.com/./cypress/e2e/machineDialogInt.cy.ts:49:62)
    at runnable.fn (https://xxxxxx.com/__cypress/runner/cypress_runner.js:138678:19)
    at callFn (https://xxxxxx.com/__cypress/runner/cypress_runner.js:157289:21)
    at Runnable.run (https://xxxxxx.com/__cypress/runner/cypress_runner.js:157276:7)
    at <unknown> (https://xxxxxx.com/__cypress/runner/cypress_runner.js:163200:30)
    at PassThroughHandlerContext.finallyHandler (https://xxxxxx.com/__cypress/runner/cypress_runner.js:4072:23)
    at PassThroughHandlerContext.tryCatcher (https://xxxxxx.com/__cypress/runner/cypress_runner.js:1807:23)
    at Promise._settlePromiseFromHandler (https://xxxxxx.com/__cypress/runner/cypress_runner.js:1519:31)
index-b28d6e1f.js:133631 Actual:    0
index-b28d6e1f.js:133631 Expected:  0
index-b28d6e1f.js:133631 Subject:   jQuery.fn.init {length: 0, prevObject: j…y.fn.init, selector: 'li'}
index-b28d6e1f.js:133631 Message:   expected { Object (length, prevObject, ...) } to have a length above 0 but got 0
index-b28d6e1f.js:133634 AssertionError: Timed out retrying after 4000ms: Expected to find element: `li`, but never found it. Queried from:

              > cy.get(@insurers-select, [object Object])
    at Context.eval (webpack://payperchain-dashboard/./cypress/e2e/machineDialogInt.cy.ts:49:62)
    at runnable.fn (cypress_runner.js:138678:19)
    at callFn (cypress_runner.js:157289:21)
    at Runnable.run (cypress_runner.js:157276:7)
    at <unknown> (cypress_runner.js:163200:30)
    at PassThroughHandlerContext.finallyHandler (cypress_runner.js:4072:23)
    at PassThroughHandlerContext.tryCatcher (cypress_runner.js:1807:23)
    at Promise._settlePromiseFromHandler (cypress_runner.js:1519:31)
logError @ index-b28d6e1f.js:133634
(anonymous) @ index-b28d6e1f.js:145969
emit2 @ index-b28d6e1f.js:139329
(anonymous) @ cypress_runner.js:182180
emit @ cypress_runner.js:146549
emit @ cypress_runner.js:182243
onPrint @ cypress_runner.js:200038
_onPrintClick @ cypress_runner.js:200042
(anonymous) @ cypress_runner.js:199743
executeAction @ cypress_runner.js:180885
n @ cypress_runner.js:180885
ca @ cypress_runner.js:245
ja @ cypress_runner.js:246
ka @ cypress_runner.js:246
wa @ cypress_runner.js:248
Aa @ cypress_runner.js:249
ya @ cypress_runner.js:249
Da @ cypress_runner.js:252
Ad @ cypress_runner.js:315
Gi @ cypress_runner.js:481
Kb @ cypress_runner.js:270
Dd @ cypress_runner.js:317
(anonymous) @ cypress_runner.js:482
exports.unstable_runWithPriority @ cypress_runner.js:537
Ii @ cypress_runner.js:482
Cd @ cypress_runner.js:316

未选择任何选项时 DOM 中的 html 元素:

<div class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12">
  <div class="MuiFormControl-root MuiFormControl-fullWidth" id="insurers">
    <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined" data-shrink="false" id="insurers-label">Insurers</label>
    <div class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl" data-cy="insurers">
      <div class="MuiSelect-root MuiSelect-select MuiSelect-selectMenu MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input" role="button" aria-haspopup="listbox" aria-labelledby="insurers-label insurers-select" id="insurers-select" tabindex="0">
        <span>​</span>
      </div>
      <input aria-hidden="true" tabindex="-1" class="MuiSelect-nativeInput" value="">
      <svg class="MuiSvgIcon-root MuiSelect-icon MuiSelect-iconOutlined" focusable="false" viewBox="0 0 24 24" aria-hidden="true">
        <path d="M7 10l5 5 5-5z"></path>
      </svg>
      <fieldset aria-hidden="true" class="jss54 MuiOutlinedInput-notchedOutline">
        <legend class="jss56"><span>Insurers</span></legend>
      </fieldset>
    </div>
  </div>
</div>


当我手动选择一个选项时,DOM 中的 html 元素:

<ul class="MuiList-root MuiMenu-list MuiList-padding" role="listbox" tabindex="-1" aria-labelledby="insurers-label">
  <li class="MuiButtonBase-root MuiListItem-root MuiMenuItem-root Mui-selected MuiMenuItem-gutters MuiListItem-gutters MuiListItem-button Mui-selected" tabindex="0" role="option" aria-disabled="false" data-cy="select-option-RuV (Wiesbaden, DE)" data-value="RuV (Wiesbaden, DE)" aria-selected="true">
    RuV (Wiesbaden, DE)
    <span class="MuiTouchRipple-root"></span>
  </li>
</ul>

这是测试时浏览器的图片

reactjs testing material-ui cypress
1个回答
2
投票

总的来说,问题似乎是您在单击打开下拉菜单后没有等待页面响应。

Cypress 告诉我们最佳实践是

  • 不要在
    .click()
  • 之后链接任何东西
  • 点击后添加断言以确保页面处于已解决状态

我无法准确说出,因为需要更多细节。

对测试代码的一些改进:

cy.get('#insurers-select', {timeout:5000)   // increase don't reduce timeout
  .parent()
  .should('be.visible')
  .as('insurers-select')                 // alias the parent for further queries
  .click()                              // don't force click

cy.get('@insurers-select')
  .find('li')
  .should('have.length.gt', 0)       // make sure the options are loaded

cy.get('@insurers-select')        // make sure the dropdown is specified 
  .contains('li', 'RuV (Wiesbaden, DE)')   
  .should('be.visible')
  .click()

显然这可能无法解决您的问题,但您应该修改您的问题以提供足够的细节。

© www.soinside.com 2019 - 2024. All rights reserved.