Skip to content

Commit

Permalink
flutter: Add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
iamsergio committed Dec 7, 2024
1 parent ab7d86a commit b7df963
Show file tree
Hide file tree
Showing 57 changed files with 3,232 additions and 14 deletions.
13 changes: 12 additions & 1 deletion .github/workflows/flutter-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ jobs:
- name: Run tests
run: |
ls build-dev-flutter/lib
cd src/flutter/dart
flutter pub get
xvfb-run flutter test
flutter test
env:
KDDW_BINDINGS_LIB: ${{ github.workspace }}/build-dev-flutter/lib/libkddockwidgets.so

- name: Run integration tests
run: |
cd tests/flutter/
flutter pub get
xvfb-run flutter test -d linux integration_test/ui_test.dart
env:
KDDW_BINDINGS_LIB: ${{ github.workspace }}/build-dev-flutter/lib/libkddockwidgets.so
18 changes: 9 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,15 @@ kddockwidgets_example.iml
/src/core/layouting/build/

# Flutter auto generated files
/examples/flutter/linux/flutter/generated_plugin_registrant.cc
/examples/flutter/linux/flutter/generated_plugin_registrant.h
/examples/flutter/linux/flutter/generated_plugins.cmake
/examples/flutter/windows/flutter/generated_plugin_registrant.cc
/examples/flutter/windows/flutter/generated_plugin_registrant.h
/examples/flutter/windows/flutter/generated_plugins.cmake
/tests/flutter_tests_embedder/linux/flutter/generated_plugin_registrant.cc
/tests/flutter_tests_embedder/linux/flutter/generated_plugin_registrant.h
/tests/flutter_tests_embedder/linux/flutter/generated_plugins.cmake
generated_plugin_registrant.cc
generated_plugin_registrant.h
generated_plugins.cmake
.flutter-plugins
.flutter-plugins-dependencies
.metadata
/tests/flutter/build/
/tests/flutter/macos/Podfile
/tests/flutter/macos/Podfile.lock

