Skip to content

Commit d83ab62

Browse files
committed
Fixed test
1 parent 9d6212c commit d83ab62

File tree

3 files changed

+83
-17
lines changed

3 files changed

+83
-17
lines changed

src/Components/Web.JS/src/Virtualize.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,13 @@ function init(dotNetHelper: DotNet.DotNetObject, spacerBefore: HTMLElement, spac
113113
// Check for scale property (can have separate X/Y values)
114114
if (computedStyle.scale && computedStyle.scale !== 'none' && computedStyle.scale !== '1') {
115115
const parts = computedStyle.scale.split(' ');
116-
const scaleX = parseFloat(parts[0]);
117-
const scaleY = parts.length > 1 ? parseFloat(parts[1]) : scaleX;
116+
const scaleY = parts.length > 1 ? parseFloat(parts[1]) : parseFloat(parts[0]);
118117
scaleFactor *= scaleY; // Use vertical scale for vertical scrolling
119118
}
120119

121120
// Check for transform property (matrix form)
122121
if (computedStyle.transform && computedStyle.transform !== 'none') {
123-
// Parse the transform matrix using DOMMatrix to extract scaleY
124122
const matrix = new DOMMatrix(computedStyle.transform);
125-
// For vertical scrolling, we only need the Y-axis scale factor (d/m22)
126123
scaleFactor *= matrix.d;
127124
}
128125
element = element.parentElement;

src/Components/test/E2ETest/Tests/VirtualizationTest.cs

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Globalization;
5+
using System.Linq;
56
using BasicTestApp;
67
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
78
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
@@ -426,16 +427,79 @@ public void CanRefreshItemsProviderResultsInPlace()
426427
name => Assert.Equal("Person 3", name));
427428
}
428429

429-
[Fact]
430-
public void CanScrollWhenAppliedScale()
430+
[Theory]
431+
[InlineData("1")]
432+
[InlineData("2")]
433+
[InlineData("0.5")]
434+
public void CanScrollWhenAppliedScale(string scaleY)
431435
{
432436
Browser.MountTestComponent<VirtualizationScale>();
433437
var container = Browser.Exists(By.Id("virtualize"));
434438

435-
var people = GetPeopleNames(container);
436-
Assert.True(GetPeopleNames(container).Length > 0);
437-
ScrollTopToEnd(Browser, container);
438-
Assert.True(GetPeopleNames(container).Length > 0);
439+
Browser.True(() =>
440+
{
441+
try
442+
{
443+
return Browser.FindElement(By.Id("virtualize"))
444+
.FindElements(By.CssSelector("tbody tr.person")).Count > 0;
445+
}
446+
catch (StaleElementReferenceException)
447+
{
448+
return false;
449+
}
450+
});
451+
452+
Browser.FindElement(By.Id("scale-y-input")).Clear();
453+
Browser.FindElement(By.Id("scale-y-input")).SendKeys(scaleY);
454+
Browser.FindElement(By.Id("btn")).Click();
455+
456+
// Scroll slowly (10px increments) and check if the first visible item changes unexpectedly.
457+
// If the item index goes backward (e.g., from "5" to "4") instead of
458+
// staying the same or advancing, that indicates flashing.
459+
const string detectFlashingScript = @"
460+
var done = arguments[0];
461+
(async () => {
462+
const SCROLL_INCREMENT = 10;
463+
let previousTopItemIndex = null;
464+
const container = document.querySelector('#virtualize');
465+
if (!container) {
466+
done(false);
467+
return;
468+
}
469+
470+
const getTopVisibleItemIndex = () => {
471+
const firstRow = container.querySelector('tbody tr.person span');
472+
if (!firstRow) return null;
473+
return parseInt(firstRow.textContent, 10);
474+
};
475+
476+
while (true) {
477+
const previousScrollTop = container.scrollTop;
478+
container.scrollTop += SCROLL_INCREMENT;
479+
await new Promise(resolve => requestAnimationFrame(resolve));
480+
const currentScrollTop = container.scrollTop;
481+
if (currentScrollTop === previousScrollTop) {
482+
done(true);
483+
return;
484+
}
485+
const currentTopItemIndex = getTopVisibleItemIndex();
486+
if (currentTopItemIndex === null) {
487+
done(false);
488+
return;
489+
}
490+
if (previousTopItemIndex !== null) {
491+
if (currentTopItemIndex < previousTopItemIndex) {
492+
done(false);
493+
return;
494+
}
495+
}
496+
previousTopItemIndex = currentTopItemIndex;
497+
}
498+
})();";
499+
500+
var jsExecutor = (IJavaScriptExecutor)Browser;
501+
var noFlashingDetected = (bool)jsExecutor.ExecuteAsyncScript(detectFlashingScript);
502+
Assert.True(noFlashingDetected);
439503
}
440504

441505
[Theory]

src/Components/test/testassets/BasicTestApp/VirtualizationScale.razor

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
<div style="scale: @ScaleX @ScaleY; transform-origin: top left;">
22
<div id="virtualize" style="height: 200px; overflow: auto">
3-
<Virtualize ItemsProvider="@itemsProvider">
4-
<tr class="person"><span>@context.Name</span></tr>
5-
</Virtualize>
3+
<table>
4+
<tbody>
5+
<Virtualize ItemsProvider="@itemsProvider">
6+
<tr class="person"><span>@context.Id</span></tr>
7+
</Virtualize>
8+
</tbody>
9+
</table>
610
</div>
711
</div>
812

9-
<input type="number" @bind="ScaleX" />
10-
<input type="number" @bind="ScaleY" />
13+
<input type="number" @bind="ScaleX" id="scale-x-input" />
14+
<input type="number" @bind="ScaleY" id="scale-y-input" />
15+
<button id="btn">Click</button>
1116

1217
@code {
1318
internal class Person
@@ -16,8 +21,8 @@
1621
public string Name { get; set; } = string.Empty;
1722
}
1823

19-
public double ScaleX { get; set; } = 1.0;
20-
public double ScaleY { get; set; } = 1.0;
24+
public double? ScaleX { get; set; } = 1.0;
25+
public double? ScaleY { get; set; } = 1.0;
2126

2227
private ItemsProviderDelegate<Person> itemsProvider = default!;
2328

0 commit comments

Comments
 (0)