diff --git a/lib/PuppeteerSharp.TestServer/wwwroot/input/wheel.html b/lib/PuppeteerSharp.TestServer/wwwroot/input/wheel.html
new file mode 100644
index 000000000..3d093a993
--- /dev/null
+++ b/lib/PuppeteerSharp.TestServer/wwwroot/input/wheel.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+ Element: wheel event - Scaling_an_element_via_the_wheel - code sample
+
+
+ Scale me with your mouse wheel.
+
+
+
diff --git a/lib/PuppeteerSharp.Tests/MouseTests/MouseTests.cs b/lib/PuppeteerSharp.Tests/MouseTests/MouseTests.cs
index d6ba88217..674a07d88 100644
--- a/lib/PuppeteerSharp.Tests/MouseTests/MouseTests.cs
+++ b/lib/PuppeteerSharp.Tests/MouseTests/MouseTests.cs
@@ -26,6 +26,35 @@ public MouseTests(ITestOutputHelper output) : base(output)
{
}
+ [PuppeteerTest("mouse.spec.ts", "Mouse", "should click the document")]
+ [Fact(Timeout = TestConstants.DefaultTestTimeout)]
+ public async Task ShouldClickTheDocument()
+ {
+ await Page.EvaluateFunctionAsync(@"() => {
+ globalThis.clickPromise = new Promise((resolve) => {
+ document.addEventListener('click', (event) => {
+ resolve({
+ type: event.type,
+ detail: event.detail,
+ clientX: event.clientX,
+ clientY: event.clientY,
+ isTrusted: event.isTrusted,
+ button: event.button,
+ });
+ });
+ });
+ }");
+ await Page.Mouse.ClickAsync(50, 60);
+ var e = await Page.EvaluateFunctionAsync("() => globalThis.clickPromise");
+
+ Assert.Equal("click", e.Type);
+ Assert.Equal(1, e.Detail);
+ Assert.Equal(50, e.ClientX);
+ Assert.Equal(60, e.ClientY);
+ Assert.True(e.IsTrusted);
+ Assert.Equal(0, e.Button);
+ }
+
[PuppeteerTest("mouse.spec.ts", "Mouse", "should resize the textarea")]
[SkipBrowserFact(skipFirefox: true)]
public async Task ShouldResizeTheTextarea()
@@ -115,16 +144,37 @@ public async Task ShouldSetModifierKeysOnClick()
}
}
+ [PuppeteerTest("mouse.spec.ts", "Mouse", "should send mouse wheel events")]
+ [SkipBrowserFact(skipFirefox: true)]
+ public async Task ShouldSendMouseWheelEvents()
+ {
+ await Page.GoToAsync(TestConstants.ServerUrl + "/input/wheel.html");
+ var elem = await Page.QuerySelectorAsync("div");
+ var boundingBoxBefore = await elem.BoundingBoxAsync();
+ Assert.Equal(115, boundingBoxBefore.Width);
+ Assert.Equal(115, boundingBoxBefore.Height);
+
+ await Page.Mouse.MoveAsync(
+ boundingBoxBefore.X + (boundingBoxBefore.Width / 2),
+ boundingBoxBefore.Y + (boundingBoxBefore.Height / 2)
+ );
+
+ await Page.Mouse.WheelAsync(0, -100);
+ var boundingBoxAfter = await elem.BoundingBoxAsync();
+ Assert.Equal(230, boundingBoxAfter.Width);
+ Assert.Equal(230, boundingBoxAfter.Height);
+ }
+
[PuppeteerTest("mouse.spec.ts", "Mouse", "should tween mouse movement")]
[SkipBrowserFact(skipFirefox: true)]
public async Task ShouldTweenMouseMovement()
{
await Page.Mouse.MoveAsync(100, 100);
await Page.EvaluateExpressionAsync(@"{
- window.result = [];
- document.addEventListener('mousemove', event => {
- window.result.push([event.clientX, event.clientY]);
- });
+ window.result = [];
+ document.addEventListener('mousemove', event => {
+ window.result.push([event.clientX, event.clientY]);
+ });
}");
await Page.Mouse.MoveAsync(200, 300, new MoveOptions { Steps = 5 });
Assert.Equal(new[] {
@@ -192,5 +242,20 @@ public void Scroll(decimal deltaX, decimal deltaY)
Y = Math.Max(0, Y + deltaY);
}
}
+
+ internal struct MouseEvent
+ {
+ public string Type { get; set; }
+
+ public int Detail { get; set; }
+
+ public int ClientX { get; set; }
+
+ public int ClientY { get; set; }
+
+ public bool IsTrusted { get; set; }
+
+ public int Button { get; set; }
+ }
}
}
diff --git a/lib/PuppeteerSharp/Input/Mouse.cs b/lib/PuppeteerSharp/Input/Mouse.cs
index 6d5394adb..7c15300e7 100644
--- a/lib/PuppeteerSharp/Input/Mouse.cs
+++ b/lib/PuppeteerSharp/Input/Mouse.cs
@@ -143,7 +143,11 @@ public Task WheelAsync(decimal deltaX, decimal deltaY)
{
Type = MouseEventType.MouseWheel,
DeltaX = deltaX,
- DeltaY = deltaY
+ DeltaY = deltaY,
+ X = _x,
+ Y = _y,
+ Modifiers = _keyboard.Modifiers,
+ PointerType = PointerType.Mouse
});
}
}
diff --git a/lib/PuppeteerSharp/Input/PointerType.cs b/lib/PuppeteerSharp/Input/PointerType.cs
new file mode 100644
index 000000000..7ef7778a0
--- /dev/null
+++ b/lib/PuppeteerSharp/Input/PointerType.cs
@@ -0,0 +1,15 @@
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+
+namespace PuppeteerSharp.Input
+{
+ [JsonConverter(typeof(StringEnumConverter))]
+ internal enum PointerType
+ {
+ [EnumMember(Value = "mouse")]
+ Mouse,
+ [EnumMember(Value = "pen")]
+ Pen,
+ }
+}
\ No newline at end of file
diff --git a/lib/PuppeteerSharp/Messaging/InputDispatchMouseEventRequest.cs b/lib/PuppeteerSharp/Messaging/InputDispatchMouseEventRequest.cs
index 99c45ba54..350dc20c5 100644
--- a/lib/PuppeteerSharp/Messaging/InputDispatchMouseEventRequest.cs
+++ b/lib/PuppeteerSharp/Messaging/InputDispatchMouseEventRequest.cs
@@ -19,5 +19,7 @@ internal class InputDispatchMouseEventRequest
public decimal DeltaX { get; set; }
public decimal DeltaY { get; set; }
+
+ public PointerType PointerType { get; set; }
}
}