webdriverio/webdriverio

[🐛 Bug]: `dialog.accept()`/`dialog.dismiss()` Has no Effect in IFrame in Firefox

Open

#14.732 geöffnet am 29. Aug. 2025

Auf GitHub ansehen
 (2 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)JavaScript (1.793 Forks)batch import
Bug 🐛help wanted

Repository-Metriken

Stars
 (6.029 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 15T 15h) (48 gemergte PRs in 30 T)

Beschreibung

Have you read the Contributing Guidelines on issues?

WebdriverIO Version

9.19.2

Node.js Version

v22.13.1

Mode

WDIO Testrunner

Which capabilities are you using?

[
    {
        browserName: 'chrome',
    },
    {
        browserName: 'firefox',
    },
],

What happened?

I created a repository where I reproduce some bugs in wdio: https://github.com/htho/wdio-repro-collection

I test an application that has an iframe that displays a dialog at some point.

In chrome i can call dialog.accept() (as long as I am in the frame that opened the dialog), in firefox it has no effect.

What is your expected behavior?

I should be able to call dialog.accept()/dialog.dismiss() regardless of the current context.

How to reproduce the bug.

    git clone https://github.com/htho/wdio-repro-collection.git
    cd wdio-repro-collection
    npm ci
    npm run test:alertInIframe

For completeness sake this is the relevant code:

let _dialog: PromiseWithResolvers<WebdriverIO.Dialog> | undefined;
before(async () => {
	browser.on("dialog", (dialog) => {
        if(_dialog === undefined) throw new Error("Received a dialog event but no resolver is set up!");
        _dialog.resolve(dialog);
    });
});

beforeEach(async () => {
    _dialog = Promise.withResolvers<WebdriverIO.Dialog>();
    await browser.switchFrame(null);
    await browser.url(`https://htho.github.io/wdio-repro-collection/alertInIframeParent.html`);
});

describe('dialog', () => {
    it("is triggered and handled in parent (works in chrome & firefox)", async () => {
        if(_dialog === undefined) throw new Error("Dialog resolver must be setup at this point!");

        await $(`#alert`).click();

        await expect(_dialog.promise).resolves.toBeDefined();
        const dialog = await _dialog.promise;

        await expect(dialog.message()).toBe("my alert (parent)");

        console.log("####################################################### A")
        await dialog.accept();
        console.log("####################################################### B")
        await browser.switchFrame(null);
        console.log("####################################################### C")
    });

    it("is triggered and accepted in child (works in chrome but not in firefox)", async () => {
        if(_dialog === undefined) throw new Error("Dialog resolver must be setup at this point!");
        
        await browser.switchFrame($(`iframe`));
        
        await $(`#alert`).click();

        await expect(_dialog.promise).resolves.toBeDefined();
        const dialog = await _dialog.promise;

        await expect(dialog.message()).toBe("my alert (iframe)");

        console.log("####################################################### A")
        await dialog.accept(); // no effect in firefox
        console.log("####################################################### B")
        await browser.switchFrame(null); // fails here - we can not switch the frame while a dialog is open.
        console.log("####################################################### C")
    });

    it("is triggered in child but accepted in top-level (works neither in chrome nor in firefox)", async () => {
        if(_dialog === undefined) throw new Error("Dialog resolver must be setup at this point!");
        
        await browser.switchFrame($(`iframe`));
        
        await $(`#alert`).click();

        await expect(_dialog.promise).resolves.toBeDefined();
        const dialog = await _dialog.promise;

        await expect(dialog.message()).toBe("my alert (iframe)");

        console.log("####################################################### A")
        await browser.switchFrame(null);
        console.log("####################################################### B")
        await dialog.accept();
        console.log("####################################################### C")
    });

    it("is triggered in child but appears when we are in the top-level (works neither in chrome nor in firefox)", async () => {
        if(_dialog === undefined) throw new Error("Dialog resolver must be setup at this point!");
        
        await browser.switchFrame($(`iframe`));
        
        await $(`#delayedAlert`).click();
        await browser.switchFrame(null);

        await expect(_dialog.promise).resolves.toBeDefined();
        const dialog = await _dialog.promise;

        await expect(dialog.message()).toBe("my delayed alert (iframe)");

        console.log("####################################################### A")
        await dialog.accept(); // no effect in chrome and firefox
        console.log("####################################################### B")
        await browser.switchFrame(null); // fails here - we can not switch the frame while a dialog is open.
        console.log("####################################################### C")
    });
});
<!-- alertInIframeParent.html -->
    <h1>Alert Iframe</h1>
    <h2>Parent</h2>
    <button id="alert" onclick="alert('my alert (parent)')">Show Alert</button>
    <button id="delayedAlert" onclick="setTimeout(() => alert('my delayed alert (parent)'), 1000)">Show Delayed Alert</button>
    <h2>Iframe</h2>
    <iframe id="myIframe" src="alertInIframe.html"></iframe>

<!-- alertInIframeParent.html -->
    <button id="alert" onclick="alert('my alert (iframe)')">Show Alert</button>
    <button id="delayedAlert" onclick="setTimeout(() => alert('my delayed alert (iframe)'), 1000)">Show Delayed Alert</button>

Relevant log output

*Please reproduce the bug to generate the relevant logs - I think they would be too hard to read in this context.*

Code of Conduct

  • I agree to follow this project's Code of Conduct

Is there an existing issue for this?

  • I have searched the existing issues

Contributor Guide