/docs/book/book/
/book/
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ repos:
rev: v0.6.13
hooks:
- id: cmake-lint
exclude: (.py.cmake|Doxyfile.cmake|examples/flutter/)
exclude: (.py.cmake|Doxyfile.cmake|examples/flutter/|tests/flutter/)
- id: cmake-format
exclude: (.py.cmake|Doxyfile.cmake|examples/flutter/)
exclude: (.py.cmake|Doxyfile.cmake|examples/flutter/|tests/flutter/)
- repo: https://github.com/DavidAnson/markdownlint-cli2
rev: v0.15.0
hooks:
Expand Down
16 changes: 15 additions & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ SPDX-License-Identifier = "MIT"
# Flutter
[[annotations]]
path = [
"tests/flutter_tests_embedder/tests_embedder.**",
"examples/flutter/assets/**",
"examples/flutter/macos/Runner/Configs/AppInfo.xcconfig",
"examples/flutter/.metadata",
Expand All @@ -136,6 +135,21 @@ path = [
"examples/flutter/macos/Runner/Release.entitlements",
"examples/flutter/windows/runner/resources/app_icon.ico",
"examples/flutter/windows/runner/runner.exe.manifest",
"tests/flutter/assets/**",
"tests/flutter/macos/Runner/Configs/AppInfo.xcconfig",
"tests/flutter/.metadata",
"tests/flutter/macos/Runner/Assets.xcassets/**",
"tests/flutter/macos/Runner.xcodeproj/**",
"tests/flutter/macos/Flutter/**",
"tests/flutter/macos/Runner.xcworkspace/**",
"tests/flutter/macos/.gitignore",
"tests/flutter/macos/Runner/Configs/**.xcconfig",
"tests/flutter/macos/Runner/Base.lproj/MainMenu.xib",
"tests/flutter/macos/Runner/DebugProfile.entitlements",
"tests/flutter/macos/Runner/Info.plist",
"tests/flutter/macos/Runner/Release.entitlements",
"tests/flutter/windows/runner/resources/app_icon.ico",
"tests/flutter/windows/runner/runner.exe.manifest",
]
precedence = "aggregate"
SPDX-FileCopyrightText = "Copyright 2013-2014 The Flutter Authors"
Expand Down
4 changes: 3 additions & 1 deletion src/flutter/dart/lib/widgets/DropAreaWidget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ class DropAreaWidgetState extends State<DropAreaWidget> {
void scheduleCheckLayoutSize() {
WidgetsBinding.instance.addPostFrameCallback((_) {
final renderBox =
dropArea.key.currentContext?.findRenderObject() as RenderBox;
dropArea.key.currentContext?.findRenderObject() as RenderBox?;

if (renderBox == null) return;

final Size size = renderBox.size;
if (size != oldSize) {
Expand Down
13 changes: 13 additions & 0 deletions tests/flutter/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
#
# SPDX-License-Identifier: BSD-3-Clause

include: package:flutter_lints/flutter.yaml

linter:
rules:
library_prefixes: false
analyzer:
errors:
unused_import: false
file_names: false
Binary file added tests/flutter/assets/KDAB_bubble_blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/flutter/assets/KDAB_bubble_fulcolor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 119 additions & 0 deletions tests/flutter/integration_test/ui_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
This file is part of KDDockWidgets.
SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
Author: Sérgio Martins <[email protected]>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
Contact KDAB at <[email protected]> for commercial licensing options.
*/

import 'dart:io';
import 'dart:ui';

import 'package:KDDockWidgets/models/DockItem.dart';
import 'package:KDDockWidgets/models/DropArea.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:KDDockWidgets/widgets/DropAreaWidget.dart';
import 'package:flutter_test/flutter_test.dart';

Future<Finder?> waitForWidget(WidgetTester tester, Key key,
{int maxTries = 10}) async {
for (int i = 0; i < maxTries; ++i) {
final finder = find.byKey(key);
if (finder.evaluate().isNotEmpty) return finder;
await tester.pump(Duration(seconds: 1));
}

return null;
}

// Returns true when the widget can't be seen anymore
Future<bool> waitForWidgetToHide(WidgetTester tester, Key key,
{int maxTries = 10}) async {
for (int i = 0; i < maxTries; ++i) {
await tester.pump(Duration(seconds: 1));
final finder = find.byKey(key);
if (finder.evaluate().isEmpty) return true;
}

return false;
}

Future<void> pumps(WidgetTester tester, int numPumps) async {
for (int i = 0; i < numPumps; ++i) {
await tester.pump(Duration(seconds: 1));
}
}

class MyApp extends StatelessWidget {
final Widget child;
const MyApp({Key? key, required this.child}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
home: RepaintBoundary(
key: Key('boundary'),
child: Scaffold(
body: child,
),
));
}
}

void main() async {
testWidgets('Counter increments test', (WidgetTester tester) async {
final dock1 =
DockItem(uniqueName: "dw1", guestWidget: Container(color: Colors.cyan));
final dock2 =
DockItem(uniqueName: "dw2", guestWidget: Container(color: Colors.cyan));
final dock3 =
DockItem(uniqueName: "dw3", guestWidget: Container(color: Colors.cyan));

final dock11 = DockItem(
uniqueName: "dw11", guestWidget: Container(color: Colors.cyan));
final dock12 = DockItem(
uniqueName: "dw12", guestWidget: Container(color: Colors.cyan));
final dock13 = DockItem(
uniqueName: "dw13", guestWidget: Container(color: Colors.cyan));

final dropArea = DropArea();
dropArea.addDockItem(dock1, Location.LocationOnTop);
dropArea.addDockItem(dock2, Location.LocationOnBottom);
final group = dropArea.groups.first;
group.addDockWidget(dock3);
group.addDockWidget(dock11);
group.addDockWidget(dock12);
group.addDockWidget(dock13);

dropArea.setLayoutSize(700, 700);
final dropAreaWidget = DropAreaWidget(dropArea);

// Build the widget tree
await tester.pumpWidget(MyApp(
child: dropAreaWidget,
));

await tester.pump();

final renderObject = tester.firstRenderObject(find.byType(RepaintBoundary));
final image =
await (renderObject as RenderRepaintBoundary).toImage(pixelRatio: 2);
final pixelRatio = window.devicePixelRatio; // Use device pixel ratio

final byteDataFuture = image.toByteData(format: ImageByteFormat.png);
await tester.pumpAndSettle();

final byteData = await byteDataFuture;
final buffer = byteData!.buffer.asUint8List();

// Save the bytes to a file
final file = File('screenshot.png');
file.writeAsBytesSync(buffer);
await tester.pump();
});
}
162 changes: 162 additions & 0 deletions tests/flutter/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# This file was auto-generated by the Flutter SDK
#
# SPDX-FileCopyrightText: 2014 The Flutter Authors.
# SPDX-License-Identifier: BSD-3-Clause

# Project-level configuration.
cmake_minimum_required(VERSION 3.15)
project(runner LANGUAGES CXX)

# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "kddockwidgets_flutter_example")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "com.example.kddockwidgets_flutter_example")

# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0063 NEW)

# Load bundled libraries from the lib/ directory relative to the binary.
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")

if(DEFINED ENV{KDDW_EXAMPLE_USES_ASAN})
# For development purposes, support ASAN and UBSAN.
# gcc only, as it needs to match the ASAN used to build KDDW
set(CMAKE_CXX_COMPILER g++)
add_compile_options(-fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer)
add_link_options(-fsanitize=address -fsanitize=undefined)
endif()

# Root filesystem for cross-building.
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()

# Define build configuration options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE
"Debug"
CACHE STRING "Flutter build mode" FORCE
)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release")
endif()

# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS target)
target_compile_features(${target} PUBLIC cxx_std_14)
target_compile_options(${target} PRIVATE -Wall -Werror)
target_compile_options(${target} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${target} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()

# Flutter library and tool build rules.
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
add_subdirectory(${FLUTTER_MANAGED_DIR})

# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)

add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")

# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc")

# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})

# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)

# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)

# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run")

# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)

# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX
"${BUILD_BUNDLE_DIR}"
CACHE PATH "..." FORCE
)
endif()

# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime
)

set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")

install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime)

install(
FILES "${FLUTTER_ICU_DATA_FILE}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime
)

install(
FILES "${FLUTTER_LIBRARY}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime
)

foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(
FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime
)
endforeach(bundled_library)

# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime
)
install(
DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime
)

# Install the AOT library on non-Debug builds only.
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
install(
FILES "${AOT_LIBRARY}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime
)
endif()
Loading

0 comments on commit b7df963

Please sign in to comment.