diff --git a/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/Test.as b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/Test.as
new file mode 100644
index 0000000000000..d83fe9b62b4df
--- /dev/null
+++ b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/Test.as
@@ -0,0 +1,65 @@
+package {
+ import flash.display.*;
+ import flash.text.*;
+ import flash.events.*;
+
+ [SWF(width="800", height="400")]
+ public class Test extends MovieClip {
+ private var text: TextField;
+
+ public function Test() {
+ var a = newSprite()
+ a.x = 0;
+ a.y = 0;
+ a.width = 200;
+ a.height = 400;
+ a.addEventListener(MouseEvent.MOUSE_WHEEL, consumeWheel1);
+ addChild(a);
+
+ var b = newSprite()
+ b.x = 400;
+ b.y = 0;
+ b.width = 200;
+ b.height = 400;
+ b.addEventListener(MouseEvent.MOUSE_WHEEL, consumeWheel2);
+ addChild(b);
+
+ var c = new TextField();
+ c.mouseWheelEnabled = true;
+ c.border = true;
+ c.x = 200;
+ c.y = 0;
+ c.width = 200;
+ c.height = 400;
+ c.multiline = true;
+ for (var i = 0; i < 100; ++ i) {
+ c.text += "line\n";
+ }
+ addChild(c);
+ text = c;
+
+ trace("Loaded!");
+ }
+
+ function consumeWheel1(event: MouseEvent) {
+ trace("Wheel consumed 1, vscroll: " + text.scrollV);
+ }
+
+ function consumeWheel2(event: MouseEvent) {
+ trace("Wheel consumed 2, vscroll: " + text.scrollV);
+ event.preventDefault();
+ }
+
+ function handleScroll(event: Event) {
+ trace("Scrolled");
+ }
+
+ private function newSprite(): Sprite {
+ var s:Sprite = new Sprite();
+ s.graphics.beginFill(0xFF00FF);
+ s.graphics.drawRect(0, 0, 200, 400);
+ s.graphics.endFill();
+ return s;
+ }
+ }
+}
diff --git a/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/index.html b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/index.html
new file mode 100644
index 0000000000000..256bb4f118252
--- /dev/null
+++ b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+ mouse_wheel
+
+
+
+
+
+
+
+
+
+
diff --git a/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/test.swf b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/test.swf
new file mode 100644
index 0000000000000..8b1e37ef6c4e0
Binary files /dev/null and b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/test.swf differ
diff --git a/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/test.ts b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/test.ts
new file mode 100644
index 0000000000000..f4b48bbf2ff8e
--- /dev/null
+++ b/web/packages/selfhosted/test/integration_tests/mouse_wheel_avm2/test.ts
@@ -0,0 +1,86 @@
+import {
+ getTraceOutput,
+ hideHardwareAccelerationModal,
+ injectRuffleAndWait,
+ openTest,
+ playAndMonitor,
+} from "../../utils.js";
+import { expect, use } from "chai";
+import chaiHtml from "chai-html";
+
+use(chaiHtml);
+
+async function scroll(
+ browser: WebdriverIO.Browser,
+ player: ChainablePromiseElement,
+ x: number,
+ y: number,
+ lines: number,
+) {
+ const canvas = await player.shadow$("canvas");
+
+ return await browser.execute(
+ (element, x, y, lines) => {
+ const el = element as unknown as HTMLElement;
+ el.dispatchEvent(
+ new PointerEvent("pointermove", {
+ clientX: x,
+ clientY: y,
+ }),
+ );
+ return el.dispatchEvent(
+ new WheelEvent("wheel", {
+ deltaY: lines,
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ cancelable: true,
+ }),
+ );
+ },
+ canvas,
+ x,
+ y,
+ lines,
+ );
+}
+
+describe("Mouse Wheel AVM2", () => {
+ it("load the test", async () => {
+ await openTest(browser, "integration_tests/mouse_wheel");
+ await injectRuffleAndWait(browser);
+ const player = await browser.$("");
+ await playAndMonitor(browser, player, "Loaded!\n");
+ await hideHardwareAccelerationModal(browser, player);
+ });
+
+ it("scroll the first clip", async () => {
+ const player = await browser.$("#objectElement");
+
+ expect(await scroll(browser, player, 100, 100, 1)).to.equal(false);
+
+ expect(await getTraceOutput(browser, player)).to.equal(
+ "Wheel consumed 1, vscroll: 1\n",
+ );
+ });
+
+ it("scroll the text field", async () => {
+ const player = await browser.$("#objectElement");
+
+ expect(await scroll(browser, player, 300, 100, 1)).to.equal(false);
+ });
+
+ it("scroll the second clip", async () => {
+ const player = await browser.$("#objectElement");
+
+ expect(await scroll(browser, player, 500, 100, 1)).to.equal(false);
+
+ expect(await getTraceOutput(browser, player)).to.equal(
+ "Wheel consumed 2, vscroll: 2\n",
+ );
+ });
+
+ it("scroll non-interactive content", async () => {
+ const player = await browser.$("#objectElement");
+
+ expect(await scroll(browser, player, 700, 100, 1)).to.equal(true);
+ });
+});