// End-to-end integration test for the Studio-plugin theme // hook: spins a real `fai serve`, installs the in-tree // `studio-theme-solarized` plugin via direct module-dir // staging (mirror-install would also work but takes longer // and pulls a network egress), then calls `invokePluginTheme` // and asserts the round-trip. // // Run manually with: // // flutter test test/integration/plugin_theme_test.dart // // Pre-reqs (handled by HubFixture's skip-when-missing path): // - fai binary on PATH or at ../chain_platform/target/release/fai // - studio-theme-solarized plugin built to module.wasm in its // chain_plugins dir. import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'hub_fixture.dart'; void main() { test( 'invokePluginTheme returns Solarized Light + Dark schemes', () async { final fixture = await HubFixture.start(); if (fixture == null) return; try { // Stage the plugin into the fixture's modules dir // ourselves. Going through `installModule` would // require the plugin to be on the mirror, which would // add network + bundle-fetch latency that doesn't // belong in an in-process round-trip test. final pluginSrc = Directory( '../chain_plugins/studio-theme-solarized', ); if (!await pluginSrc.exists()) { markTestSkipped('studio-theme-solarized source not available'); return; } final wasm = File('${pluginSrc.path}/module.wasm'); if (!await wasm.exists()) { markTestSkipped( 'studio-theme-solarized has no built module.wasm — ' 'run `cargo build --release --target wasm32-wasip2` first', ); return; } final dest = Directory( '${fixture.tempDir.path}/modules/studio-theme-solarized', ); await dest.create(recursive: true); await File('${pluginSrc.path}/module.yaml') .copy('${dest.path}/module.yaml'); await wasm.copy('${dest.path}/module.wasm'); // Call the hook for both brightnesses. final light = await fixture.client.invokePluginTheme( capability: 'studio.theme.solarized', brightness: 'light', ); expect(light.brightness, 'light'); expect(light.tokens.length, 14); // Solarized blue is the pinned primary in both schemes. expect(light.tokens[0], 0xFF268BD2); final dark = await fixture.client.invokePluginTheme( capability: 'studio.theme.solarized', brightness: 'dark', ); expect(dark.brightness, 'dark'); expect(dark.tokens.length, 14); expect(dark.tokens[0], 0xFF268BD2); // Different surface tokens between Light and Dark — // regression guard against a plugin that returns the // same scheme for both. expect(light.tokens[8], isNot(equals(dark.tokens[8]))); } finally { await fixture.dispose(); } }, // Component-Model instantiation can take a few seconds on // first run as wasmtime caches the compiled artefact. timeout: const Timeout(Duration(minutes: 1)), ); }