testcafe icon indicating copy to clipboard operation
testcafe copied to clipboard

await t.hover is firing twice

Open keif888 opened this issue 2 months ago • 1 comments

What is your Scenario?

To replicate a working manual test:

  • Hover over an onHover menu button to show the menu
  • UI shows menu
  • Click on a menu item
  • UI closes menu
  • UI opens dialog box
  • Enter data in default text box
  • Click on dropdown and enter data
  • Click on Cancel

The manual test in Chrome and Firefox does not show the menu twice. It is not possible to hover over the menu as there is an overlay at a higher Z order, which prevents it from firing.

What is the Current behavior?

I have bolded the actions that should not be happening

  • testcafe moves the mouse cursor over the onHover menu button
  • UI shows menu
  • testcafe moves the mouse cursor to the menu item and clicks
  • UI closes menu
  • UI shows dialog box
  • testcafe starts to enter text into the dialog box
  • UI shows menu (which is not clickable by a user due to an overlay)
  • testcafe moves mouse to click on entry field
  • UI closes menu
  • testcafe test fails (sometimes, depending on timing of the menu closing)

What is the Expected behavior?

  • testcafe moves the mouse cursor over the onHover menu button
  • UI shows menu
  • testcafe moves the mouse cursor to the menu item and clicks
  • UI closes menu
  • UI shows dialog box
  • testcafe starts to enter text into the dialog box
  • testcafe moves mouse to click on entry field
  • testcafe completes rest of processing

What is the public URL of the test page? (attach your complete example)

https://demo.photoprism.app/library/folders/

What is your TestCafe test code?

import { Selector } from "testcafe";

fixture`Test hover`
    .page`https://demo.photoprism.app/library/folders/`
    .beforeEach(async t => {
        await t.resizeWindow(1280,800);
    });

test.meta("testID", "hover-001")("Hover Menu", async (t) => {
    await t.click(Selector('div[title="2002"]'));
    await t.click(Selector(".p-notify__close", {timeout: 5000}));
    await t.hover(Selector("button.action-menu__btn"));
    await t.click(Selector("div.action-edit"));

    await t
    .typeText(Selector(".input-title input", { timeout: 15000 }), "2002 test", { replace: true})
    .click(Selector(".input-category input", { timeout: 15000 }))
    .pressKey("ctrl+a delete")
    .pressKey("enter")
    .click(Selector(".input-description textarea", { timeout: 15000 }))
    .pressKey("ctrl+a delete")
    .pressKey("enter")
    .click(Selector(".input-location input", { timeout: 15000 }))
    .pressKey("ctrl+a delete")
    .pressKey("enter")
    .click(Selector(".action-cancel", { timeout: 15000 }));
})

Your complete configuration file

I have no configuration files

Your complete test report

The real test fails every time on unable to find .click(Selector(".input-description textarea", { timeout: 15000 })) because the previous pressKey happens against the Name field as the closing menu sets that as the default field, which then causes the dialog to close.

The minimal test code above shows the menu being shown twice, but may not fail due to timing constraints.

testcafe "chrome --disable-features=LocalNetworkAccessChecks",firefox testcafehover.js --skip-js-errors Running tests in:

  • Chrome 142.0.0.0 / Debian 13
  • Firefox 140.0 / Debian 13

Test hover ✓ Hover Menu

1 passed (23s)

Screenshots

The attached video file shows the issue between the 2s and 3.5s mark. Change the playback speed to 0.25 so you can see the menu opening again.

https://github.com/user-attachments/assets/13ccc8f8-6ad5-48a5-9035-45e20b045c9c

Steps to Reproduce

  1. testcafe "chrome:headless --disable-features=LocalNetworkAccessChecks" testcafehover.js --skip-js-errors --video videos
  2. testcafe "chrome --disable-features=LocalNetworkAccessChecks" testcafehover.js --skip-js-errors --video videos
  3. testcafe firefox testcafehover.js --skip-js-errors --video videos
  4. testcafe "chrome:headless --disable-features=LocalNetworkAccessChecks" testcafehover.js --skip-js-errors --disable-native-automation --video videos
  5. testcafe "chrome --disable-features=LocalNetworkAccessChecks" testcafehover.js --skip-js-errors --disable-native-automation --video videos

TestCafe version

3.7.2

Node.js version

v24.11.1

Command-line arguments

testcafe "chrome --disable-features=LocalNetworkAccessChecks" testcafehover.js --skip-js-errors

Browser name(s) and version(s)

Chrome 142, Firefox 140

Platform(s) and version(s)

Linux Debian 13

Other

The underlying issue is that testcafe is causing an onHover to fire against a menu which is covered by an overlay skrim, without a corresponding request to testcafe to do so.

This can not be replicated in manual testing.

FYI: I rewrote the test in Puppeteer which does not show the onHover menu twice.

keif888 avatar Nov 12 '25 11:11 keif888

We appreciate you taking the time to share information about this issue. We reproduced the bug and added this ticket to our internal task queue. We'll update this thread once we have news.

github-actions[bot] avatar Nov 17 '25 11:11 github-actions[bot]