Files
Rtty/desktop/integration_test/e2e_test.dart

81 lines
3.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 端到端集成测试:在真实 Windows 桌面运行完整链路。
//
// 验证RustLib.init() → 点 CONNECT → TerminalEngineAlacritty Rust 引擎)创建
// → 连上服务端 → 命令回显(内容渲染 + 输入通路)。
//
// 运行前需先启动 Rust 服务端cd .. && cargo run
// 运行flutter test integration_test -d windows
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_alacritty/flutter_alacritty.dart';
import 'package:integration_test/integration_test.dart';
import 'package:rtty_desktop/main.dart' as app;
import 'package:rtty_desktop/src/terminal_screen.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('桌面端连接服务端并渲染命令输出', (WidgetTester tester) async {
await app.main();
await tester.pumpAndSettle();
// 未连接提示。
expect(find.text('AWAITING CONNECTION'), findsOneWidget);
// 点击 CONNECT。
await tester.tap(find.text('CONNECT'));
await tester.pump();
// 等待连接就绪(进入 connected 状态,提示页消失)。
final deadline = DateTime.now().add(const Duration(seconds: 8));
while (DateTime.now().isBefore(deadline)) {
await tester.pump(const Duration(milliseconds: 200));
if (find.text('AWAITING CONNECTION').evaluate().isEmpty) break;
}
expect(find.text('AWAITING CONNECTION'), findsNothing,
reason: '连接后应进入终端渲染');
// Alacritty TerminalView 应渲染。
expect(find.byType(TerminalView), findsOneWidget,
reason: 'Alacritty TerminalView 应渲染');
// 通过引擎输出通路发送一条命令(模拟用户输入),验证:
// 服务端回显 → backend.output → engine.feed → 网格渲染。
final engine = tester.state<TerminalViewState>(find.byType(TerminalView)).widget.engine;
final token = 'RTTY_INT_${DateTime.now().millisecondsSinceEpoch}';
engine.write(Uint8List.fromList('echo $token\r\n'.codeUnits));
// 轮询引擎网格,等待命令回显进入渲染。
String? found;
final outDeadline = DateTime.now().add(const Duration(seconds: 8));
while (DateTime.now().isBefore(outDeadline)) {
await tester.pump(const Duration(milliseconds: 200));
final gridText = _gridText(engine);
if (gridText.contains(token)) {
found = gridText;
break;
}
}
expect(found, isNotNull, reason: '命令回显应进入引擎网格');
debugPrint('回显捕获: ${found!.trim().split('\n').last}');
// 输入通路也验证TerminalView 聚焦时按键应经 engine.write → backend → 服务端。
expect(find.byType(TerminalScreen), findsOneWidget);
});
}
/// 从引擎镜像网格提取可视文本。
String _gridText(TerminalEngine engine) {
final grid = engine.gridForView;
final sb = StringBuffer();
for (var r = 0; r < grid.rows; r++) {
for (var c = 0; c < grid.columns; c++) {
final cp = grid.codepointAt(r, c);
sb.writeCharCode(cp == 0 ? 32 : cp);
}
sb.write('\n');
}
return sb.toString();
}