Run web tests in CI

This commit is contained in:
Simon Binder
2024-07-28 00:09:33 +02:00
parent d743b94028
commit ec1649342f
10 changed files with 327 additions and 11 deletions
+77
View File
@@ -98,6 +98,67 @@ jobs:
# moor/.dart_tool/package_config.json
# retention-days: 1
drift_web_ddc:
needs: [drift]
runs-on: ubuntu-latest
defaults:
run:
working-directory: drift
steps:
# setup
- uses: actions/checkout@v4
- uses: ./.github/actions/prepare
with:
dart_version: ${{ needs.setup.outputs.dart_version }}
- run: melos bootstrap --scope drift
working-directory: .
# Using build_runner test allows compiling the tests with ddc, which is much faster than
# dart2js since we have a lot of entrypoints.
- run: dart run tool/test_with_ddc.dart
# todo: Even with shards, dart2js take too long. We run unit tests with ddc and dart2wasm and
# also run web integration tests (compiled with dart2js), so maybe we don't need those?
# drift_web_dart2js:
# needs: [drift]
# runs-on: ubuntu-latest
# defaults:
# run:
# working-directory: drift
# strategy:
# matrix:
# browser: [chrome, firefox]
# shard: [0, 1, 2, 3]
# name: "Drift web unit tests, dart2js, ${{ matrix.browser }}, shard ${{ matrix.shard }}"
# steps:
# # setup
# - uses: actions/checkout@v4
# - uses: ./.github/actions/prepare
# with:
# dart_version: ${{ needs.setup.outputs.dart_version }}
# - run: melos bootstrap --scope drift
# working-directory: .
# - run: dart test -p ${{ matrix.browser }} --compiler dart2js --total-shards 4 --shard-index ${{ matrix.shard }}
drift_web_dart2wasm:
needs: [drift]
runs-on: ubuntu-latest
defaults:
run:
working-directory: drift
strategy:
matrix:
browser: [chrome, firefox]
name: "Drift web unit tests, dart2wasm, ${{ matrix.browser }}"
steps:
# setup
- uses: actions/checkout@v4
- uses: ./.github/actions/prepare
with:
dart_version: ${{ needs.setup.outputs.dart_version }}
- run: melos bootstrap --scope drift
working-directory: .
- run: dart test -p ${{ matrix.browser }} --compiler dart2wasm
drift_dev:
runs-on: ubuntu-latest
needs: [setup]
@@ -266,6 +327,22 @@ jobs:
- name: Check that extracting schema still works
working-directory: examples/migrations_example
run: dart run drift_dev schema dump lib/database.dart drift_migrations/
web_integration_tests:
name: "Web integration tests"
needs: [drift]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/prepare
with:
dart_version: ${{ needs.setup.outputs.dart_version }}
- uses: nanasess/setup-chromedriver@v2
- run: melos bootstrap --scope web_wasm
working-directory: .
- name: Test
working-directory: extras/integration_tests/web_wasm
run: dart test
# upload_coverage:
# runs-on: ubuntu-20.04
# needs: [moor, sqlparser]
+92
View File
@@ -0,0 +1,92 @@
# This file needs to be kept in sync with `build.yaml`.
# It is used to also compile the test entrypoints with dart2js, a
# resource-intensive operation we don't want to run by default.
targets:
drift_regular:
auto_apply_builders: false
sources:
exclude:
# Exlude sources used for the drift-file based generation source
- "test/generated/custom_tables.dart"
- "test/generated/data_classes.dart"
- "test/generated/tables.drift*"
builders:
drift_dev:
enabled: true
generate_for:
exclude:
# Exlude sources used for the drift-file based generation source
- "test/generated/custom_tables.dart"
- "test/generated/data_classes.dart"
- "test/generated/tables.drift*"
options:
override_hash_and_equals_in_result_sets: true
use_column_name_as_json_key_when_defined_in_moor_file: true
write_from_json_string_constructor: true
raw_result_set_data: true
named_parameters: true
fatal_warnings: true
sql:
dialect: sqlite
options:
version: "3.37"
modules:
- json1
- fts5
- geopoly
drift_custom:
auto_apply_builders: false
sources:
- "test/generated/custom_tables.dart"
- "test/generated/data_classes.dart"
- "test/generated/tables.drift*"
builders:
drift_dev:
options:
fatal_warnings: true
store_date_time_values_as_text: true
# Dart doesn't support YAML merge tags yet, https://github.com/dart-lang/yaml/issues/121
override_hash_and_equals_in_result_sets: true
use_column_name_as_json_key_when_defined_in_moor_file: true
write_from_json_string_constructor: true
raw_result_set_data: true
named_parameters: true
sql:
dialect: sqlite
options:
version: "3.37"
modules:
- json1
- fts5
- geopoly
web_worker:
auto_apply_builders: false
builders:
build_web_compilers:entrypoint:
enabled: true
generate_for:
- "web/drift_worker.dart"
options:
compiler: dart2js
tests:
auto_apply_builders: false
builders:
build_test:test_bootstrap:
enabled: true
$default:
dependencies: [:drift_regular, :drift_custom, :web_worker, :tests]
builders:
build_test:test_bootstrap:
enabled: false
drift_dev:
enabled: false
build_web_compilers:entrypoint:
enabled: true
generate_for:
- "test/**.browser_test.dart"
options:
compiler: dartdevc
+34 -8
View File
@@ -6,7 +6,8 @@
# This way, we get to write integration tests for both date time modes.
targets:
$default:
drift_regular:
auto_apply_builders: false
sources:
exclude:
# Exlude sources used for the drift-file based generation source
@@ -15,6 +16,13 @@ targets:
- "test/generated/tables.drift*"
builders:
drift_dev:
enabled: true
generate_for:
exclude:
# Exlude sources used for the drift-file based generation source
- "test/generated/custom_tables.dart"
- "test/generated/data_classes.dart"
- "test/generated/tables.drift*"
options:
override_hash_and_equals_in_result_sets: true
use_column_name_as_json_key_when_defined_in_moor_file: true
@@ -30,13 +38,7 @@ targets:
- json1
- fts5
- geopoly
build_web_compilers:entrypoint:
generate_for:
- "web/drift_worker.dart"
options:
compiler: dart2js
custom:
drift_custom:
auto_apply_builders: false
sources:
- "test/generated/custom_tables.dart"
@@ -61,3 +63,27 @@ targets:
- json1
- fts5
- geopoly
web_worker:
auto_apply_builders: false
builders:
build_web_compilers:entrypoint:
enabled: true
generate_for:
- "web/drift_worker.dart"
options:
compiler: dart2js
$default:
dependencies: [:drift_regular, :drift_custom, :web_worker]
builders:
build_test:test_bootstrap:
enabled: false
drift_dev:
enabled: false
build_web_compilers:entrypoint:
enabled: true
generate_for:
- "test/**.browser_test.dart"
options:
compiler: dartdevc
+1
View File
@@ -47,3 +47,4 @@ dev_dependencies:
test_descriptor: ^2.0.1
vm_service: ^14.0.0
rxdart: ^0.28.0
build_daemon: ^4.0.2
@@ -39,6 +39,8 @@ void main() {
sqlite3 = await WasmSqlite3.loadFromUrl(
Uri.parse('http://localhost:$port/sqlite3.wasm'));
sqlite3.registerVirtualFileSystem(fs, makeDefault: true);
channel.sink.close();
});
runAllTests(DriftWasmExecutor(fs, () => sqlite3));
+2
View File
@@ -20,6 +20,8 @@ Future<WasmSqlite3> get sqlite3 {
final sqlite = await WasmSqlite3.loadFromUrl(
Uri.parse('http://localhost:$port/sqlite3.wasm'));
sqlite.registerVirtualFileSystem(InMemoryFileSystem(), makeDefault: true);
channel.sink.close();
return sqlite;
});
}
+101
View File
@@ -0,0 +1,101 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:build_daemon/client.dart';
import 'package:build_daemon/data/build_target.dart';
import 'package:build_daemon/data/build_status.dart';
/// For some reason, `build_runner test` doesn't stop even after tests have
/// completed. I couldn't figure out why it does that.
/// So, we're re-implementing it here by first running a build and then running
/// precompiled tests, exiting once we see a line indicating that tests are
/// done.
///
/// The proper way to run ddc tests would be
///
/// ```
/// dart run build_runner test -d -c test -- -p chrome
/// ```
///
/// https://www.xkcd.com/1495/
void main() async {
final client = await BuildDaemonClient.connect(
Directory.current.path,
[Platform.executable, 'run', 'build_runner', 'daemon', '-d', '-c', 'test'],
logHandler: (log) => print(log.message),
);
final directory = await Directory.systemTemp.createTemp('drift');
client.registerBuildTarget(DefaultBuildTarget((b) {
b.target = 'test';
b.outputLocation
..output = directory.path
..useSymlinks = false
..hoist = false;
}));
client.startBuild();
listen:
await for (final results in client.buildResults) {
for (final result in results.results) {
switch (result.status) {
case BuildStatus.failed:
print('Could not run build');
exitCode = 1;
return;
case BuildStatus.succeeded:
print('Build complete');
break listen;
case BuildStatus.started:
break;
}
}
}
await client.close();
final process = await Process.start(
Platform.executable,
[
'run',
'test',
'--precompiled',
directory.absolute.path,
'-p',
'chrome',
'-p',
'firefox',
'-r',
'compact',
],
);
Completer<int> manualExitCode = Completer();
process.stderr.pipe(stderr);
final subscription = process.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
stdout.writeln(line);
if (line.contains('All tests passed')) {
print('Stopping with success exit code');
manualExitCode.complete(0);
} else if (line.contains('Some tests failed')) {
print('Stopping with failure exit code');
manualExitCode.complete(1);
}
});
final result = await Future.any([
process.exitCode,
manualExitCode.future.whenComplete(() => subscription.cancel()),
]);
await directory.delete(recursive: true);
exit(result);
}
@@ -2,5 +2,7 @@ targets:
$default:
builders:
build_web_compilers:entrypoint:
generate_for:
- web/**
options:
compiler: dart2js
@@ -43,6 +43,7 @@ class TestAssetServer {
'run',
'build_runner',
'daemon',
'-d',
if (debug)
'--define=build_web_compilers:entrypoint=dart2js_args=["-Dsqlite3.wasm.worker.debug=true"]'
],
@@ -90,7 +91,7 @@ class TestAssetServer {
}
},
'localhost',
8080,
0,
);
return server;
@@ -71,10 +71,21 @@ void main() {
final rawDriver = await createDriver(
spec: browser.isChromium ? WebDriverSpec.JsonWire : WebDriverSpec.W3c,
uri: browser.driverUri,
desired: {
'goog:chromeOptions': {
'args': [
'--headless=new',
'--disable-search-engine-choice-screen',
],
},
'moz:firefoxOptions': {
'args': ['-headless']
},
},
);
driver = DriftWebDriver(server, rawDriver);
await driver.driver.get('http://localhost:8080/');
await driver.driver.get('http://localhost:${server.server.port}/');
});
tearDown(() => driver.driver.quit());
@@ -260,7 +271,8 @@ void main() {
expect(await driver.amountOfRows, 1);
await Future.delayed(const Duration(seconds: 2));
await driver.driver.get('http://localhost:8080/no-coep');
await driver.driver
.get('http://localhost:${server.server.port}/no-coep');
await driver.openDatabase();
expect(await driver.amountOfRows, isZero);
});