mirror of https://github.com/AMT-Cheif/drift.git
167 lines
5.0 KiB
Dart
167 lines
5.0 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:isolate';
|
|
|
|
import 'package:build_daemon/client.dart';
|
|
import 'package:build_daemon/constants.dart';
|
|
import 'package:build_daemon/data/build_status.dart';
|
|
import 'package:build_daemon/data/build_target.dart';
|
|
import 'package:collection/collection.dart';
|
|
import 'package:package_config/package_config.dart';
|
|
import 'package:path/path.dart' as p;
|
|
import 'package:shelf/shelf_io.dart';
|
|
import 'package:shelf_proxy/shelf_proxy.dart';
|
|
import 'package:web_wasm/initialization_mode.dart';
|
|
import 'package:webdriver/async_io.dart';
|
|
// ignore: implementation_imports
|
|
import 'package:drift/src/web/wasm_setup/types.dart';
|
|
|
|
class TestAssetServer {
|
|
final BuildDaemonClient buildRunner;
|
|
late final HttpServer server;
|
|
|
|
TestAssetServer(this.buildRunner);
|
|
|
|
Future<void> close() async {
|
|
await server.close(force: true);
|
|
await buildRunner.close();
|
|
}
|
|
|
|
static Future<TestAssetServer> start() async {
|
|
final packageConfig =
|
|
await loadPackageConfigUri((await Isolate.packageConfig)!);
|
|
final ownPackage = packageConfig['web_wasm']!.root;
|
|
var packageDir = ownPackage.toFilePath(windows: Platform.isWindows);
|
|
if (packageDir.endsWith('/')) {
|
|
packageDir = packageDir.substring(0, packageDir.length - 1);
|
|
}
|
|
|
|
final buildRunner = await BuildDaemonClient.connect(
|
|
packageDir,
|
|
[
|
|
Platform.executable, // dart
|
|
'run',
|
|
'build_runner',
|
|
'daemon',
|
|
],
|
|
logHandler: (log) => print(log.message),
|
|
);
|
|
|
|
buildRunner
|
|
..registerBuildTarget(DefaultBuildTarget((b) => b.target = 'web'))
|
|
..startBuild();
|
|
|
|
// Wait for the build to complete, so that the server we return is ready to
|
|
// go.
|
|
await buildRunner.buildResults.firstWhere((b) {
|
|
final buildResult = b.results.firstWhereOrNull((r) => r.target == 'web');
|
|
return buildResult != null && buildResult.status != BuildStatus.started;
|
|
});
|
|
|
|
final assetServerPortFile =
|
|
File(p.join(daemonWorkspace(packageDir), '.asset_server_port'));
|
|
final assetServerPort = int.parse(await assetServerPortFile.readAsString());
|
|
|
|
final server = TestAssetServer(buildRunner);
|
|
|
|
final proxy = proxyHandler('http://localhost:$assetServerPort/web/');
|
|
server.server = await serve(
|
|
(request) async {
|
|
final pathSegments = request.url.pathSegments;
|
|
|
|
if (pathSegments.isNotEmpty && pathSegments[0] == 'no-coep') {
|
|
// Serve stuff under /no-coep like the regular website, but without
|
|
// adding the security headers.
|
|
return await proxy(request.change(path: 'no-coep'));
|
|
} else {
|
|
final response = await proxy(request);
|
|
|
|
if (!request.url.path.startsWith('/no-coep')) {
|
|
return response.change(headers: {
|
|
// Needed for shared array buffers to work
|
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
'Cross-Origin-Embedder-Policy': 'require-corp'
|
|
});
|
|
}
|
|
|
|
return response;
|
|
}
|
|
},
|
|
'localhost',
|
|
8080,
|
|
);
|
|
|
|
return server;
|
|
}
|
|
}
|
|
|
|
class DriftWebDriver {
|
|
final TestAssetServer server;
|
|
final WebDriver driver;
|
|
|
|
DriftWebDriver(this.server, this.driver);
|
|
|
|
Future<
|
|
({
|
|
Set<WasmStorageImplementation> storages,
|
|
Set<MissingBrowserFeature> missingFeatures,
|
|
List<ExistingDatabase> existing,
|
|
})> probeImplementations() async {
|
|
final rawResult = await driver
|
|
.executeAsync('detectImplementations("", arguments[0])', []);
|
|
final result = json.decode(rawResult);
|
|
|
|
return (
|
|
storages: {
|
|
for (final entry in result['impls'])
|
|
WasmStorageImplementation.values.byName(entry)
|
|
},
|
|
missingFeatures: {
|
|
for (final entry in result['missing'])
|
|
MissingBrowserFeature.values.byName(entry)
|
|
},
|
|
existing: <ExistingDatabase>[
|
|
for (final entry in result['existing'])
|
|
(
|
|
WebStorageApi.byName[entry[0] as String]!,
|
|
entry[1] as String,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Future<void> openDatabase([WasmStorageImplementation? implementation]) async {
|
|
await driver.executeAsync(
|
|
'open(arguments[0], arguments[1])', [implementation?.name]);
|
|
}
|
|
|
|
Future<void> insertIntoDatabase() async {
|
|
await driver.executeAsync('insert("", arguments[0])', []);
|
|
}
|
|
|
|
Future<int> get amountOfRows async {
|
|
return await driver.executeAsync('get_rows("", arguments[0])', []);
|
|
}
|
|
|
|
Future<void> waitForTableUpdate() async {
|
|
await driver.executeAsync('wait_for_update("", arguments[0])', []);
|
|
}
|
|
|
|
Future<void> enableInitialization(InitializationMode mode) async {
|
|
final result = await driver.executeAsync(
|
|
'enable_initialization(arguments[0], arguments[1])',
|
|
[mode.name],
|
|
);
|
|
|
|
if (result != true) {
|
|
throw 'Could not set initialization mode';
|
|
}
|
|
}
|
|
|
|
Future<void> deleteDatabase(WebStorageApi storageApi, String name) async {
|
|
await driver.executeAsync('delete_database(arguments[0], arguments[1])', [
|
|
json.encode([storageApi.name, name]),
|
|
]);
|
|
}
|
|
}
|