- Dart Web 브라우저 E2E 테스트 프레임워크 추가 - browser_ws_dart_io_test, browser_ws_kotlin_test 등 브라우저 통합 테스트 추가 - Dart Web 크로스테스트 케이스 추가 (go, kotlin, python, typescript) - TypeScript 브라우저 웹소켓 클라이언트 개선 - Node.js 웹소켓 서버 클라이언트 업데이트 - 테스트 실행 매트릭스 스킬 및 스크립트 업데이트 - README.md 문서 업데이트
111 lines
3.3 KiB
Dart
111 lines
3.3 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:proto_socket/proto_socket.dart';
|
|
|
|
const _host = '127.0.0.1';
|
|
const _wsPort = 29098;
|
|
const _heartbeatIntervalSeconds = 30;
|
|
const _heartbeatWaitSeconds = 10;
|
|
const _serverObservationWindow = Duration(milliseconds: 500);
|
|
const _processTimeout = Duration(seconds: 60);
|
|
const _streamTimeout = Duration(seconds: 5);
|
|
|
|
final _repoRoot = File.fromUri(Platform.script).parent.parent.parent.path;
|
|
final _dartDir = Directory('$_repoRoot/dart').path;
|
|
|
|
class _ServerWsClient extends WsProtobufClient {
|
|
_ServerWsClient(WebSocket ws)
|
|
: super(ws, _heartbeatIntervalSeconds, _heartbeatWaitSeconds, {
|
|
TestData.getDefault().info_.qualifiedMessageName: TestData.fromBuffer,
|
|
});
|
|
}
|
|
|
|
class _DartWebWsServer extends WsProtobufServer {
|
|
final void Function(WsProtobufClient) onConnected;
|
|
|
|
_DartWebWsServer(int port, this.onConnected)
|
|
: super(_host, port, (ws) => _ServerWsClient(ws));
|
|
|
|
@override
|
|
void onClientConnected(WsProtobufClient client) => onConnected(client);
|
|
}
|
|
|
|
Future<void> main() async {
|
|
print(
|
|
'INFO typeName dart=${TestData.getDefault().info_.qualifiedMessageName}');
|
|
try {
|
|
await _runWebWsSuite();
|
|
print('PASS scenario=send-push');
|
|
print('PASS scenario=request-response');
|
|
print('PASS all dart-server/dart-web-client crosstests passed');
|
|
} catch (error) {
|
|
stderr.writeln('FAIL crosstest error=$error');
|
|
exitCode = 1;
|
|
}
|
|
}
|
|
|
|
Future<void> _runWebWsSuite() async {
|
|
final received = Completer<bool>();
|
|
final server = _DartWebWsServer(_wsPort, (client) {
|
|
client.addRequestListener<TestData, TestData>((req) async {
|
|
print('SERVER_RECEIVED index=${req.index} message=${req.message}');
|
|
if (req.index == 101 && req.message == 'fire from dart web client') {
|
|
if (!received.isCompleted) {
|
|
received.complete(true);
|
|
}
|
|
unawaited(client.send(TestData()
|
|
..index = 200
|
|
..message = 'push from dart server'));
|
|
}
|
|
return TestData()
|
|
..index = req.index * 2
|
|
..message = 'echo: ${req.message}';
|
|
});
|
|
});
|
|
|
|
await server.start();
|
|
try {
|
|
await _runDartBrowserTest('test/browser_ws_dart_io_test.dart');
|
|
final ok = await received.future
|
|
.timeout(_serverObservationWindow, onTimeout: () => false);
|
|
if (!ok) {
|
|
throw StateError('WS web send-push server did not receive expected data');
|
|
}
|
|
} finally {
|
|
await server.stop();
|
|
}
|
|
}
|
|
|
|
Future<void> _runDartBrowserTest(String testPath) async {
|
|
final process = await Process.start(
|
|
'dart',
|
|
['test', '-p', 'chrome', testPath],
|
|
workingDirectory: _dartDir,
|
|
);
|
|
|
|
final stdoutDone = process.stdout
|
|
.transform(utf8.decoder)
|
|
.transform(const LineSplitter())
|
|
.listen(print)
|
|
.asFuture<void>();
|
|
|
|
final stderrDone = process.stderr
|
|
.transform(utf8.decoder)
|
|
.transform(const LineSplitter())
|
|
.listen(stderr.writeln)
|
|
.asFuture<void>();
|
|
|
|
final code = await process.exitCode.timeout(_processTimeout, onTimeout: () {
|
|
process.kill(ProcessSignal.sigkill);
|
|
return -1;
|
|
});
|
|
await Future.wait([stdoutDone, stderrDone])
|
|
.timeout(_streamTimeout, onTimeout: () {
|
|
throw StateError('dart browser test streams did not finish');
|
|
});
|
|
if (code != 0) {
|
|
throw StateError('dart browser test failed exitCode=$code');
|
|
}
|
|
}
|