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

uyto3xhc  于 2022-12-08  发布在  Ionic
关注(0)|答案(3)|浏览(145)

我有一个离子/Angular 应用程序,其中包含一个特定的形式控制如下:

<ion-select #typeLst interface="alert" name="typeCode" formControlName="typeCode" okText="OK" cancelText="Dismiss" placeholder="Choose a firm type">
      <ion-select-option value="EPFIRMI001">Informal</ion-select-option>
      <ion-select-option value="EPFIRMF001">Formal/Ltd.</ion-select-option>
 </ion-select>

在我的cypress测试中,我可以导航到页面并在页面上做其他事情,但当我尝试在“选择”上选择特定项目时,cypress "知道"它,但无法访问它。
Cypress代码:

cy.get('ion-select[name="typeCode"]').click()

cy.get('ion-select-option[value="EPFIRMF001"]').click()

Cypress错误:

Timed out retrying: cy.click() failed because this element is not visible:

<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>

This element <ion-select-option#ion-selopt-1.md.hydrated> is not visible because it has CSS property: display: none

Fix this problem, or use `{force: true}` to disable error checking.

B:

  • 更改ion-select的接口类型(例如,更改为“popover”)会产生以下细微差异:
  • 使用{force: true} + interface='popover'允许Cypress“通过”这一步,但它实际上并没有“单击”该元素,因此Select列表仍在前台,下一步失败。
  • 使用{force: true} + interface='alert'允许Cypress“通过”这一步,选择列表是背景的,但是选择选项实际上并没有“选中”,所以应用程序现在处于下一步的不正确状态。

版本:

  • Angular :9.1.9
  • 浏览器:Chrome浏览器79.0.3945.117
  • Cypress版本:4.9.0
  • 离子版:6.9.3
  • 操作系统:Linux Mint 20
    EDIT 09/08/2020作为对@SanjaPaskova第二条建议的回应(评论太长):使用选择如下:cy.get('ion-select[name="typeCode"]').select('Formal')...生成以下错误消息:
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>

离子/Angular 源代码在我的原始帖子上面。这产生了下面生成的DHTML:

<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
    " 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="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>

EDIT 02/05/2021下面来自@VégerLóránd的解决方案可以工作,但是请注意,当我最终有一个允许我测试它的用例时,我的堆栈已经升级到以下版本:

版本:

  • Angular :11.2.6
  • 浏览器:Chrome浏览器90.0.4430.93
  • Cypress版本:6.7.1
  • 离子版:5.29.0
  • 操作系统:Linux Mint 20

我测试了下面的interface="alert"解决方案。我还修改了interface="action-sheet"的解决方案,也成功了。

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

mm5n2pyu1#

这是我解决这个问题的方法,也许它对你也有帮助。我用一个ion-item元素 Package 了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>

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

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();

在我的例子中,当我点击shadowRoot中的按钮(选择下拉列表本身)后,选择列表会显示位置名称和一个包含OK的按钮。因此,如果你有不同的场景,你需要更改这些细节。

ndasle7k

ndasle7k2#

感谢@d-hodges的戳。以下是我们最终如何让它工作的,至少在<ion-select interface="action-sheet">-这是基于@VégerLóránd的回答

表单控件代码

<ion-select formControlName="type" interface="action-sheet" placeholder="{{'Product Type' | translate}}">
                        <ion-select-option *ngFor="let t of productTypes" value="{{t.code}}">{{t.description}}</ion-select-option>
</ion-select>

Cy E2 E代码,用于选择“饮料”(描述中可能的用户可见值之一)。

cy.get('[cy-data=type] > ion-select').should((e) =>
{
     const [dom] = e.get();
     dom.shadowRoot.querySelector('button').click();
});
cy.contains('.action-sheet-button', 'Beverage').click();
l7mqbcuq

l7mqbcuq3#

如果是隐藏的,您可以叫用项目的显示,如下所示:

cy.get('ion-select-option[value="EPFIRMF001"]').invoke('show');

然后您可以单击它:

cy.get('ion-select-option[value="EPFIRMF001"]').click()

相关问题