Skip to content

Commit fa08067

Browse files
committed
stabilize floating toolbar anchor assertion
1 parent fc78b67 commit fa08067

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

ci-workflows-release-pr-validation.plan.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,19 @@ Root-cause note:
222222
- mac-only keyboard shortcuts in UI tests (`Meta+A`, `Meta+Z`, `Meta+Shift+Z`) that broke Linux editor shortcuts and typing flows
223223
- browser-suite self-contention from `4` parallel xUnit workers inside one process on the slower GitHub runner
224224
- route/readiness assertions still relying on Playwright's short default timeouts instead of the suite's WASM-specific timeout budget
225+
- GitHub runs `23815330400` and `23815334683` proved the stability fixes removed all but one browser failure:
226+
- `PrompterLive.App.UITests.EditorFloatingToolbarLayoutTests.EditorScreen_FloatingToolbarStaysPinnedAfterFloatingFormatAction`
227+
- Root cause note: the test asserted `getBoundingClientRect().x/y` drift after the format action even though the production floating-toolbar contract preserves the inline/computed anchor (`left` and `top`) and the element itself is centered with `transform: translate(-50%, ...)`. Linux font/layout differences moved the rendered box without breaking the preserved anchor.
228+
- Intended fix path: assert the preserved computed anchor coordinates instead of bounding-box drift, and keep the visibility check after the floating action.
225229
- Local validation after the browser-suite stability fixes passed:
226230
- `dotnet build /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx -warnaserror`
227231
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.Core.Tests/PrompterLive.Core.Tests.csproj --no-build`
228232
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.App.Tests/PrompterLive.App.Tests.csproj --no-build`
229233
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.App.UITests/PrompterLive.App.UITests.csproj --no-build`
234+
- Local validation after the floating-toolbar anchor assertion fix passed:
235+
- `dotnet build /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx -warnaserror`
236+
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.App.UITests/PrompterLive.App.UITests.csproj --no-build`
237+
- `dotnet format /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx`
230238

231239
## Final Validation Skills And Commands
232240

tests/PrompterLive.App.UITests/Editor/EditorFloatingToolbarLayoutTests.cs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ namespace PrompterLive.App.UITests;
77
public sealed class EditorFloatingToolbarLayoutTests(StandaloneAppFixture fixture) : IClassFixture<StandaloneAppFixture>
88
{
99
private const string SegmentLineSelector = ".ed-src-line-segment";
10-
private readonly record struct LayoutBounds(double X, double Y, double Width, double Height);
10+
private readonly record struct LayoutBounds(double Y, double Height);
11+
private readonly record struct ToolbarAnchor(double Left, double Top);
1112
private readonly StandaloneAppFixture _fixture = fixture;
1213

1314
[Fact]
@@ -158,19 +159,20 @@ await sourceInput.EvaluateAsync(
158159
await Expect(floatingBar).ToBeVisibleAsync();
159160
await page.WaitForTimeoutAsync(BrowserTestConstants.Timing.FloatingToolbarSettleDelayMs);
160161

161-
var before = await GetRequiredBoundingBoxAsync(floatingBar);
162+
var before = await GetRequiredAnchorAsync(floatingBar);
162163

163164
await page.GetByTestId(UiTestIds.Editor.FloatEmphasis).ClickAsync();
165+
await Expect(floatingBar).ToBeVisibleAsync();
164166
await page.WaitForTimeoutAsync(BrowserTestConstants.Timing.FloatingToolbarSettleDelayMs);
165167

166-
var after = await GetRequiredBoundingBoxAsync(floatingBar);
168+
var after = await GetRequiredAnchorAsync(floatingBar);
167169

168170
Assert.InRange(
169-
Math.Abs(after.X - before.X),
171+
Math.Abs(after.Left - before.Left),
170172
0,
171173
BrowserTestConstants.Editor.FloatingBarPinnedMaxDriftPx);
172174
Assert.InRange(
173-
Math.Abs(after.Y - before.Y),
175+
Math.Abs(after.Top - before.Top),
174176
0,
175177
BrowserTestConstants.Editor.FloatingBarPinnedMaxDriftPx);
176178
}
@@ -186,13 +188,23 @@ await locator.EvaluateAsync<LayoutBounds>(
186188
element => {
187189
const rect = element.getBoundingClientRect();
188190
return {
189-
x: rect.x,
190191
y: rect.y,
191-
width: rect.width,
192192
height: rect.height
193193
};
194194
}
195195
""");
196196

197+
private static async Task<ToolbarAnchor> GetRequiredAnchorAsync(ILocator locator) =>
198+
await locator.EvaluateAsync<ToolbarAnchor>(
199+
"""
200+
element => {
201+
const style = window.getComputedStyle(element);
202+
return {
203+
left: Number.parseFloat(style.left),
204+
top: Number.parseFloat(style.top)
205+
};
206+
}
207+
""");
208+
197209
private readonly record struct SelectionGeometry(double SelectionTop);
198210
}

0 commit comments

Comments
 (0)