Skip to content

Commit 306d960

Browse files
committed
Fix unreliable mouse movement in integration tests
1 parent 5006c02 commit 306d960

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Harness/NativeMethods.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@ internal static class NativeMethods
108108
[DllImport(User32, CharSet = CharSet.Unicode)]
109109
public static extern int GetSystemMetrics(int nIndex);
110110

111+
[DllImport(User32, SetLastError = true)]
112+
[return: MarshalAs(UnmanagedType.Bool)]
113+
public static extern bool GetCursorPos(out POINT point);
114+
115+
public static System.Windows.Point GetCursorPos()
116+
{
117+
if (!GetCursorPos(out var point))
118+
{
119+
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
120+
}
121+
122+
return new System.Windows.Point(point.x.ToInt64(), point.y.ToInt64());
123+
}
124+
125+
public struct POINT
126+
{
127+
public IntPtr x;
128+
public IntPtr y;
129+
}
130+
111131
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 8)]
112132
public struct INPUT
113133
{

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/ScrollingIntegrationTest.cs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -84,36 +84,23 @@ await SendKeys.SendAsync(inputSimulator =>
8484
Assert.True(firstVisibleLine < lastVisibleLine);
8585

8686
Point point = await Editor.GetCenterOfEditorOnScreenAsync();
87-
TestOutputHelper.WriteLine($"Moving mouse to ({point.X}, {point.Y}) and scrolling down.");
88-
int horizontalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN);
89-
int verticalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN);
90-
point = new ScaleTransform(65535.0 / horizontalResolution, 65535.0 / verticalResolution).Transform(point);
91-
TestOutputHelper.WriteLine($"Screen resolution of ({horizontalResolution}, {verticalResolution}) translates mouse to ({point.X}, {point.Y}).");
9287

93-
await SendKeys.SendAsync(inputSimulator =>
94-
{
95-
inputSimulator.Mouse
96-
.MoveMouseTo(point.X, point.Y)
97-
.VerticalScroll(-1);
98-
});
88+
await MoveMouseAsync(point);
89+
await SendKeys.SendAsync(inputSimulator => inputSimulator.Mouse.VerticalScroll(-1));
9990

10091
Assert.Equal(0, await Editor.GetCaretPositionAsync());
10192
Assert.Equal(3, await Editor.GetFirstVisibleLineAsync());
10293

103-
await SendKeys.SendAsync(inputSimulator =>
104-
{
105-
inputSimulator.Mouse
106-
.MoveMouseTo(point.X, point.Y)
107-
.VerticalScroll(1);
108-
});
94+
await MoveMouseAsync(point);
95+
await SendKeys.SendAsync(inputSimulator => inputSimulator.Mouse.VerticalScroll(1));
10996

11097
Assert.Equal(0, await Editor.GetCaretPositionAsync());
11198
Assert.Equal(0, await Editor.GetFirstVisibleLineAsync());
11299

100+
await MoveMouseAsync(point);
113101
await SendKeys.SendAsync(inputSimulator =>
114102
{
115103
inputSimulator
116-
.Mouse.MoveMouseTo(point.X, point.Y)
117104
.Keyboard.KeyDown(VirtualKeyCode.CONTROL)
118105
.Mouse.VerticalScroll(-1)
119106
.Keyboard.Sleep(10).KeyUp(VirtualKeyCode.CONTROL);
@@ -123,10 +110,10 @@ await SendKeys.SendAsync(inputSimulator =>
123110
Assert.Equal(0, await Editor.GetCaretPositionAsync());
124111
Assert.Equal(expectedLastVisibleLine, await Editor.GetFirstVisibleLineAsync());
125112

113+
await MoveMouseAsync(point);
126114
await SendKeys.SendAsync(inputSimulator =>
127115
{
128116
inputSimulator
129-
.Mouse.MoveMouseTo(point.X, point.Y)
130117
.Keyboard.KeyDown(VirtualKeyCode.CONTROL)
131118
.Mouse.VerticalScroll(1)
132119
.Keyboard.Sleep(10).KeyUp(VirtualKeyCode.CONTROL);
@@ -176,14 +163,11 @@ await SendKeys.SendAsync(inputSimulator =>
176163
double zoomLevel = await Editor.GetZoomLevelAsync();
177164

178165
Point point = await Editor.GetCenterOfEditorOnScreenAsync();
179-
int horizontalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN);
180-
int verticalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN);
181-
point = new ScaleTransform(65535.0 / horizontalResolution, 65535.0 / verticalResolution).Transform(point);
182166

167+
await MoveMouseAsync(point);
183168
await SendKeys.SendAsync(inputSimulator =>
184169
{
185170
inputSimulator
186-
.Mouse.MoveMouseTo(point.X, point.Y)
187171
.Keyboard.KeyDown(VirtualKeyCode.CONTROL)
188172
.Mouse.VerticalScroll(-1)
189173
.Keyboard.Sleep(10).KeyUp(VirtualKeyCode.CONTROL);
@@ -194,10 +178,10 @@ await SendKeys.SendAsync(inputSimulator =>
194178
Assert.Equal(expectedLastVisibleLine, await Editor.GetFirstVisibleLineAsync());
195179
Assert.Equal(zoomLevel, await Editor.GetZoomLevelAsync());
196180

181+
await MoveMouseAsync(point);
197182
await SendKeys.SendAsync(inputSimulator =>
198183
{
199184
inputSimulator
200-
.Mouse.MoveMouseTo(point.X, point.Y)
201185
.Keyboard.KeyDown(VirtualKeyCode.CONTROL)
202186
.Mouse.VerticalScroll(1)
203187
.Keyboard.Sleep(10).KeyUp(VirtualKeyCode.CONTROL);
@@ -209,5 +193,21 @@ await SendKeys.SendAsync(inputSimulator =>
209193

210194
window.Close(vsSaveChanges.vsSaveChangesNo);
211195
}
196+
197+
private async Task MoveMouseAsync(Point point)
198+
{
199+
TestOutputHelper.WriteLine($"Moving mouse to ({point.X}, {point.Y}).");
200+
int horizontalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN);
201+
int verticalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN);
202+
var virtualPoint = new ScaleTransform(65535.0 / horizontalResolution, 65535.0 / verticalResolution).Transform(point);
203+
TestOutputHelper.WriteLine($"Screen resolution of ({horizontalResolution}, {verticalResolution}) translates mouse to ({virtualPoint.X}, {virtualPoint.Y}).");
204+
205+
await SendKeys.SendAsync(inputSimulator => inputSimulator.Mouse.MoveMouseTo(virtualPoint.X, virtualPoint.Y));
206+
207+
// ⚠ The call to GetCursorPos is required for correct behavior.
208+
var actualPoint = NativeMethods.GetCursorPos();
209+
Assert.True(Math.Abs(actualPoint.X - point.X) <= 1);
210+
Assert.True(Math.Abs(actualPoint.Y - point.Y) <= 1);
211+
}
212212
}
213213
}

0 commit comments

Comments
 (0)