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; } } }