test(studio): lock sidebar destination Y-stability on rail expansion
Adds a widget test asserting each destination icon keeps its Y position whether the rail is collapsed or expanded — a recurring regression. To drive expansion without a hover gesture (which trips RenderFlex overflow mid-transition), a test-only startSidebarExpanded flag threads StudioApp -> StudioShell -> _Sidebar (controller starts at 1.0, hover disabled); _SidebarItems get stable ValueKeys. analyze clean; new test and the existing smoke test pass. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
d66f46f133
commit
36a8252f67
2 changed files with 103 additions and 5 deletions
|
|
@ -60,11 +60,18 @@ class StudioApp extends StatefulWidget {
|
|||
/// ChainTheme.
|
||||
final String? initialThemePlugin;
|
||||
|
||||
/// Test-only: start the sidebar expanded (no hover). Lets a widget
|
||||
/// test assert destination-icon Y stability across collapsed vs
|
||||
/// expanded without a hover gesture (which trips RenderFlex overflow
|
||||
/// mid-transition). Always false in production.
|
||||
final bool startSidebarExpanded;
|
||||
|
||||
const StudioApp({
|
||||
super.key,
|
||||
required this.initialThemeMode,
|
||||
required this.initialLocale,
|
||||
this.initialThemePlugin,
|
||||
this.startSidebarExpanded = false,
|
||||
});
|
||||
|
||||
/// Lookup helper so descendants can flip the theme without
|
||||
|
|
@ -226,7 +233,9 @@ class StudioAppState extends State<StudioApp> {
|
|||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localizationsDelegates:
|
||||
AppLocalizations.localizationsDelegates,
|
||||
home: const StudioShell(),
|
||||
home: StudioShell(
|
||||
startSidebarExpanded: widget.startSidebarExpanded,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
@ -237,7 +246,10 @@ class StudioAppState extends State<StudioApp> {
|
|||
}
|
||||
|
||||
class StudioShell extends StatefulWidget {
|
||||
const StudioShell({super.key});
|
||||
/// Test-only: forward to the sidebar so it starts expanded.
|
||||
final bool startSidebarExpanded;
|
||||
|
||||
const StudioShell({super.key, this.startSidebarExpanded = false});
|
||||
|
||||
@override
|
||||
State<StudioShell> createState() => StudioShellState();
|
||||
|
|
@ -523,6 +535,7 @@ class StudioShellState extends State<StudioShell> {
|
|||
endpointLabel: HubService.instance.endpointLabel,
|
||||
activeChannel: _activeChannel,
|
||||
pendingApprovals: _pendingApprovals,
|
||||
forceExpanded: widget.startSidebarExpanded,
|
||||
),
|
||||
Container(width: 1, color: theme.colorScheme.outlineVariant),
|
||||
Expanded(
|
||||
|
|
@ -649,6 +662,11 @@ class _Sidebar extends StatefulWidget {
|
|||
/// without polling the page.
|
||||
final int pendingApprovals;
|
||||
|
||||
/// Test-only: start fully expanded (controller at 1.0) and disable
|
||||
/// hover, so a widget test can measure the expanded layout without a
|
||||
/// hover gesture. Always false in production.
|
||||
final bool forceExpanded;
|
||||
|
||||
const _Sidebar({
|
||||
required this.selectedIndex,
|
||||
required this.onSelect,
|
||||
|
|
@ -657,6 +675,7 @@ class _Sidebar extends StatefulWidget {
|
|||
required this.endpointLabel,
|
||||
required this.activeChannel,
|
||||
this.pendingApprovals = 0,
|
||||
this.forceExpanded = false,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -694,7 +713,7 @@ class _SidebarState extends State<_Sidebar>
|
|||
// the rail feels crisp rather than sluggish.
|
||||
duration: ChainMotion.slow,
|
||||
reverseDuration: ChainMotion.base,
|
||||
value: 0,
|
||||
value: widget.forceExpanded ? 1 : 0,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -740,8 +759,8 @@ class _SidebarState extends State<_Sidebar>
|
|||
final hasChannel =
|
||||
widget.activeChannel != null && widget.activeChannel!.isNotEmpty;
|
||||
return MouseRegion(
|
||||
onEnter: (_) => _ctrl.forward(),
|
||||
onExit: (_) => _ctrl.reverse(),
|
||||
onEnter: widget.forceExpanded ? null : (_) => _ctrl.forward(),
|
||||
onExit: widget.forceExpanded ? null : (_) => _ctrl.reverse(),
|
||||
child: AnimatedBuilder(
|
||||
animation: _ctrl,
|
||||
builder: (context, _) {
|
||||
|
|
@ -837,6 +856,7 @@ class _SidebarState extends State<_Sidebar>
|
|||
children: [
|
||||
for (var i = 0; i < widget.pages.length; i++)
|
||||
_SidebarItem(
|
||||
key: ValueKey('sidebar-item-${widget.pages[i].id}'),
|
||||
page: widget.pages[i],
|
||||
selected: i == widget.selectedIndex,
|
||||
t: t,
|
||||
|
|
@ -1342,6 +1362,7 @@ class _SidebarItem extends StatefulWidget {
|
|||
final int? badge;
|
||||
|
||||
const _SidebarItem({
|
||||
super.key,
|
||||
required this.page,
|
||||
required this.selected,
|
||||
required this.t,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue