diff --git a/.cirrus.yml b/.cirrus.yml index 454f849b81064..d7ce4adc52af9 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -124,6 +124,27 @@ task: - name: web_tests-7_last-linux # last Web shard must end with _last << : *WEB_SHARD_TEMPLATE + - name: web_engine_integration_test_linux + compile_host_script: | + cd $ENGINE_PATH/src + ./flutter/tools/gn --unoptimized --full-dart-sdk + ninja -C out/host_debug_unopt + fetch_framework_script: | + cd $ENGINE_PATH/src/flutter/tools + ./clone_flutter.sh + cd $FRAMEWORK_PATH/flutter + bin/flutter update-packages --local-engine=host_debug_unopt + script: + - git clone https://github.com/flutter/web_installers.git + - cd web_installers/packages/web_drivers/ + - $ENGINE_PATH/src/third_party/dart/tools/sdks/dart-sdk/bin/pub get + - $ENGINE_PATH/src/third_party/dart/tools/sdks/dart-sdk/bin/dart lib/web_driver_installer.dart chromedriver --install-only + - ./chromedriver/chromedriver --port=4444 & + - cd $ENGINE_PATH/src/flutter/e2etests/web/regular_integration_tests + - $FRAMEWORK_PATH/flutter/bin/flutter config --local-engine=host_debug_unopt --no-analytics --enable-web + - $FRAMEWORK_PATH/flutter/bin/flutter pub get --local-engine=host_debug_unopt + - $FRAMEWORK_PATH/flutter/bin/flutter drive -v --target=test_driver/text_editing_e2e.dart -d web-server --release --browser-name=chrome --local-engine=host_debug_unopt + - name: build_and_test_web_linux_firefox compile_host_script: | cd $ENGINE_PATH/src diff --git a/.gitignore b/.gitignore index 70d501a1a4b38..f92944ad0c5ff 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,102 @@ xcuserdata third_party/gn/ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/ + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/Flutter-Debug.xcconfig +**/macos/Flutter/Flutter-Release.xcconfig +**/macos/Flutter/Flutter-Profile.xcconfig + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock diff --git a/ci/licenses_golden/tool_signature b/ci/licenses_golden/tool_signature index c1c11fd3bb285..732b5d9430cd7 100644 --- a/ci/licenses_golden/tool_signature +++ b/ci/licenses_golden/tool_signature @@ -1,2 +1,2 @@ -Signature: a0775818831a05f46ce1628c95d834c1 +Signature: 9ad4afaa43bd81d0e6a011688ca40377 diff --git a/e2etests/web/regular_integration_tests/README.md b/e2etests/web/regular_integration_tests/README.md new file mode 100644 index 0000000000000..7889ef4971482 --- /dev/null +++ b/e2etests/web/regular_integration_tests/README.md @@ -0,0 +1,16 @@ +``` +This directory is for Flutter Web engine integration tests that does not +need a specific configuration. If an e2e test needs specialized app +configuration (e.g. PWA vs non-PWA packaging), please create another +directory under e2etests/web. Otherwise tests such as text_editing, history, +scrolling, pointer events... should all go under this package. + +# To run the application under test for traouble shooting purposes. +flutter run -d web-server lib/text_editing_main.dart --local-engine=host_debug_unopt + +# To run the Text Editing test and use the developer tools in the browser. +flutter run --target=test_driver/text_editing_e2e.dart -d web-server --web-port=8080 --release --local-engine=host_debug_unopt + +# To test the Text Editing test with driver: +flutter drive -v --target=test_driver/text_editing_e2e.dart -d web-server --release --browser-name=chrome --local-engine=host_debug_unopt +``` diff --git a/e2etests/web/regular_integration_tests/lib/text_editing_main.dart b/e2etests/web/regular_integration_tests/lib/text_editing_main.dart new file mode 100644 index 0000000000000..1962900718551 --- /dev/null +++ b/e2etests/web/regular_integration_tests/lib/text_editing_main.dart @@ -0,0 +1,60 @@ +// Copyright 2013 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 'package:flutter/material.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + key: const Key('mainapp'), + title: 'Integration Test App', + home: MyHomePage(title: 'Integration Test App'), + ); + } +} + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, this.title}) : super(key: key); + + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + final TextEditingController _controller = + TextEditingController(text: 'Text1'); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'Text Editing Test', + ), + TextFormField( + key: const Key('input'), + enabled: true, + controller: _controller, + //initialValue: 'Text1', + decoration: const InputDecoration( + labelText: 'Text Input Field:', + ), + ), + ], + ), + ), + ); + } +} diff --git a/e2etests/web/regular_integration_tests/pubspec.yaml b/e2etests/web/regular_integration_tests/pubspec.yaml new file mode 100644 index 0000000000000..98fa40773834e --- /dev/null +++ b/e2etests/web/regular_integration_tests/pubspec.yaml @@ -0,0 +1,18 @@ +name: regular_integration_tests +publish_to: none + +environment: + sdk: ">=2.2.2 <3.0.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + e2e: 0.2.4+4 + http: 0.12.0+2 + test: any diff --git a/e2etests/web/regular_integration_tests/test_driver/text_editing_e2e.dart b/e2etests/web/regular_integration_tests/test_driver/text_editing_e2e.dart new file mode 100644 index 0000000000000..4719766e3e6c4 --- /dev/null +++ b/e2etests/web/regular_integration_tests/test_driver/text_editing_e2e.dart @@ -0,0 +1,43 @@ +// Copyright 2013 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:html'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:regular_integration_tests/text_editing_main.dart' as app; +import 'package:flutter/material.dart'; + +import 'package:e2e/e2e.dart'; + +void main() { + E2EWidgetsFlutterBinding.ensureInitialized() as E2EWidgetsFlutterBinding; + + testWidgets('Focused text field creates a native input element', + (WidgetTester tester) async { + app.main(); + await tester.pumpAndSettle(); + + // TODO(nurhan): https://github.com/flutter/flutter/issues/51885 + SystemChannels.textInput.setMockMethodCallHandler(null); + + // Focus on a TextFormField. + final Finder finder = find.byKey(const Key('input')); + expect(finder, findsOneWidget); + await tester.tap(find.byKey(const Key('input'))); + + // A native input element will be appended to the DOM. + final List nodeList = document.getElementsByTagName('input'); + expect(nodeList.length, equals(1)); + final InputElement input = + document.getElementsByTagName('input')[0] as InputElement; + // The element's value will be the same as the textFormField's value. + expect(input.value, 'Text1'); + + // Change the value of the TextFormField. + final TextFormField textFormField = tester.widget(finder); + textFormField.controller.text = 'New Value'; + // DOM element's value also changes. + expect(input.value, 'New Value'); + }); +} diff --git a/e2etests/web/regular_integration_tests/test_driver/text_editing_e2e_test.dart b/e2etests/web/regular_integration_tests/test_driver/text_editing_e2e_test.dart new file mode 100644 index 0000000000000..26f4278d6505f --- /dev/null +++ b/e2etests/web/regular_integration_tests/test_driver/text_editing_e2e_test.dart @@ -0,0 +1,19 @@ +// Copyright 2013 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:io'; + +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final FlutterDriver driver = await FlutterDriver.connect(); + + // TODO(nurhan): https://github.com/flutter/flutter/issues/51940 + final String dataRequest = + await driver.requestData(null, timeout: const Duration(seconds: 1)); + print('result $dataRequest'); + await driver.close(); + + exit(dataRequest == 'pass' ? 0 : 1); +} diff --git a/e2etests/web/regular_integration_tests/web/index.html b/e2etests/web/regular_integration_tests/web/index.html new file mode 100644 index 0000000000000..4134d6bc48c1f --- /dev/null +++ b/e2etests/web/regular_integration_tests/web/index.html @@ -0,0 +1,12 @@ + + + + + Web Integration Tests + + + + + diff --git a/tools/licenses/lib/main.dart b/tools/licenses/lib/main.dart index 927863f82aa8a..fc948e23134b8 100644 --- a/tools/licenses/lib/main.dart +++ b/tools/licenses/lib/main.dart @@ -930,6 +930,9 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { entry.name != 'tests' && entry.name != 'javatests' && entry.name != 'testing' && + // The directory that containts end to end tests. + // Shoul be excluded from the licence checks. + entry.name != 'e2etests' && entry.name != '.dart_tool'; // Generated by various Dart tools, such as pub and // build_runner. Skip it because it does not contain // source code.