Skip to content

[integration_test] allow custom binding initialization when running integration_test tests #92254

@Norbert515

Description

@Norbert515

Use case

I'd like to be in control of the test binding I choose for integration tests. In my case, I'd like to inject a widget at the very root of the widget tree when running integration_tests.

The cookbook contains documentation about adding the ensureInitialized call, but (at least on the latest beta version) flutter run and flutter test generate an intermediate file that calls:

  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

Proposal

Remove ensureInitialized from the generated file so users can choose what binding (and what configuration) they want to run the test in.

/// Returns a serialized test suite.
StreamChannel<dynamic> serializeSuite(Function getMain()) {
  return RemoteListener.start(getMain);
}

Future<void> _testMain() async {
  // --------------------> remove this 
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
  await Future(test.main);
}

/// Capture any top-level errors (mostly lazy syntax errors, since other are
/// caught below) and report them to the parent isolate.
void catchIsolateErrors() {
  final ReceivePort errorPort = ReceivePort();
  // Treat errors non-fatal because otherwise they'll be double-printed.
  Isolate.current.setErrorsFatal(false);
  Isolate.current.addErrorListener(errorPort.sendPort);
  errorPort.listen((dynamic message) {
    // Masquerade as an IsolateSpawnException because that's what this would
    // be if the error had been detected statically.
    final IsolateSpawnException error = IsolateSpawnException(
        message[0] as String);
    final Trace stackTrace = message[1] == null ?
        Trace(const <Frame>[]) : Trace.parse(message[1] as String);
    Zone.current.handleUncaughtError(error, stackTrace);
  });
}

void main() {
  String serverPort = Platform.environment['SERVER_PORT'] ?? '';
  String server = Uri.decodeComponent('ws%3A%2F%2F127.0.0.1:$serverPort');
  StreamChannel<dynamic> testChannel = serializeSuite(() {
    catchIsolateErrors();
    goldenFileComparator = LocalFileComparator(Uri.parse('file:///C:/Users/norbe/IdeaProjects/flypress/packages/flypress/example/integration_test/app_test.dart'));
    autoUpdateGoldenFiles = false;
    return _testMain;
  });
  final callback = (method, params) async {
    testChannel.sink.add(json.decode(params['data'] as String));

    // Result is ignored but null is not accepted here.
    return developer.ServiceExtensionResponse.result('{}');
  };

  developer.registerExtension('ext.flutter.integrationTest', callback);

  testChannel.stream.listen((x) {
    developer.postEvent(
      'Flutter.IntegrationTest',
      {'data': json.encode(x)},
    );
  });
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterf: integration_testThe flutter/packages/integration_test plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions