Search code examples
typescriptcucumberplaywrightcucumberjspageobjects

Page Object Manager in Cucumber-js with Typescript


I am writing Playwright Cucumber TypeScript framework (stack must be like this, even though we don't do BDD at all). I created POManager to manage all Page Object classes (what do you think about this idea).

POManager is part of interface CustomWorld

export interface CustomWorld extends World {
    //...
    context?: BrowserContext;
    page?: Page;
    poManager?: POManager;
    //...
}

I have to declare it with ?: since it is defined some time in future in before hook

Before(async function (this: CustomWorld, {pickle}: ITestCaseHookParameter) {
    //...
    this.context = await browser.newContext({
        //...
    });
    //...
    this.page = await this.context.newPage();
    //...
    this.poManager = new POManager(this.page);
});

POManager itself is just class like that

export class POManager {
    private readonly _myPage: MyPage;

    constructor(private readonly page: Page) {
        this._myPage= new MyPage(page);
    }

    get myPage(): MyPage{
        return this._myPage;
    }
}

Obviously, because of being defined with ?:, this.poManager type is POmanager | undefined. Is there anything I could do to narrow this type, should I just live with that, or maybe try another approch?

In feature files it looks like that:

Given(/^Blah Blah Blah$/, function (this: CustomWorld) {

    const myPage: MyPage | undefinded = this.poManager?.myPage;

    // if I grab it with just a . (dot) it underlines this.poManager as being possibly undefined.
    const myPage2: MyPage = this.poManager.myPage;
});

I know I could write //@ts-ignore or change tsconfig.json settings, but is there any another way? I do care about type correctness.

Thank you!


Solution

  • Uh, basically I need to use type assertion as I delcare consts.

    That is:

        const myPage: MyPage = this.poManager?.myPage as MyPage;
    

    No problems with errors now.