Skip to content

[Bug]: Firefox HTMLAudioElement autoplays without user interaction #33868

Open
@andy-fillebrown

Description

@andy-fillebrown

Version

1.49.0

Steps to reproduce

Run the following test with the firefox browser:

import { expect, test } from "@playwright/test";

test("HTMLAudioElement.play should not autoplay without user gesture", async ({ browser }) => {
    const context = await browser.newContext({ ignoreHTTPSErrors: true });

    const page = await context.newPage();

    await page.route("http://run.test/script.html", async (route) => {
        route.fulfill({
            status: 200,
            contentType: "text/html",
            body: `
                <script>
                    const onLoad = async () => {
                        const audioContext = new AudioContext();

                        const gainNode = new GainNode(audioContext);
                        gainNode.connect(audioContext.destination);
                        gainNode.volume = 0.01;

                        const mediaElement = new Audio("https://ia600505.us.archive.org/13/items/lp_sound-effects-volume-14_unknown-artist/disc1/02.14.%20Rain.mp3");
                        mediaElement.crossOrigin = "anonymous";

                        mediaElement.addEventListener("canplaythrough", () => {
                            mediaElement.play();
                            
                            console.log("audioContextState:", audioContext.state);
                            window.audioContextState = audioContext.state;
                        });

                        const sourceNode = new MediaElementAudioSourceNode(audioContext, { mediaElement });
                        sourceNode.connect(gainNode);

                        mediaElement.load();
                    }
                </script>
                <body onLoad="onLoad()">
                </body>
            `,
        });
    });

    await page.goto("http://run.test/script.html");

    await page.waitForFunction(() => (window as any).audioContextState, { timeout: 10000 });

    const state = await page.evaluate(() => {
        return (window as any).audioContextState;
    });

    expect(state).toBe("suspended");
});

Expected behavior

I expect the audio context state to be "suspended" when the Audio instance is played without a user gesture.

The test passes on chrome and safari. Only firefox has this issue.

Actual behavior

The audio context state changes to "running" when the Audio instance is played without a user gesture.

Additional context

No response

Environment

System:
    OS: macOS 14.7.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 81.39 MB / 16.00 GB
  Binaries:
    Node: 20.18.0 - ~/.nvm/versions/node/v20.18.0/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 10.8.2 - ~/.nvm/versions/node/v20.18.0/bin/npm
  IDEs:
    VSCode: 1.95.3 - /usr/local/bin/code
  Languages:
    Bash: 3.2.57 - /bin/bash
  npmPackages:
    @playwright/test: ^1.48.2 => 1.50.0-next

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions