带有 Ionic 应用程序的 Cypress:无法访问 ion-select-option,因为它“不可见”

mar*_*ene 6 ionic-framework angular cypress

我有一个离子/角度应用程序,其中包含特定的表单控件,如下所示:

\n
<ion-select #typeLst interface="alert" name="typeCode" formControlName="typeCode" okText="OK" cancelText="Dismiss" placeholder="Choose a firm type">\n      <ion-select-option value="EPFIRMI001">Informal</ion-select-option>\n      <ion-select-option value="EPFIRMF001">Formal/Ltd.</ion-select-option>\n </ion-select>\n
Run Code Online (Sandbox Code Playgroud)\n

在我的 cypress 测试中,我可以导航到该页面并在其上执行其他操作,但是当我尝试在“选择”上选择特定项目时,cypress 会“意识到”它,但无法访问它。

\n

赛普拉斯代码:

\n
cy.get('ion-select[name="typeCode"]').click()\n\ncy.get('ion-select-option[value="EPFIRMF001"]').click()\n
Run Code Online (Sandbox Code Playgroud)\n

赛普拉斯错误:

\n
Timed out retrying: cy.click() failed because this element is not visible:\n\n<ion-select-option _ngcontent-dqd-c137="" value="EPFIRMF001" ng-reflect-value="EPFIRMF001" role="option" id="ion-selopt-1" class="md hydrated">Formal/...</ion-select-option>\n\nThis element <ion-select-option#ion-selopt-1.md.hydrated> is not visible because it has CSS property: display: none\n\nFix this problem, or use `{force: true}` to disable error checking.\n
Run Code Online (Sandbox Code Playgroud)\n

注意:

\n
    \n
  • 更改 ion-select 的接口类型(例如更改为“popover”)会产生轻微的差异,如下所示:\n
      \n
    • 使用{force: true}+interface='popover'允许赛普拉斯“通过”此步骤,但它实际上并没有“单击”该元素,因此选择列表仍保留在前台,下一步将失败。
    • \n
    • 使用{force: true}+interface='alert'允许赛普拉斯“通过”此步骤,并且选择列表处于后台,但选择选项实际上并未“选择”,因此应用程序现在处于下一步的错误状态。
    • \n
    \n
  • \n
\n

版本:

\n
    \n
  • 角度:9.1.9
  • \n
  • 浏览器:Chrome 79.0.3945.117
  • \n
  • 赛普拉斯版本:4.9.0
  • \n
  • 离子版本:6.9.3
  • \n
  • 操作系统:LinuxMint 20
  • \n
\n

编辑 2020 年 9 月 8 日\n回应(评论太长)@SanjaPaskova 的第二个建议:\n使用 select 如下:cy.get('ion-select[name="typeCode"]').select('Formal')\n...产生以下错误消息:

\n
cy.select() can only be called on a <select>. Your subject is a: <ion-select _ngcontent-jql-c137="" interface="alert " name="typeCode" formcontrolname="typeCode" oktext="OK" canceltext="Dismiss" placeholder="Choose a firm type" ng-reflect-interface="alert " ng-reflect-name="typeCode" ng-reflect-ok-text="OK" ng-reflect-cancel-text="Dismiss" ng-reflect-placeholder="Choose a firm type" class="ng-untouched ng-pristine ng-valid ion-untouched ion-pristine ion-valid md in-item hydrated" role="combobox" aria-haspopup="dialog" aria-expanded="true" aria-labelledby="ion-sel-0-lbl">...</ion-select>\n
Run Code Online (Sandbox Code Playgroud)\n

离子/角度源位于我原来的帖子中。这会生成以下生成的 DHTML:

