fix(vacaciones): header Add action, info banner, dashed CTA, collapse
Audit 9b.1 (t4:446): a solid brand-teal "Add" header action -- the
prototype's own mid-page CTA (audit 9b.6, still present, now dashed)
is a SECOND, additional entry point, not a replacement.
Audit 9b.2 (t4:448): the teal explanatory banner ("alarms marked
pause-during-vacations won't ring...") is now ALWAYS visible -- never
rendered before. New ARB key vacationExplainerBanner, all 13 locales.
Audit 9b.6 (t4:487): the bottom CTA is now dashed-border with a
date_range glyph -- was a solid OutlinedButton with an add glyph.
Reuses the dashed-painter shape already established in
pantalla_favoritos.dart's custom-station CTA (audit 4.5), duplicated
rather than shared.
Audit 9b.7 (t4:489): "Rangos pasados" is now a collapsible row --
icon, title, count, chevron -- COLLAPSED by default, expanding on tap.
Was always fully expanded inline. Updated the pre-existing widget test
to tap-then-assert instead of asserting immediate visibility.
Item 9b.3 (the eyebrow literally reading "EN CURSO") is NOT
implemented: the eyebrow STYLING is already correct (audit 9b.4), and
the residual copy gap is a shared ARB string
(vacationSummaryActiveCountdown) also used compactly in
pantalla_alarmas.dart's vacation summary row -- diverging its wording
just for this screen's eyebrow, or forcing a shoutier tone into that
other compact usage, is not worth it for a trivial-rated copy nuance.
This commit is contained in:
@@ -180,7 +180,8 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'los rangos pasados aparecen bajo el encabezado "Rangos pasados"',
|
||||
'los rangos pasados aparecen bajo el encabezado "Rangos pasados" tras '
|
||||
'expandir la fila (audit 9b.7: colapsada por defecto, t4:489)',
|
||||
(tester) async {
|
||||
final estado = await _crearEstado(
|
||||
vacaciones: [
|
||||
@@ -201,6 +202,10 @@ void main() {
|
||||
tester.element(find.byType(PantallaVacaciones)),
|
||||
);
|
||||
expect(find.text(l10n.vacationPastSectionTitle), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text(l10n.vacationPastSectionTitle));
|
||||
await _pumpEstable(tester);
|
||||
|
||||
expect(find.text('Rango viejo'), findsOneWidget);
|
||||
},
|
||||
);
|
||||
@@ -343,4 +348,101 @@ void main() {
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
group('visual fidelity (audit 9b.1/9b.2/9b.6/9b.7)', () {
|
||||
testWidgets(
|
||||
'9b.1: a header "Add" action is reachable and opens the same form '
|
||||
'as the CTA (t4:446)',
|
||||
(tester) async {
|
||||
final estado = await _crearEstado();
|
||||
addTearDown(estado.dispose);
|
||||
|
||||
await tester.pumpWidget(_buildScreen(estado));
|
||||
await _pumpEstable(tester);
|
||||
|
||||
final l10n = AppLocalizations.of(
|
||||
tester.element(find.byType(PantallaVacaciones)),
|
||||
);
|
||||
final appBar = tester.widget<AppBar>(find.byType(AppBar));
|
||||
expect(appBar.actions, isNotNull);
|
||||
expect(appBar.actions, isNotEmpty);
|
||||
|
||||
await tester.tap(find.byKey(const ValueKey('vacation-add-header')));
|
||||
await _pumpEstable(tester);
|
||||
|
||||
expect(find.text(l10n.newVacationRangeTitle), findsOneWidget);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'9b.2: the explanatory info banner is always visible (t4:448)',
|
||||
(tester) async {
|
||||
final estado = await _crearEstado();
|
||||
addTearDown(estado.dispose);
|
||||
|
||||
await tester.pumpWidget(_buildScreen(estado));
|
||||
await _pumpEstable(tester);
|
||||
|
||||
final l10n = AppLocalizations.of(
|
||||
tester.element(find.byType(PantallaVacaciones)),
|
||||
);
|
||||
expect(find.text(l10n.vacationExplainerBanner), findsOneWidget);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'9b.6: the bottom CTA has a dashed border and a date_range icon '
|
||||
'(t4:487)',
|
||||
(tester) async {
|
||||
final estado = await _crearEstado();
|
||||
addTearDown(estado.dispose);
|
||||
|
||||
await tester.pumpWidget(_buildScreen(estado));
|
||||
await _pumpEstable(tester);
|
||||
|
||||
expect(find.byIcon(Icons.date_range_rounded), findsOneWidget);
|
||||
// Exactly ONE add_rounded on the whole screen -- the header's OWN
|
||||
// "Add" action (audit 9b.1). The bottom CTA no longer uses it.
|
||||
expect(find.byIcon(Icons.add_rounded), findsOneWidget);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'9b.7: "Rangos pasados" is collapsed by default, showing a count, '
|
||||
'and expands on tap (t4:489)',
|
||||
(tester) async {
|
||||
final estado = await _crearEstado(
|
||||
vacaciones: [
|
||||
RangoVacaciones(
|
||||
id: 'pa1',
|
||||
nombre: 'Rango viejo',
|
||||
inicio: _hoyDia.subtract(const Duration(days: 30)),
|
||||
fin: _hoyDia.subtract(const Duration(days: 20)),
|
||||
),
|
||||
],
|
||||
);
|
||||
addTearDown(estado.dispose);
|
||||
|
||||
await tester.pumpWidget(_buildScreen(estado));
|
||||
await _pumpEstable(tester);
|
||||
|
||||
final l10n = AppLocalizations.of(
|
||||
tester.element(find.byType(PantallaVacaciones)),
|
||||
);
|
||||
expect(find.text(l10n.vacationPastSectionTitle), findsOneWidget);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
expect(
|
||||
find.text('Rango viejo'),
|
||||
findsNothing,
|
||||
reason:
|
||||
'collapsed by default -- matches the prototype count-only row',
|
||||
);
|
||||
|
||||
await tester.tap(find.text(l10n.vacationPastSectionTitle));
|
||||
await _pumpEstable(tester);
|
||||
|
||||
expect(find.text('Rango viejo'), findsOneWidget);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user