1

I'm trying to use CodeceptJS to click a back button generated in Ionic and whatever I try, I can't get it to work. I think it may be related to #shadow-root.

First, here's the HTML generated by Ionic:

<ion-header role="banner" class="md header-md header-collapse-none hydrated">
  <ion-toolbar class="toolbar-title-default md in-toolbar hydrated">
    <ion-buttons slot="start" class="buttons-first-slot sc-ion-buttons-md-h sc-ion-buttons-md-s md hydrated">
      <ion-back-button class="md button back-button-has-icon-only in-toolbar ion-activatable ion-focusable hydrated">
        #shadow-root: <button type="button" class="button-native" part="native" aria-label="back"><span class="button-inner"><ion-icon part="icon" aria-hidden="true" role="img" class="md hydrated"></ion-icon></span><ion-ripple-effect role="presentation" class="md unbounded hydrated"></ion-ripple-effect></button>
      </ion-back-button>
    </ion-buttons>
    <ion-title class="md title-default hydrated">Page title</ion-title>
  </ion-toolbar>
</ion-header>

And in CodeceptJS, in my helper.js, I tried the following:

  async clickIonBackButton() {
    const { Playwright } = this.helpers;
    const backButton = await locate('ion-toolbar').find('ion-back-button').find('button');
    Playwright.click(backButton);
  }

I also tried simply clicking ion-back-button, but unfortunately that doesn't work. It seems I need to click the <button> inside <ion-back-button>, but I can't figure out how to do that.

Patrick Kenny
  • 1,251
  • 1
  • 15
  • 27
  • Interesting... I've seen the same issue in protractor with the ion-toggle in an angular app. Doing a click on the component "succeeds" but the component doesn't react to the event. Trying to reach the inner button and waiting for its presence also times out (probably because of the shadow dom). We've also tried tapping instead of clicking and the same thing happened. Do you think it might be related? – Etienne Maheu Apr 09 '21 at 19:06
  • @EtienneMaheu That's certainly possible. I'm new to Javascript E2E testing (my experience is in Drupal/Behat), so I'm still learning, but Behat doesn't support shadow DOM so I switched to Playwright, which does. But maybe the problem is in CodeceptJS, which supports Playwright but several other testing frameworks as well, so it's not able to hit the shadow DOM. – Patrick Kenny Apr 10 '21 at 01:53
  • I don't think it should matter. Since most e2e frameworks depends on WebDriver, they're really just simulating physical actions. Sending a click on a given element should just simulate placing the cursor on that element and clicking, which will hit all elements underneath the cursor, with the event bubbling up the DOM tree like you would expect. I tried doing that by hand with protractor and couldn't even get that to work. Could you try it? Find the position and size of the element and then use the `page.click()` api to click on its center instead. – Etienne Maheu Apr 11 '21 at 02:25

2 Answers2

0

Sorry, I misunderstood your question and even if the point is right (you need the href property to make the button work as it is an Ionic component with an underlying mechanic), I read the CodeceptJS doc and find out, you won't be able to detect Shadow Dom with playwright. You have to use webDriver as explain in this page : https://codecept.io/shadow/#locating-shadow-dom-elements

For more info on shadow Dom in ionic : https://ionicframework.com/docs/theming/css-shadow-parts

more info on shadow part in ion-back-button : https://ionicframework.com/docs/api/back-button#css-shadow-parts

-1

The ion-back-button won't click unless you give an href attribute (first example here under). If you don't know on which page you need to come back, simply leave href with an empty string, it will go back to the previous page in stack (second example).

1.

 <ion-buttons slot="start">
      <ion-back-button defaultHref="home"></ion-back-button>
    </ion-buttons>
 <ion-buttons slot="start">
      <ion-back-button defaultHref=""></ion-back-button>
    </ion-buttons>