Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/internal/engine.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0928c1af2f45361a9473565d7946978dbc42493e
05ab04dbe8cf8ad0e27821abb785ee2655d9af0b
12 changes: 12 additions & 0 deletions dev/bots/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ Future<void> main(List<String> args) async {
print('═' * 80);
await selectShard(const <String, ShardRunner>{
'add_to_app_tests': _runAddToAppTests,
'add_to_app_life_cycle_tests': _runAddToAppLifeCycleTests,
'build_tests': _runBuildTests,
'framework_coverage': _runFrameworkCoverage,
'framework_tests': _runFrameworkTests,
Expand Down Expand Up @@ -358,6 +359,17 @@ Future<void> _runAddToAppTests() async {
}
}

Future<void> _runAddToAppLifeCycleTests() async {
if (Platform.isMacOS) {
print('${green}Running add-to-app life cycle iOS integration tests$reset...');
final String addToAppDir = path.join(flutterRoot, 'dev', 'integration_tests', 'ios_add2app_life_cycle');
await runCommand('./build_and_test.sh',
<String>[],
workingDirectory: addToAppDir,
);
}
}

Future<void> _runFrameworkTests() async {
final bq.BigqueryApi bigqueryApi = await _getBigqueryApi();

Expand Down
69 changes: 69 additions & 0 deletions dev/integration_tests/ios_add2app_life_cycle/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

.DS_Store

## Build generated
build/
DerivedData/
Pods/

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/

## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint

## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/
27 changes: 27 additions & 0 deletions dev/integration_tests/ios_add2app_life_cycle/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Copyright 2014 The Chromium Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 changes: 15 additions & 0 deletions dev/integration_tests/ios_add2app_life_cycle/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
platform :ios, '12.0'

flutter_application_path = 'flutterapp/'

load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')

target 'ios_add2app' do
install_all_flutter_pods(flutter_application_path)
end

target 'ios_add2appTests' do
inherit! :search_paths
install_flutter_engine_pod
pod 'EarlGrey'
end
28 changes: 28 additions & 0 deletions dev/integration_tests/ios_add2app_life_cycle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# iOS Add2App Life Cycle Test

This application demonstrates some basic functionality for Add2App,
along with a native iOS ViewController as a baseline and to demonstrate
interaction.

The following functionality is currently implemented:

1. A regular iOS view controller (UIViewController), similar to the default
`flutter create` template (NativeViewController.m).
1. A FlutterViewController subclass that takes over full screen. Demos showing
this both from a cold/fresh engine state and a warm engine state
(FullScreenViewController.m).
1. A demo of pushing a FlutterViewController on as a child view.
1. A demo of showing both the native and the Flutter views using a platform
channel to to interact with each other (HybridViewController.m).
1. A demo of showing two FlutterViewControllers simultaneously
(DualViewController.m).

A few key things are tested here (IntegrationTests.m):

1. The ability to pre-warm the engine and attach/detatch a ViewController from
it.
1. The ability to use platform channels to communicate between views.
1. The ability to simultaneously run two instances of the engine.
1. That a FlutterViewController can be freed when no longer in use (also tested
from FlutterViewControllerTests.m).
1. That a FlutterEngine can be freed when no longer in use.
24 changes: 24 additions & 0 deletions dev/integration_tests/ios_add2app_life_cycle/build_and_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

set -e

cd "$(dirname "$0")"

pushd flutterapp
../../../../bin/flutter build ios --debug --simulator --no-codesign
popd

pod install
os_version=$(xcrun --show-sdk-version --sdk iphonesimulator)

PRETTY="cat"
if which xcpretty; then
PRETTY="xcpretty"
fi

set -o pipefail && xcodebuild \
-workspace ios_add2app.xcworkspace \
-scheme ios_add2app \
-sdk "iphonesimulator$os_version" \
-destination "OS=$os_version,name=iPhone X" test | $PRETTY

41 changes: 41 additions & 0 deletions dev/integration_tests/ios_add2app_life_cycle/flutterapp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.DS_Store
.dart_tool/

.packages
.pub/

.idea/
.vagrant/
.sconsign.dblite
.svn/

*.swp
profile

DerivedData/

.generated/

*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3

!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3

xcuserdata

*.moved-aside

*.pyc
*sync/
Icon?
.tags*

build/
.android/
.ios/
.flutter-plugins
10 changes: 10 additions & 0 deletions dev/integration_tests/ios_add2app_life_cycle/flutterapp/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: 06179457d553b96b4d7421a08ac90535ca2c9632
channel: unknown

project_type: module
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# ios_add2app_life_cycle_flutter

A new flutter module project.

## Getting Started

For help getting started with Flutter, view our online
[documentation](https://flutter.dev/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/foundation.dart';
import 'package:collection/collection.dart';

VoidCallback originalSemanticsListener;

void main() {
WidgetsFlutterBinding.ensureInitialized();
// Disconnects semantics listener for testing purposes.
originalSemanticsListener = ui.window.onSemanticsEnabledChanged;
ui.window.onSemanticsEnabledChanged = null;
RendererBinding.instance.setSemanticsEnabled(false);
// 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 {
const LifeCycleSpy();

@override
_LifeCycleSpyState createState() => _LifeCycleSpyState();
}

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

@override
void initState(){
super.initState();
WidgetsBinding.instance.addObserver(this);
_actualLifeCycleSequence = <AppLifecycleState>[
SchedulerBinding.instance.lifecycleState
];
}

@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_actualLifeCycleSequence = List<AppLifecycleState>.from(_actualLifeCycleSequence);
_actualLifeCycleSequence.add(state);
});
}

@override
Widget build(BuildContext context) {
if (const ListEquality<AppLifecycleState>().equals(_actualLifeCycleSequence, _expectedLifeCycleSequence)) {
// Rewires the semantics harness if test passes.
RendererBinding.instance.setSemanticsEnabled(true);
ui.window.onSemanticsEnabledChanged = originalSemanticsListener;
}
return const MaterialApp(
title: 'Flutter View',
home: Text('test'),
);
}
}
Loading