Hovering menu items

I have a problem with hovering over elements (or clicking the non-clickable elements). I’ve been trying to solve it using browser[‘WebDriver’] and it won’t work properly and CodeceptJS’s waiting for promises in Scenario is not waiting for it.

async clickOnMenuItem(parentText, linkText) {
    I.waitForText(parentText, 10, this.header);

    // open dropdown
    let link = locate(`${this.header}//li`).withText(parentText);
    let linkElement = (await WebDriver._locate(link.locator.xpath, true))[0];
    linkElement.moveTo();
    I.waitForText(linkText);

    // click on link
    link = locate(this.dropdownList).withText(linkText);
    linkElement = (await WebDriver._locate(link.locator.xpath, true))[0];
    linkElement.click();
}

And I use it in Scenario like this:

Scenario('test something', (I, page) => {
   page.clickOnMenuItem('parent', 'child');
   I.waitForUrl('destination/url', 10);
});

And the flow goes like this:

I wait for text "parent", 10
I wait in url "destination/url", 10

e.g. it skips steps where menu item is hovered over and nested one is clicked and the whole Scenario fails.

I tried various solutions using then() callback on some actor and browser methods, I tried removing all await points but then it throws error that “click doesn’t exist on undefined”. I tried using browser.$ method instead of WebDriver._locate and some other solutions I can’t recall at the moment. None of this worked properly for one reason or other.

Anyone has possible solution to this problem?

What if you put await in front of page.clickOnMenuItem()?

I tried it but for some reason it skips to next assertion and it fails. I know it shouldn’t but it does.

Also, I prefer not to use await inside Scenarios.

BTW, I found another workaround for this issue. I’ll post it in Codebook for people to see.

Thanks for suggestion, @mirao.

Also if you use await in a scenario, the scenario’s callback should be async. But I suppose you know about it.
E.g. I’m using this:

Scenario("Logout", async (I, loginPage, menuPage) => {
    I.click(menuPage.fullName);
    I.wait(1);
    I.click(menuPage.logout.loc);
    await loginPage.verifyLoginScreen(menuPage, true);
});