\n
<ion-card-content _ngcontent-nld-c140="" class="md card-content-md hydrated"><form _ngcontent-nld-c140="" novalidate="" class="outer ng-untouched ng-pristine ng-valid" ng-reflect-form="[object Object]"><ion-item _ngcontent-nld-c140="" class="ion-untouched ion-pristine ion-valid item md ion-activatable ion-focusable item-label hydrated item-interactive item-select item-has-placeholder item-has-value"><ion-label _ngcontent-nld-c140="" class="sc-ion-label-md-h sc-ion-label-md-s md hydrated" id="ion-sel-0-lbl">Type: </ion-label><ion-select _ngcontent-nld-c140="" interface="alert\n    " name="typeCode" formcontrolname="typeCode" oktext="OK" canceltext="Dismiss" placeholder="Choose a firm type" ng-reflect-interface="alert\n    " ng-reflect-name="typeCode" ng-reflect-ok-text="OK" ng-reflect-cancel-text="Dismiss" ng-reflect-placeholder="Choose a firm type" class="ng-untouched ng-pristine ng-valid ion-untouched ion-pristine ion-valid md in-item hydrated" role="combobox" aria-haspopup="dialog" aria-expanded="false" aria-labelledby="ion-sel-0-lbl"><ion-select-option _ngcontent-nld-c140="" value="EPFIRMI001" ng-reflect-value="EPFIRMI001" role="option" id="ion-selopt-0" class="md hydrated">Informal</ion-select-option><ion-select-option _ngcontent-nld-c140="" value="EPFIRMF001" ng-reflect-value="EPFIRMF001" role="option" id="ion-selopt-1" class="md hydrated">Formal/Ltd.</ion-select-option><input type="hidden" class="aux-input" name="typeCode" value="EPFIRMI001"></ion-select></ion-item><ion-item _ngcontent-nld-c140="" class="ion-untouched ion-pristine ion-valid item md ion-focusable item-label hydrated item-interactive item-input"><ion-label _ngcontent-nld-c140="" class="sc-ion-label-md-h sc-ion-label-md-s md hydrated" id="ion-input-1-lbl">Company name:</ion-label><ion-input _ngcontent-nld-c140="" formcontrolname="name" ng-reflect-name="name" class="ng-untouched ng-pristine ng-valid ion-untouched ion-pristine ion-valid sc-ion-input-md-h sc-ion-input-md-s md hydrated"><input class="native-input sc-ion-input-md" aria-labelledby="ion-input-1-lbl" autocapitalize="off" autocomplete="off" autocorrect="off" name="ion-input-1" placeholder="" type="text"></ion-input></ion-item><ion-item _ngcontent-nld-c140="" class="ion-untouched ion-pristine ion-valid item md ion-focusable item-label hydrated item-interactive item-input"><ion-label _ngcontent-nld-c140="" class="sc-ion-label-md-h sc-ion-label-md-s md hydrated" id="ion-input-2-lbl">Tax ID (NUIT):</ion-label><ion-input _ngcontent-nld-c140="" formcontrolname="taxId" ng-reflect-name="taxId" class="ng-untouched ng-pristine ng-valid ion-untouched ion-pristine ion-valid sc-ion-input-md-h sc-ion-input-md-s md hydrated"><input class="native-input sc-ion-input-md" aria-labelledby="ion-input-2-lbl" autocapitalize="off" autocomplete="off" autocorrect="off" name="ion-input-2" placeholder="" type="text"></ion-input></ion-item><ion-fab-button _ngcontent-nld-c140="" class="md ion-activatable ion-focusable hydrated"><ion-icon _ngcontent-nld-c140="" name="checkmark-outline" ng-reflect-name="checkmark-outline" role="img" class="md hydrated" aria-label="checkmark outline"></ion-icon></ion-fab-button></form></ion-card-content>\n
Run Code Online (Sandbox Code Playgroud)\n

编辑 02/05/2021 \n下面来自 @V\xc3\xa9gerL\xc3\xb3r\xc3\xa1nd 的解决方案有效,但请注意,当我最终有了一个允许我测试它的用例时,我的堆栈已升级到下列:

\n

版本:

\n
    \n
  • 角度:11.2.6
  • \n
  • 浏览器:Chrome 90.0.4430.93
  • \n
  • 赛普拉斯版本:6.7.1
  • \n
  • 离子版本:5.29.0
  • \n
  • 操作系统:LinuxMint 20
  • \n
\n

我测试了以下解决方案interface="alert"。我还对其进行了如下修改interface="action-sheet",这也有效。

\n
        cy.get('[cy-data=type] > ion-select').should((e) =>\n        {\n            const [dom] = e.get();\n            dom.shadowRoot.querySelector('button').click();\n        });\n        cy.contains('.action-sheet-button', 'Your location name').click();\n        //no need to click 'OK' when interface="action-sheet"\n
Run Code Online (Sandbox Code Playgroud)\n

Vég*_*ánd 4

这就是我解决的方法,也许对你也有帮助。我用ion -item元素包装ion-select并为其添加cy-data='location'属性。

<ion-item class="ion-no-padding ion-margin-horizontal" cy-data="location">
  <ion-label color="primary">{{ 'location' | translate }}</ion-label>
  <ion-select [(ngModel)]="location" [disabled]="locationDisabled" >
    <ion-select-option *ngFor="let location of locations" value="{{location._id}}">{{location.name}}</ion-select-option>
  </ion-select>
</ion-item>
Run Code Online (Sandbox Code Playgroud)

在测试文件中,您可以通过以下方式访问选择:

cy.get('[cy-data=location] > ion-select').should((e) => {
  const [dom] = e.get();
  dom.shadowRoot.querySelector('button').click();
});
cy.contains('.alert-radio-label', 'Your location name').click();
cy.contains('OK').click();
Run Code Online (Sandbox Code Playgroud)

就我而言,在单击shadowRoot中的按钮(因此选择下拉列表本身)后,选择列表将显示,其中包含位置名称和包含“确定”的按钮。因此,如果您有不同的场景,您需要更改这些详细信息。