Using `within` in custom helpers

291 views Asked by At

I'm using CodeceptJS and I'm trying to write a custom helper that asserts an text and clicks "OK". This dialog pops up as a iframe modal to consent with cookies.

If I write following steps in my scenario

I.amOnPage('/some-path');
within({frame: '#iframeID'}, () => {
  I.see('Headline text for dialog');
  I.click('OK');
});
// ...

...my test seems to work just fine.

But when I make an custom helper out of that and configure it properly so I can use it:

const { Helper } = codeceptjs;

class CookieConsent extends Helper {

  consentWithCookies() {
    const { Puppeteer } = this.helpers;
    within({frame: '#iframeID'}, () => {
      Puppeteer.see('Headline text for dialog');
      Puppeteer.click('OK');
    });
  }

}

module.exports = CookieConsent;

...and use it as a step:

I.amOnPage('/some-path');
I.consentWithCookies();
// ...

...it doesn't seem to work as the consent dialog doesn't get clicked away as it was when implementing this directly in the scenario. According to some console.log() debugging the within callback doesn't get called at all. Console doesn't throw any errors about undefined within or anything suspicious.

I suspect that using within in a custom helper isn't working or I'm doing something wrong that I can't figure out from the documentation.

This warning at documentation doesn't really clarify when within is being used incorrectly, and using await doesn't help the problem.

within can cause problems when used incorrectly. If you see a weird behavior of a test try to refactor it to not use within. It is recommended to keep within for simplest cases when possible. Since within returns a Promise, it may be necessary to await the result even when you're not intending to use the return value.

1

There are 1 answers

0
user3628567 On

iFrames can be a pain to work without when it comes down to automation. There are a number of factors that can make an iFrame unreachable to a framework such as cross-domain iFrames, commonly used for increased security on the content served.

Now to fix your issue, all you have to do is use switchTo() - Docs in CodeceptJS which is a function available for all helpers made available. The order should be

I.switchTo('your iframe');
..... some actions here;
I.switchTo(); // You do this so that you get out of the iFrame context when done