main.dart 2.56 KB
Newer Older
1 2 3 4 5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:ui' as ui;
6 7

import 'package:collection/collection.dart';
8 9
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
10
import 'package:flutter/services.dart';
11

12
VoidCallback? originalSemanticsListener;
13 14 15 16 17 18

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // Disconnects semantics listener for testing purposes.
  originalSemanticsListener = ui.window.onSemanticsEnabledChanged;
  ui.window.onSemanticsEnabledChanged = null;
19
  RendererBinding.instance?.setSemanticsEnabled(false);
20 21 22 23 24 25 26 27 28 29 30 31
  // If the test passes, LifeCycleSpy will rewire the semantics listener back.
  runApp(const LifeCycleSpy());
}

/// A Test widget that spies on app life cycle changes.
///
/// It will collect the AppLifecycleState sequence during its lifetime, and it
/// will rewire semantics harness if the sequence it receives matches the
/// expected list.
///
/// Rewiring semantics is a signal to native IOS test that the test has passed.
class LifeCycleSpy extends StatefulWidget {
32
  const LifeCycleSpy({Key? key}) : super(key: key);
33 34

  @override
35
  State<LifeCycleSpy> createState() => _LifeCycleSpyState();
36 37 38 39 40 41 42 43
}

class _LifeCycleSpyState extends State<LifeCycleSpy> with WidgetsBindingObserver {
  final List<AppLifecycleState> _expectedLifeCycleSequence = <AppLifecycleState>[
    AppLifecycleState.detached,
    AppLifecycleState.inactive,
    AppLifecycleState.resumed,
  ];
44
  List<AppLifecycleState?>? _actualLifeCycleSequence;
45 46

  @override
47
  void initState() {
48
    super.initState();
49
    WidgetsBinding.instance?.addObserver(this);
50
    _actualLifeCycleSequence =  <AppLifecycleState?>[
51
      ServicesBinding.instance?.lifecycleState
52 53 54 55 56
    ];
  }

  @override
  void dispose() {
57
    WidgetsBinding.instance?.removeObserver(this);
58 59 60 61 62 63
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
64 65
      _actualLifeCycleSequence = List<AppLifecycleState>.from(_actualLifeCycleSequence!);
      _actualLifeCycleSequence?.add(state);
66 67 68 69 70
    });
  }

  @override
  Widget build(BuildContext context) {
71
    if (const ListEquality<AppLifecycleState?>().equals(_actualLifeCycleSequence, _expectedLifeCycleSequence)) {
72
      // Rewires the semantics harness if test passes.
73
      RendererBinding.instance?.setSemanticsEnabled(true);
74 75 76 77 78 79 80 81
      ui.window.onSemanticsEnabledChanged = originalSemanticsListener;
    }
    return const MaterialApp(
      title: 'Flutter View',
      home: Text('test'),
    );
  }
}