import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:glitch_gm_lab/room_page.dart'; void main() { for (final width in [390.0, 900.0, 1400.0]) { testWidgets('room panels fit at width $width and use authoritative revision', (tester) async { WidgetController.hitTestWarningShouldBeFatal = true; addTearDown(() => WidgetController.hitTestWarningShouldBeFatal = false); tester.view.devicePixelRatio = 1; tester.view.physicalSize = Size(width, 1000); addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); final data = jsonDecode(File('test/fixtures/room.json').readAsStringSync()); final state = data['state'] as Map; Map? sent; final client = MockClient((request) async { if (request.method == 'POST') { sent = jsonDecode(request.body); return http.Response(jsonEncode({'accepted':true,'message':'test accepted','state':state}), 200); } if (request.url.path.endsWith('trace')) { return http.Response(jsonEncode({'trace':[],'final_hash':'fixture'}),200); } return http.Response(jsonEncode({'state':state}),200); }); await tester.pumpWidget(MaterialApp(home:RoomPage(client:client))); await tester.pump(); expect(find.textContaining('Connected. The room timer'), findsOneWidget); expect(tester.takeException(), isNull); Future select(String name) async { if (width < 900) { await tester.tap(find.byTooltip('Open navigation menu')); await tester.pumpAndSettle(); } await tester.ensureVisible(find.text(name)); await tester.tap(find.text(name)); await tester.pumpAndSettle(); } await select('Diagnostics'); await tester.ensureVisible(find.text('+ 1 second')); await tester.tap(find.text('+ 1 second')); await tester.pump(); expect(sent?['expected_revision'], state['revision']); expect(sent?['run_id'], state['run_id']); for (final tab in ['Cabinets','Ship & Cells','Calibration & Launch','Teddy','Diagnostics','Room Flow']) { await select(tab); expect(tester.takeException(), isNull, reason:tab); } state['phase']='CALIBRATION'; state['wave']={'id':99,'targets':{'cabinet_01':2},'ready':{},'deadline':40000,'retry_at':0}; await tester.pump(const Duration(seconds:1)); await tester.pump(); await select('Calibration & Launch'); expect(find.text('Simulate held Ready'), findsOneWidget); expect(tester.takeException(), isNull); await tester.pumpWidget(const SizedBox()); }); } testWidgets('disconnected room disables mutating controls', (tester) async { await tester.pumpWidget(MaterialApp(home:RoomPage(client:MockClient((_) async => http.Response('{}',503))))); await tester.pump(); expect(find.textContaining('disconnected'),findsOneWidget); for (final button in tester.widgetList(find.byType(OutlinedButton))) { expect(button.onPressed,isNull); } await tester.pumpWidget(const SizedBox()); }); }