From 135cea367a9ca9d80d66ac8835d06fc432678bb5 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 17:13:38 -0400 Subject: [PATCH 01/33] Upgraded pigeons to latest v26 version. Flutter minimum supported version is now 3.38. --- wakelock_plus/analysis_options.yaml | 1 + wakelock_plus/android/build.gradle | 2 +- .../plus/wakelock/WakelockPlusMessages.g.kt | 4 +- wakelock_plus/example/pubspec.yaml | 8 +- .../include/wakelock_plus/messages.g.h | 4 +- .../Sources/wakelock_plus/messages.g.m | 10 +- wakelock_plus/pubspec.yaml | 10 +- .../lib/messages.g.dart | 100 ++++++++++-------- wakelock_plus_platform_interface/pubspec.yaml | 6 +- .../test/messages.g.dart | 22 ++-- 10 files changed, 83 insertions(+), 84 deletions(-) diff --git a/wakelock_plus/analysis_options.yaml b/wakelock_plus/analysis_options.yaml index 031ffd7..bf6c98c 100644 --- a/wakelock_plus/analysis_options.yaml +++ b/wakelock_plus/analysis_options.yaml @@ -7,6 +7,7 @@ analyzer: - ".git/**" # Exclude private git directory - "build/**" # Exclude generated files in the build directory - ".dart_tool/**" # Exclude Dart tool-generated files + - "pigeons/**" # Exclude pigeons linter: rules: diff --git a/wakelock_plus/android/build.gradle b/wakelock_plus/android/build.gradle index 422cc26..d2a1ffe 100644 --- a/wakelock_plus/android/build.gradle +++ b/wakelock_plus/android/build.gradle @@ -46,7 +46,7 @@ android { defaultConfig { // Use flutter.minSdkVersion once the minimum supported Flutter version is 3.35 or higher. - minSdkVersion 21 + minSdkVersion flutter.minSdkVersion testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } diff --git a/wakelock_plus/android/src/main/kotlin/dev/fluttercommunity/plus/wakelock/WakelockPlusMessages.g.kt b/wakelock_plus/android/src/main/kotlin/dev/fluttercommunity/plus/wakelock/WakelockPlusMessages.g.kt index 8c7aa32..2d4b1d0 100644 --- a/wakelock_plus/android/src/main/kotlin/dev/fluttercommunity/plus/wakelock/WakelockPlusMessages.g.kt +++ b/wakelock_plus/android/src/main/kotlin/dev/fluttercommunity/plus/wakelock/WakelockPlusMessages.g.kt @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v26.0.1), do not edit directly. +// Autogenerated from Pigeon (v26.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") @@ -56,7 +56,7 @@ private object WakelockPlusMessagesPigeonUtils { } if (a is Map<*, *> && b is Map<*, *>) { return a.size == b.size && a.all { - (b as Map).containsKey(it.key) && + (b as Map).contains(it.key) && deepEquals(it.value, b[it.key]) } } diff --git a/wakelock_plus/example/pubspec.yaml b/wakelock_plus/example/pubspec.yaml index a08ffa4..e1db1da 100644 --- a/wakelock_plus/example/pubspec.yaml +++ b/wakelock_plus/example/pubspec.yaml @@ -5,8 +5,8 @@ description: Demonstrates how to use the wakelock_plus plugin. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: '>=3.3.0 <4.0.0' - flutter: ">=3.19.0" + sdk: '>=3.11.0 <4.0.0' + flutter: ">=3.41.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -28,7 +28,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.5 + cupertino_icons: ^1.0.8 dev_dependencies: flutter_test: @@ -43,7 +43,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^2.0.1 + flutter_lints: ^6.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/include/wakelock_plus/messages.g.h b/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/include/wakelock_plus/messages.g.h index e9ccc22..eea50a3 100644 --- a/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/include/wakelock_plus/messages.g.h +++ b/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/include/wakelock_plus/messages.g.h @@ -1,7 +1,7 @@ -// Autogenerated from Pigeon (v26.0.1), do not edit directly. +// Autogenerated from Pigeon (v26.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon -#import +@import Foundation; @protocol FlutterBinaryMessenger; @protocol FlutterMessageCodec; diff --git a/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/messages.g.m b/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/messages.g.m index 1a2154c..911784b 100644 --- a/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/messages.g.m +++ b/wakelock_plus/ios/wakelock_plus/Sources/wakelock_plus/messages.g.m @@ -1,16 +1,12 @@ -// Autogenerated from Pigeon (v26.0.1), do not edit directly. +// Autogenerated from Pigeon (v26.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "./include/wakelock_plus/messages.g.h" #if TARGET_OS_OSX -#import +@import FlutterMacOS; #else -#import -#endif - -#if !__has_feature(objc_arc) -#error File requires ARC to be enabled. +@import Flutter; #endif static NSArray *wrapResult(id result, FlutterError *error) { diff --git a/wakelock_plus/pubspec.yaml b/wakelock_plus/pubspec.yaml index 2ba3b7e..6c8ce26 100644 --- a/wakelock_plus/pubspec.yaml +++ b/wakelock_plus/pubspec.yaml @@ -6,15 +6,15 @@ version: 1.4.0 repository: https://github.com/fluttercommunity/wakelock_plus/tree/main/wakelock_plus environment: - sdk: '>=3.4.0 <4.0.0' - flutter: ">=3.22.0" + sdk: '>=3.10.0 <4.0.0' + flutter: ">=3.38.0" dependencies: flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.11.0 + meta: ^1.17.0 wakelock_plus_platform_interface: ^1.3.0 # Windows dependencies @@ -22,7 +22,7 @@ dependencies: win32: ">=5.6.1 <6.0.0" # Linux dependencies - dbus: ^0.7.11 + dbus: ^0.7.12 package_info_plus: ^9.0.0 # Web dependencies @@ -32,7 +32,7 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^6.0.0 - pigeon: ^26.0.1 # dart run pigeon --input "pigeons/messages.dart" + pigeon: ^26.2.3 # dart run pigeon --input "pigeons/messages.dart" # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/wakelock_plus_platform_interface/lib/messages.g.dart b/wakelock_plus_platform_interface/lib/messages.g.dart index 0546d2e..4a4ce96 100644 --- a/wakelock_plus_platform_interface/lib/messages.g.dart +++ b/wakelock_plus_platform_interface/lib/messages.g.dart @@ -1,20 +1,40 @@ -// Autogenerated from Pigeon (v26.0.1), do not edit directly. +// Autogenerated from Pigeon (v26.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: unused_import, unused_shown_name +// ignore_for_file: type=lint import 'dart:async'; -import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; +import 'dart:typed_data' show Float64List, Int32List, Int64List; -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; - -PlatformException _createConnectionError(String channelName) { - return PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel: "$channelName".', - ); +import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; + +Object? _extractReplyValueOrThrow( + List? replyList, + String channelName, { + required bool isNullValid, +}) { + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } + return replyList.firstOrNull; } + List wrapResponse({Object? result, PlatformException? error, bool empty = false}) { if (empty) { return []; @@ -145,9 +165,9 @@ class _PigeonCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 129: + case 129: return ToggleMessage.decode(readValue(buffer)!); - case 130: + case 130: return IsEnabledMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -169,53 +189,39 @@ class WakelockPlusApi { final String pigeonVar_messageChannelSuffix; Future toggle(ToggleMessage msg) async { - final String pigeonVar_channelName = 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + final pigeonVar_channelName = 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([msg]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ) + ; } Future isEnabled() async { - final String pigeonVar_channelName = 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + final pigeonVar_channelName = 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else if (pigeonVar_replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (pigeonVar_replyList[0] as IsEnabledMessage?)!; - } + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ) + ; + return pigeonVar_replyValue! as IsEnabledMessage; } } diff --git a/wakelock_plus_platform_interface/pubspec.yaml b/wakelock_plus_platform_interface/pubspec.yaml index 61355df..99f5fb0 100644 --- a/wakelock_plus_platform_interface/pubspec.yaml +++ b/wakelock_plus_platform_interface/pubspec.yaml @@ -7,14 +7,14 @@ repository: >-2 https://github.com/fluttercommunity/wakelock_plus/tree/main/wakelock_plus_platform_interface environment: - sdk: '>=3.4.0 <4.0.0' - flutter: ">=3.22.0" + sdk: '>=3.10.0 <4.0.0' + flutter: ">=3.38.0" dependencies: flutter: sdk: flutter plugin_platform_interface: ^2.1.8 - meta: ^1.11.0 + meta: ^1.17.0 dev_dependencies: flutter_test: diff --git a/wakelock_plus_platform_interface/test/messages.g.dart b/wakelock_plus_platform_interface/test/messages.g.dart index 53a05ae..945b212 100644 --- a/wakelock_plus_platform_interface/test/messages.g.dart +++ b/wakelock_plus_platform_interface/test/messages.g.dart @@ -1,6 +1,6 @@ -// Autogenerated from Pigeon (v26.0.1), do not edit directly. +// Autogenerated from Pigeon (v26.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers, omit_obvious_local_variable_types // ignore_for_file: avoid_relative_lib_imports import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -32,9 +32,9 @@ class _PigeonCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 129: + case 129: return ToggleMessage.decode(readValue(buffer)!); - case 130: + case 130: return IsEnabledMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -53,21 +53,17 @@ abstract class TestWakelockPlusApi { static void setUp(TestWakelockPlusApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle was null.'); - final List args = (message as List?)!; - final ToggleMessage? arg_msg = (args[0] as ToggleMessage?); - assert(arg_msg != null, - 'Argument for dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle was null, expected non-null ToggleMessage.'); + final List args = message! as List; + final ToggleMessage arg_msg = args[0]! as ToggleMessage; try { - api.toggle(arg_msg!); + api.toggle(arg_msg); return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -78,7 +74,7 @@ abstract class TestWakelockPlusApi { } } { - final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { From 018f5d956a69cb612fd24bed15b4cc2d8b4269fc Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 18:37:34 -0400 Subject: [PATCH 02/33] Updated Github Action workflows to better test this library under multiple platforms. --- .github/workflows/checks.yml | 347 ++++++++++++++++++++++++++++------- .github/workflows/pana.yml | 2 +- 2 files changed, 281 insertions(+), 68 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index c749c04..ebdd6e4 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -18,97 +18,310 @@ on: jobs: analyze: - timeout-minutes: 11 + timeout-minutes: 15 runs-on: ubuntu-latest name: ${{ matrix.package }} analysis on ${{ matrix.channel }} strategy: matrix: - channel: - - 'stable' - - 'beta' - package: - - 'wakelock_plus' - - 'wakelock_plus_platform_interface' + channel: [stable, beta] + package: [wakelock_plus, wakelock_plus_platform_interface] fail-fast: false - steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: channel: ${{ matrix.channel }} - - run: flutter pub get + + - name: Install dependencies + run: flutter pub get working-directory: ${{ matrix.package }} + - name: Check format - working-directory: ${{ matrix.package }} + # We use --set-exit-if-changed to ensure CI fails if code isn't formatted + # according to dart style run: dart format . --set-exit-if-changed - # Ignoring formatting issues for now, as we're still supporting versions of Flutter below - # 3.29. - # Once the minimum supported version is 3.29 or later, we can enforce this on more recent - # versions. + working-directory: ${{ matrix.package }} continue-on-error: true - - run: flutter analyze + + - name: Analyze + run: flutter analyze working-directory: ${{ matrix.package }} - test: - timeout-minutes: 30 - # Using macOS 13 Ventura due to https://github.com/flutter/flutter/issues/118469 - runs-on: macos-13 - name: ${{ matrix.package }} testing on ${{ matrix.channel }} with ${{ matrix.device }} + test_unit_interface: + runs-on: ubuntu-latest + name: Platform Interface Unit Tests + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + + # Unit tests for the interface are separated to run on fast, cheap Linux runners + # as they do not require a physical device or simulator. + - name: Run unit tests + run: | + flutter pub get + flutter test + working-directory: wakelock_plus_platform_interface + + # --- ANDROID JOBS --- + + android_example_build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Build Android APK + run: | + cd wakelock_plus/example + flutter pub get + flutter build apk --debug --target=./lib/main.dart + + android_integration_test: + runs-on: ubuntu-latest + timeout-minutes: 45 strategy: matrix: - device: - - 'iPhone 14 Pro Simulator (17.2)' - - 'iPhone 14 Pro Max Simulator (17.2)' - channel: - - 'stable' - - 'beta' - package: - - 'wakelock_plus' - - 'wakelock_plus_platform_interface' + # Matrix covers Min SDK (24), common mid-range versions, and latest (35) + # to ensure broad compatibility across the Android ecosystem. + api-level: [24, 28, 31, 33, 35] fail-fast: false + name: Android Integration (API ${{ matrix.api-level }}) + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Enable KVM + # Linux runners require KVM (Kernel-based Virtual Machine) to be enabled + # to run Android emulators with hardware acceleration for acceptable CI performance. + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Run Integration Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: google_apis + arch: x86_64 + force-avd-creation: false + # Swiftshader is used for software-based GPU acceleration in headless environments + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + working-directory: wakelock_plus/example + script: | + flutter drive \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart + + # --- IOS JOBS --- + + ios_example_build: + runs-on: macos-latest steps: - - name: Start iOS simulator - if: matrix.package == 'wakelock_plus' - # Using gawk to be able to use my regex to separate the IDs from the device names - # (because my awk skills suck) to then pipe that to awk to find the right device. - run: | - # Work around an upstream issue with the runner image: - # https://github.com/actions/runner-images/issues/8500 - brew upgrade || brew link --overwrite python@3.12 - brew install gawk - xcrun xctrace list devices - UDID=$( - xcrun xctrace list devices | - gawk 'match($0, /(.+) \(([^.]*)\)/, a) { printf "%s,%s\n", a[1], a[2] }' | - awk -F ',' -v 'device=${{ matrix.device }}' '$1 == device { print $2 }' - ) - xcrun simctl boot "${UDID:?simulator not found}" - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: ${{ matrix.channel }} - - run: flutter pub get - working-directory: ${{ matrix.package }} - - name: Run unit tests (tester) - if: matrix.package == 'wakelock_plus' - run: flutter test - working-directory: ${{ matrix.package }} - # For some reason, Web tests are currently not working. - # - name: Run unit tests (chrome) - # if: matrix.package == 'wakelock_plus' - # run: | - # flutter config --enable-web - # flutter test --platform chrome - # working-directory: ${{ matrix.package }} - - name: Integration tests on iOS - if: matrix.package == 'wakelock_plus' + channel: stable + - name: Build iOS run: | cd wakelock_plus/example - flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart - - name: Integration tests on macOS - if: matrix.package == 'wakelock_plus' + flutter pub get + flutter build ios --no-codesign --debug --target=./lib/main.dart + + ios_integration_test: + # Per requirements: macOS-26 runner is required to access the iPhone 17 simulator environment + runs-on: macos-26 + timeout-minutes: 45 + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + + - name: Start iOS simulator + # Using the standard plus_plugins action to handle the simulator lifecycle + uses: futureware-tech/simulator-action@v5 + with: + model: 'iPhone 17' + + - name: Run Integration Tests run: | cd wakelock_plus/example + flutter pub get + flutter drive \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart + + # --- MACOS JOBS --- + + macos_example_build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Build macOS + run: | + flutter config --enable-macos-desktop + cd wakelock_plus/example + flutter pub get + flutter build macos --debug --target=./lib/main.dart + + macos_integration_test: + runs-on: macos-15 + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + + - name: Run Integration Tests + run: | flutter config --enable-macos-desktop - flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart -d macos + cd wakelock_plus/example + flutter pub get + flutter drive \ + -d macos \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart + + # --- LINUX JOBS --- + + linux_example_build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev + - name: Build Linux + run: | + flutter config --enable-linux-desktop + cd wakelock_plus/example + flutter pub get + flutter build linux --debug --target=./lib/main.dart + + linux_integration_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + + - name: Install dependencies + # Flutter Linux desktop requires specific C++ and GTK development headers to compile. + # xvfb provides a virtual display for headless environments. + run: | + sudo apt-get update + sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb + + - name: Run Integration Tests + # xvfb-run (X Virtual Frame Buffer) is critical for Linux CI. + # It creates a virtual display in memory so that the Flutter application can + # initialize its UI/GPU context in a headless environment without a monitor. + run: | + flutter config --enable-linux-desktop + cd wakelock_plus/example + flutter pub get + xvfb-run flutter drive \ + -d linux \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart + + # --- WINDOWS JOBS --- + + windows_example_build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Build Windows + run: | + flutter config --enable-windows-desktop + cd wakelock_plus/example + flutter pub get + flutter build windows --debug --target=./lib/main.dart + + windows_integration_test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + + - name: Run Integration Tests + run: | + flutter config --enable-windows-desktop + cd wakelock_plus/example + flutter pub get + flutter drive \ + -d windows \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart + + # --- WEB JOBS --- + + web_example_build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + - name: Build Web + run: | + cd wakelock_plus/example + flutter pub get + flutter build web --debug --target=./lib/main.dart + + web_integration_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + channel: stable + + - name: Install Web Dependencies + # xvfb is required for a virtual display context, and chromium-chromedriver + # is the bridge between the test driver and the browser. + run: | + sudo apt-get update + sudo apt-get install -y xvfb chromium-chromedriver + + - name: Run Integration Tests + # Following plus_plugins standard: + # 1. Start virtual framebuffer (Xvfb) for Chrome to run in. + # 2. Start chromedriver on port 4444. + # 3. Use -d chrome to allow driver to control the browser instance. + run: | + export DISPLAY=:99 + Xvfb $DISPLAY -screen 0 1024x768x16 & + sleep 5 # Give xvfb some time to start. + + chromedriver --port=4444 & + sleep 2 # Give chromedriver time to start. + + flutter config --enable-web + cd wakelock_plus/example + flutter pub get + flutter drive \ + -d chrome \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart \ + --dart-define=CI=true \ No newline at end of file diff --git a/.github/workflows/pana.yml b/.github/workflows/pana.yml index f9c59aa..f571926 100644 --- a/.github/workflows/pana.yml +++ b/.github/workflows/pana.yml @@ -27,7 +27,7 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: axel-op/dart-package-analyzer@v3 with: relativePath: ${{ matrix.package }} From ddbb963abfcbebe03dbbcfba853588caf46f6b05 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:05:45 -0400 Subject: [PATCH 03/33] Fixed broken tests. --- ...wakelock_plus_platform_interface_test.dart | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/wakelock_plus_platform_interface/test/wakelock_plus_platform_interface_test.dart b/wakelock_plus_platform_interface/test/wakelock_plus_platform_interface_test.dart index 5ac85b3..5713022 100644 --- a/wakelock_plus_platform_interface/test/wakelock_plus_platform_interface_test.dart +++ b/wakelock_plus_platform_interface/test/wakelock_plus_platform_interface_test.dart @@ -1,4 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:wakelock_plus_platform_interface/messages.g.dart'; import 'package:wakelock_plus_platform_interface/src/method_channel_wakelock_plus.dart'; import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interface.dart'; @@ -27,24 +28,26 @@ void main() { group('$WakelockPlusPlatformInterface', () { test('$MethodChannelWakelockPlus() is the default instance', () { - expect(WakelockPlusPlatformInterface.instance, - isInstanceOf()); + expect( + WakelockPlusPlatformInterface.instance, + isInstanceOf(), + ); }); test('Cannot be implemented with `implements`', () { expect(() { WakelockPlusPlatformInterface.instance = - const ImplementsWakelockPlusPlatformInterface(false); - }, throwsA(isInstanceOf())); + ImplementsWakelockPlusPlatformInterface(); + }, throwsA(isA())); }); test('Can be mocked with `implements`', () { WakelockPlusPlatformInterface.instance = - const ImplementsWakelockPlusPlatformInterface(true); + WakelockPlusPlatformInterfaceMock(); }); test('Can be extended', () { - WakelockPlusPlatformInterface.instance = ExtendsVideoPlayerPlatform(); + WakelockPlusPlatformInterface.instance = ExtendsWakelockPlusPlatform(); }); }); @@ -79,17 +82,29 @@ void main() { }); } +/// This class should fail verification because it uses `implements` +/// and does NOT use [MockPlatformInterfaceMixin]. class ImplementsWakelockPlusPlatformInterface implements WakelockPlusPlatformInterface { - const ImplementsWakelockPlusPlatformInterface(this.mocked); + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +/// This class should pass verification because it uses [MockPlatformInterfaceMixin]. +class WakelockPlusPlatformInterfaceMock + with MockPlatformInterfaceMixin + implements WakelockPlusPlatformInterface { + @override + Future get enabled => throw UnimplementedError(); - final bool mocked; + @override + bool get isMock => throw UnimplementedError(); @override - dynamic noSuchMethod(Invocation invocation) { - if (invocation.memberName == #isMock && mocked) return true; - throw NoSuchMethodError.withInvocation(this, invocation); + Future toggle({required bool enable}) { + throw UnimplementedError(); } } -class ExtendsVideoPlayerPlatform extends WakelockPlusPlatformInterface {} +/// This class should pass verification because it uses `extends`. +class ExtendsWakelockPlusPlatform extends WakelockPlusPlatformInterface {} From d9112dcc166c06af4d25a3e5dfa9b02323b0654c Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:06:29 -0400 Subject: [PATCH 04/33] Added N-1 Flutter version testing to checks. --- .github/workflows/checks.yml | 152 ++++++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 46 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index ebdd6e4..d7c9a89 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -16,29 +16,54 @@ on: - '**/integration_test/**' - '.github/workflows/checks.yml' +env: + # Minimum version supported by the package + FLUTTER_VERSION_MINIMUM_DEFAULT: "3.38.10" + # Moving latest stable + FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "stable" + # Moving beta channel + FLUTTER_VERSION_BETA_CHANNEL_DEFAULT: "beta" + jobs: + setup_matrix: + name: Determine Flutter Test Versions + runs-on: ubuntu-latest + outputs: + flutter_versions_json: ${{ steps.set_versions.outputs.versions_json }} + steps: + - name: Determine Flutter versions + id: set_versions + run: | + MIN="${{ env.FLUTTER_VERSION_MINIMUM_DEFAULT }}" + STABLE="${{ env.FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT }}" + BETA="${{ env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }}" + + # Create JSON array: ["3.38.10", "stable", "beta"] + VERSIONS_JSON=$(jq -c --null-input '$ARGS.positional' --args "$MIN" "$STABLE" "$BETA") + echo "versions_json=$VERSIONS_JSON" >> $GITHUB_OUTPUT + analyze: + needs: setup_matrix timeout-minutes: 15 runs-on: ubuntu-latest - name: ${{ matrix.package }} analysis on ${{ matrix.channel }} + name: ${{ matrix.package }} analysis on ${{ matrix.flutter_version }} strategy: matrix: - channel: [stable, beta] + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} package: [wakelock_plus, wakelock_plus_platform_interface] fail-fast: false steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: ${{ matrix.channel }} + flutter-version: ${{ matrix.flutter_version }} - name: Install dependencies run: flutter pub get working-directory: ${{ matrix.package }} - name: Check format - # We use --set-exit-if-changed to ensure CI fails if code isn't formatted - # according to dart style + # Ensure CI fails if code isn't formatted according to dart style run: dart format . --set-exit-if-changed working-directory: ${{ matrix.package }} continue-on-error: true @@ -47,32 +72,42 @@ jobs: run: flutter analyze working-directory: ${{ matrix.package }} - test_unit_interface: + unit_tests: + needs: setup_matrix runs-on: ubuntu-latest - name: Platform Interface Unit Tests + name: ${{ matrix.package }} unit tests on ${{ matrix.flutter_version }} + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + package: [wakelock_plus, wakelock_plus_platform_interface] + fail-fast: false steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} + + - name: Install dependencies + run: flutter pub get + working-directory: ${{ matrix.package }} - # Unit tests for the interface are separated to run on fast, cheap Linux runners - # as they do not require a physical device or simulator. - name: Run unit tests - run: | - flutter pub get - flutter test - working-directory: wakelock_plus_platform_interface + run: flutter test + working-directory: ${{ matrix.package }} # --- ANDROID JOBS --- android_example_build: + needs: setup_matrix runs-on: ubuntu-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Build Android APK run: | cd wakelock_plus/example @@ -80,12 +115,12 @@ jobs: flutter build apk --debug --target=./lib/main.dart android_integration_test: + needs: setup_matrix runs-on: ubuntu-latest timeout-minutes: 45 strategy: matrix: - # Matrix covers Min SDK (24), common mid-range versions, and latest (35) - # to ensure broad compatibility across the Android ecosystem. + flutter_version: [stable] api-level: [24, 28, 31, 33, 35] fail-fast: false name: Android Integration (API ${{ matrix.api-level }}) @@ -93,11 +128,10 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Enable KVM - # Linux runners require KVM (Kernel-based Virtual Machine) to be enabled - # to run Android emulators with hardware acceleration for acceptable CI performance. + # Linux runners require KVM to run Android emulators with hardware acceleration run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules @@ -110,7 +144,6 @@ jobs: target: google_apis arch: x86_64 force-avd-creation: false - # Swiftshader is used for software-based GPU acceleration in headless environments emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true working-directory: wakelock_plus/example @@ -122,12 +155,16 @@ jobs: # --- IOS JOBS --- ios_example_build: + needs: setup_matrix runs-on: macos-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Build iOS run: | cd wakelock_plus/example @@ -135,17 +172,19 @@ jobs: flutter build ios --no-codesign --debug --target=./lib/main.dart ios_integration_test: - # Per requirements: macOS-26 runner is required to access the iPhone 17 simulator environment + needs: setup_matrix runs-on: macos-26 timeout-minutes: 45 + strategy: + matrix: + flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Start iOS simulator - # Using the standard plus_plugins action to handle the simulator lifecycle uses: futureware-tech/simulator-action@v5 with: model: 'iPhone 17' @@ -161,12 +200,16 @@ jobs: # --- MACOS JOBS --- macos_example_build: + needs: setup_matrix runs-on: macos-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Build macOS run: | flutter config --enable-macos-desktop @@ -175,12 +218,16 @@ jobs: flutter build macos --debug --target=./lib/main.dart macos_integration_test: + needs: setup_matrix runs-on: macos-15 + strategy: + matrix: + flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Run Integration Tests run: | @@ -195,12 +242,16 @@ jobs: # --- LINUX JOBS --- linux_example_build: + needs: setup_matrix runs-on: ubuntu-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Install dependencies run: | sudo apt-get update @@ -213,24 +264,23 @@ jobs: flutter build linux --debug --target=./lib/main.dart linux_integration_test: + needs: setup_matrix runs-on: ubuntu-latest + strategy: + matrix: + flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Install dependencies - # Flutter Linux desktop requires specific C++ and GTK development headers to compile. - # xvfb provides a virtual display for headless environments. run: | sudo apt-get update sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb - name: Run Integration Tests - # xvfb-run (X Virtual Frame Buffer) is critical for Linux CI. - # It creates a virtual display in memory so that the Flutter application can - # initialize its UI/GPU context in a headless environment without a monitor. run: | flutter config --enable-linux-desktop cd wakelock_plus/example @@ -243,12 +293,16 @@ jobs: # --- WINDOWS JOBS --- windows_example_build: + needs: setup_matrix runs-on: windows-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Build Windows run: | flutter config --enable-windows-desktop @@ -257,12 +311,16 @@ jobs: flutter build windows --debug --target=./lib/main.dart windows_integration_test: + needs: setup_matrix runs-on: windows-latest + strategy: + matrix: + flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Run Integration Tests run: | @@ -277,12 +335,16 @@ jobs: # --- WEB JOBS --- web_example_build: + needs: setup_matrix runs-on: ubuntu-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Build Web run: | cd wakelock_plus/example @@ -290,32 +352,30 @@ jobs: flutter build web --debug --target=./lib/main.dart web_integration_test: + needs: setup_matrix runs-on: ubuntu-latest + strategy: + matrix: + flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: stable + flutter-version: ${{ matrix.flutter_version }} - name: Install Web Dependencies - # xvfb is required for a virtual display context, and chromium-chromedriver - # is the bridge between the test driver and the browser. run: | sudo apt-get update sudo apt-get install -y xvfb chromium-chromedriver - name: Run Integration Tests - # Following plus_plugins standard: - # 1. Start virtual framebuffer (Xvfb) for Chrome to run in. - # 2. Start chromedriver on port 4444. - # 3. Use -d chrome to allow driver to control the browser instance. run: | export DISPLAY=:99 Xvfb $DISPLAY -screen 0 1024x768x16 & - sleep 5 # Give xvfb some time to start. + sleep 5 chromedriver --port=4444 & - sleep 2 # Give chromedriver time to start. + sleep 2 flutter config --enable-web cd wakelock_plus/example From f312575e6c98b31387135e42f9c5ed27ce9d889d Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:13:18 -0400 Subject: [PATCH 05/33] Fixed failing workflow jobs. --- .github/workflows/checks.yml | 80 +++++++++++++++++------------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index d7c9a89..bb4f0e0 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -114,43 +114,40 @@ jobs: flutter pub get flutter build apk --debug --target=./lib/main.dart - android_integration_test: - needs: setup_matrix - runs-on: ubuntu-latest - timeout-minutes: 45 - strategy: - matrix: - flutter_version: [stable] - api-level: [24, 28, 31, 33, 35] - fail-fast: false - name: Android Integration (API ${{ matrix.api-level }}) - steps: - - uses: actions/checkout@v6 - - uses: subosito/flutter-action@v2 - with: - flutter-version: ${{ matrix.flutter_version }} - - - name: Enable KVM - # Linux runners require KVM to run Android emulators with hardware acceleration - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - - - name: Run Integration Tests - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - target: google_apis - arch: x86_64 - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: true - working-directory: wakelock_plus/example - script: | - flutter drive \ - --driver=test_driver/integration_test.dart \ - --target=integration_test/wakelock_plus_test.dart +android_integration_test: + needs: setup_matrix + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + matrix: + flutter_version: [stable] + api-level: [24, 28, 31, 33, 35] + fail-fast: false + name: Android Integration (API ${{ matrix.api-level }}) + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ matrix.flutter_version }} + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Run Integration Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: google_apis + arch: x86_64 + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + working-directory: wakelock_plus/example + # We use a single line here because the emulator-runner's script block often misinterprets backslashes + script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- IOS JOBS --- @@ -276,9 +273,10 @@ jobs: flutter-version: ${{ matrix.flutter_version }} - name: Install dependencies + # dbus-x11 provides dbus-run-session, which is required for plugins interacting with D-Bus run: | sudo apt-get update - sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb + sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb dbus-x11 - name: Run Integration Tests run: | @@ -323,14 +321,12 @@ jobs: flutter-version: ${{ matrix.flutter_version }} - name: Run Integration Tests + # We use a single line here to prevent PowerShell ParserErrors run: | flutter config --enable-windows-desktop cd wakelock_plus/example flutter pub get - flutter drive \ - -d windows \ - --driver=test_driver/integration_test.dart \ - --target=integration_test/wakelock_plus_test.dart + flutter drive -d windows --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- WEB JOBS --- From c134f032d5e7be3d6195e260341bc04a60dd4fc4 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:18:36 -0400 Subject: [PATCH 06/33] Fixed Linux integration test workflow job. --- .github/workflows/checks.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index bb4f0e0..b6efbe5 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -279,11 +279,12 @@ android_integration_test: sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb dbus-x11 - name: Run Integration Tests + # Wrap in dbus-run-session to provide the org.freedesktop.ScreenSaver service bus run: | flutter config --enable-linux-desktop cd wakelock_plus/example flutter pub get - xvfb-run flutter drive \ + xvfb-run dbus-run-session -- flutter drive \ -d linux \ --driver=test_driver/integration_test.dart \ --target=integration_test/wakelock_plus_test.dart @@ -369,15 +370,20 @@ android_integration_test: export DISPLAY=:99 Xvfb $DISPLAY -screen 0 1024x768x16 & sleep 5 - + chromedriver --port=4444 & sleep 2 - + flutter config --enable-web cd wakelock_plus/example flutter pub get + + # We use a timeout or ensure the process is killed if it hangs after "All tests passed!" + # In many CI environments, adding --no-build if already built helps, + # but here we ensure the drive command exits. flutter drive \ -d chrome \ --driver=test_driver/integration_test.dart \ --target=integration_test/wakelock_plus_test.dart \ - --dart-define=CI=true \ No newline at end of file + --dart-define=CI=true \ + --no-keep-app-running \ No newline at end of file From de373e5c8505e1d5c987563062fd099c84bb865f Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:19:46 -0400 Subject: [PATCH 07/33] Fixed workflow formatting. --- .github/workflows/checks.yml | 68 ++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index b6efbe5..47630c9 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -114,40 +114,40 @@ jobs: flutter pub get flutter build apk --debug --target=./lib/main.dart -android_integration_test: - needs: setup_matrix - runs-on: ubuntu-latest - timeout-minutes: 45 - strategy: - matrix: - flutter_version: [stable] - api-level: [24, 28, 31, 33, 35] - fail-fast: false - name: Android Integration (API ${{ matrix.api-level }}) - steps: - - uses: actions/checkout@v6 - - uses: subosito/flutter-action@v2 - with: - flutter-version: ${{ matrix.flutter_version }} - - - name: Enable KVM - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - - - name: Run Integration Tests - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - target: google_apis - arch: x86_64 - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: true - working-directory: wakelock_plus/example - # We use a single line here because the emulator-runner's script block often misinterprets backslashes - script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart + android_integration_test: + needs: setup_matrix + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + matrix: + flutter_version: [stable] + api-level: [24, 28, 31, 33, 35] + fail-fast: false + name: Android Integration (API ${{ matrix.api-level }}) + steps: + - uses: actions/checkout@v6 + - uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ matrix.flutter_version }} + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Run Integration Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: google_apis + arch: x86_64 + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + working-directory: wakelock_plus/example + # We use a single line here because the emulator-runner's script block often misinterprets backslashes + script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- IOS JOBS --- From 049a107410cd46f37a72d0c82c8078346b4bc96f Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:21:48 -0400 Subject: [PATCH 08/33] Fixed yet another workflow issue. --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 47630c9..5cee15d 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -20,7 +20,7 @@ env: # Minimum version supported by the package FLUTTER_VERSION_MINIMUM_DEFAULT: "3.38.10" # Moving latest stable - FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "stable" + FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "3.x" # Moving beta channel FLUTTER_VERSION_BETA_CHANNEL_DEFAULT: "beta" From 65c209d3102a748e77c6f6acbe5be38200d062fe Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:27:45 -0400 Subject: [PATCH 09/33] Workflow now juggles between the minimum Flutter version this package supports plus the stable and beta channels. --- .github/workflows/checks.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 5cee15d..8c32ced 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -38,7 +38,7 @@ jobs: STABLE="${{ env.FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT }}" BETA="${{ env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }}" - # Create JSON array: ["3.38.10", "stable", "beta"] + # Create JSON array: ["Latest N-1 version", "stable", "beta"] VERSIONS_JSON=$(jq -c --null-input '$ARGS.positional' --args "$MIN" "$STABLE" "$BETA") echo "versions_json=$VERSIONS_JSON" >> $GITHUB_OUTPUT @@ -56,7 +56,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ contains(matrix.flutter_version, '.') && matrix.flutter_version || '' }} + channel: ${{ !contains(matrix.flutter_version, '.') && matrix.flutter_version || '' }} - name: Install dependencies run: flutter pub get From 504811250852d0b25b3473fcbebdf837f168b3a9 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:28:54 -0400 Subject: [PATCH 10/33] Straggler from previous commit. --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 8c32ced..7ff71d1 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -20,7 +20,7 @@ env: # Minimum version supported by the package FLUTTER_VERSION_MINIMUM_DEFAULT: "3.38.10" # Moving latest stable - FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "3.x" + FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "stable" # Moving beta channel FLUTTER_VERSION_BETA_CHANNEL_DEFAULT: "beta" From 7aa5ebcf2b960e4ea49a4770f7f850fb6740dccc Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:40:32 -0400 Subject: [PATCH 11/33] Second attempt at supporting different versions and channels. --- .github/workflows/checks.yml | 84 ++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 7ff71d1..3aca81d 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -17,11 +17,12 @@ on: - '.github/workflows/checks.yml' env: - # Minimum version supported by the package + # The version of Flutter to use should use the minimum Dart SDK version supported by the package. + # Current minimum (N-1 logic) FLUTTER_VERSION_MINIMUM_DEFAULT: "3.38.10" - # Moving latest stable - FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "stable" - # Moving beta channel + # Latest 3.x stable + FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "3.x" + # Beta channel support FLUTTER_VERSION_BETA_CHANNEL_DEFAULT: "beta" jobs: @@ -38,7 +39,7 @@ jobs: STABLE="${{ env.FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT }}" BETA="${{ env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }}" - # Create JSON array: ["Latest N-1 version", "stable", "beta"] + # Create JSON array: ["3.38.10", "3.x", "beta"] VERSIONS_JSON=$(jq -c --null-input '$ARGS.positional' --args "$MIN" "$STABLE" "$BETA") echo "versions_json=$VERSIONS_JSON" >> $GITHUB_OUTPUT @@ -56,8 +57,9 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ contains(matrix.flutter_version, '.') && matrix.flutter_version || '' }} - channel: ${{ !contains(matrix.flutter_version, '.') && matrix.flutter_version || '' }} + # Logic: If version contains a dot or 'x', it's a version/3.x. Otherwise (beta), it's a channel. + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies run: flutter pub get @@ -86,7 +88,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies run: flutter pub get @@ -108,7 +111,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build Android APK run: | cd wakelock_plus/example @@ -121,7 +125,6 @@ jobs: timeout-minutes: 45 strategy: matrix: - flutter_version: [stable] api-level: [24, 28, 31, 33, 35] fail-fast: false name: Android Integration (API ${{ matrix.api-level }}) @@ -129,9 +132,10 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + channel: 'stable' # Integration tests run on stable to reduce emulator flakes - name: Enable KVM + # Hardware acceleration is required for Android emulators in CI run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules @@ -147,7 +151,7 @@ jobs: emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true working-directory: wakelock_plus/example - # We use a single line here because the emulator-runner's script block often misinterprets backslashes + # One-line script to prevent backslash-parsing errors in the emulator-runner script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- IOS JOBS --- @@ -162,7 +166,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build iOS run: | cd wakelock_plus/example @@ -171,16 +176,13 @@ jobs: ios_integration_test: needs: setup_matrix - runs-on: macos-26 + runs-on: macos-26 # Required for iPhone 17 / iOS 18 support timeout-minutes: 45 - strategy: - matrix: - flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + channel: 'stable' - name: Start iOS simulator uses: futureware-tech/simulator-action@v5 @@ -207,7 +209,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build macOS run: | flutter config --enable-macos-desktop @@ -218,14 +221,11 @@ jobs: macos_integration_test: needs: setup_matrix runs-on: macos-15 - strategy: - matrix: - flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + channel: 'stable' - name: Run Integration Tests run: | @@ -249,7 +249,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies run: | sudo apt-get update @@ -264,27 +265,24 @@ jobs: linux_integration_test: needs: setup_matrix runs-on: ubuntu-latest - strategy: - matrix: - flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + channel: 'stable' - name: Install dependencies - # dbus-x11 provides dbus-run-session, which is required for plugins interacting with D-Bus + # dbus-x11 and xvfb are required for plugins that interact with ScreenSaver services headlessly run: | sudo apt-get update sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb dbus-x11 - name: Run Integration Tests - # Wrap in dbus-run-session to provide the org.freedesktop.ScreenSaver service bus run: | flutter config --enable-linux-desktop cd wakelock_plus/example flutter pub get + # xvfb-run provides display, dbus-run-session provides session bus for ScreenSaver inhibition xvfb-run dbus-run-session -- flutter drive \ -d linux \ --driver=test_driver/integration_test.dart \ @@ -302,7 +300,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build Windows run: | flutter config --enable-windows-desktop @@ -313,17 +312,14 @@ jobs: windows_integration_test: needs: setup_matrix runs-on: windows-latest - strategy: - matrix: - flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + channel: 'stable' - name: Run Integration Tests - # We use a single line here to prevent PowerShell ParserErrors + # Use single line to prevent PowerShell parsing errors with backslashes run: | flutter config --enable-windows-desktop cd wakelock_plus/example @@ -342,7 +338,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build Web run: | cd wakelock_plus/example @@ -352,14 +349,11 @@ jobs: web_integration_test: needs: setup_matrix runs-on: ubuntu-latest - strategy: - matrix: - flutter_version: [stable] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + channel: 'stable' - name: Install Web Dependencies run: | @@ -371,17 +365,15 @@ jobs: export DISPLAY=:99 Xvfb $DISPLAY -screen 0 1024x768x16 & sleep 5 - + chromedriver --port=4444 & sleep 2 - + flutter config --enable-web cd wakelock_plus/example flutter pub get - # We use a timeout or ensure the process is killed if it hangs after "All tests passed!" - # In many CI environments, adding --no-build if already built helps, - # but here we ensure the drive command exits. + # Use --no-keep-app-running to ensure the process exits cleanly after tests pass flutter drive \ -d chrome \ --driver=test_driver/integration_test.dart \ From 082ee54217f302328a7e3cf2dacfdf92f2424877 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:46:14 -0400 Subject: [PATCH 12/33] Third attempt at supporting different versions and channels. --- .github/workflows/checks.yml | 75 +++++++++--------------------------- 1 file changed, 19 insertions(+), 56 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 3aca81d..5099c73 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -18,11 +18,8 @@ on: env: # The version of Flutter to use should use the minimum Dart SDK version supported by the package. - # Current minimum (N-1 logic) FLUTTER_VERSION_MINIMUM_DEFAULT: "3.38.10" - # Latest 3.x stable FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "3.x" - # Beta channel support FLUTTER_VERSION_BETA_CHANNEL_DEFAULT: "beta" jobs: @@ -39,7 +36,6 @@ jobs: STABLE="${{ env.FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT }}" BETA="${{ env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }}" - # Create JSON array: ["3.38.10", "3.x", "beta"] VERSIONS_JSON=$(jq -c --null-input '$ARGS.positional' --args "$MIN" "$STABLE" "$BETA") echo "versions_json=$VERSIONS_JSON" >> $GITHUB_OUTPUT @@ -57,16 +53,14 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - # Logic: If version contains a dot or 'x', it's a version/3.x. Otherwise (beta), it's a channel. - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + flutter-version: ${{ matrix.flutter_version }} - name: Install dependencies - run: flutter pub get + # We use --no-example to prevent SDK version conflicts in the example app during root package testing + run: flutter pub get --no-example working-directory: ${{ matrix.package }} - name: Check format - # Ensure CI fails if code isn't formatted according to dart style run: dart format . --set-exit-if-changed working-directory: ${{ matrix.package }} continue-on-error: true @@ -88,15 +82,12 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - - - name: Install dependencies - run: flutter pub get - working-directory: ${{ matrix.package }} + flutter-version: ${{ matrix.flutter_version }} - name: Run unit tests - run: flutter test + run: | + flutter pub get --no-example + flutter test working-directory: ${{ matrix.package }} # --- ANDROID JOBS --- @@ -111,8 +102,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + flutter-version: ${{ matrix.flutter_version }} - name: Build Android APK run: | cd wakelock_plus/example @@ -132,10 +122,9 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' # Integration tests run on stable to reduce emulator flakes + channel: 'stable' - name: Enable KVM - # Hardware acceleration is required for Android emulators in CI run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules @@ -151,7 +140,6 @@ jobs: emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true working-directory: wakelock_plus/example - # One-line script to prevent backslash-parsing errors in the emulator-runner script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- IOS JOBS --- @@ -166,8 +154,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + flutter-version: ${{ matrix.flutter_version }} - name: Build iOS run: | cd wakelock_plus/example @@ -176,7 +163,7 @@ jobs: ios_integration_test: needs: setup_matrix - runs-on: macos-26 # Required for iPhone 17 / iOS 18 support + runs-on: macos-26 timeout-minutes: 45 steps: - uses: actions/checkout@v6 @@ -193,9 +180,7 @@ jobs: run: | cd wakelock_plus/example flutter pub get - flutter drive \ - --driver=test_driver/integration_test.dart \ - --target=integration_test/wakelock_plus_test.dart + flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- MACOS JOBS --- @@ -209,8 +194,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + flutter-version: ${{ matrix.flutter_version }} - name: Build macOS run: | flutter config --enable-macos-desktop @@ -232,10 +216,7 @@ jobs: flutter config --enable-macos-desktop cd wakelock_plus/example flutter pub get - flutter drive \ - -d macos \ - --driver=test_driver/integration_test.dart \ - --target=integration_test/wakelock_plus_test.dart + flutter drive -d macos --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- LINUX JOBS --- @@ -249,8 +230,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + flutter-version: ${{ matrix.flutter_version }} - name: Install dependencies run: | sudo apt-get update @@ -272,7 +252,6 @@ jobs: channel: 'stable' - name: Install dependencies - # dbus-x11 and xvfb are required for plugins that interact with ScreenSaver services headlessly run: | sudo apt-get update sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb dbus-x11 @@ -282,11 +261,7 @@ jobs: flutter config --enable-linux-desktop cd wakelock_plus/example flutter pub get - # xvfb-run provides display, dbus-run-session provides session bus for ScreenSaver inhibition - xvfb-run dbus-run-session -- flutter drive \ - -d linux \ - --driver=test_driver/integration_test.dart \ - --target=integration_test/wakelock_plus_test.dart + xvfb-run dbus-run-session -- flutter drive -d linux --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- WINDOWS JOBS --- @@ -300,8 +275,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + flutter-version: ${{ matrix.flutter_version }} - name: Build Windows run: | flutter config --enable-windows-desktop @@ -319,7 +293,6 @@ jobs: channel: 'stable' - name: Run Integration Tests - # Use single line to prevent PowerShell parsing errors with backslashes run: | flutter config --enable-windows-desktop cd wakelock_plus/example @@ -338,8 +311,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + flutter-version: ${{ matrix.flutter_version }} - name: Build Web run: | cd wakelock_plus/example @@ -365,18 +337,9 @@ jobs: export DISPLAY=:99 Xvfb $DISPLAY -screen 0 1024x768x16 & sleep 5 - chromedriver --port=4444 & sleep 2 - flutter config --enable-web cd wakelock_plus/example flutter pub get - - # Use --no-keep-app-running to ensure the process exits cleanly after tests pass - flutter drive \ - -d chrome \ - --driver=test_driver/integration_test.dart \ - --target=integration_test/wakelock_plus_test.dart \ - --dart-define=CI=true \ - --no-keep-app-running \ No newline at end of file + flutter drive -d chrome --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart --dart-define=CI=true --no-keep-app-running \ No newline at end of file From 71fe2667ee753ed8604804948a1909457381ca9c Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:48:25 -0400 Subject: [PATCH 13/33] Fourth attempt at supporting different versions and channels. --- .github/workflows/checks.yml | 73 +++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 5099c73..8c2b463 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -18,8 +18,11 @@ on: env: # The version of Flutter to use should use the minimum Dart SDK version supported by the package. + # Current minimum (N-1 logic) FLUTTER_VERSION_MINIMUM_DEFAULT: "3.38.10" + # Latest 3.x stable FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "3.x" + # Beta channel support FLUTTER_VERSION_BETA_CHANNEL_DEFAULT: "beta" jobs: @@ -36,6 +39,7 @@ jobs: STABLE="${{ env.FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT }}" BETA="${{ env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }}" + # Create JSON array: ["3.38.10", "3.x", "beta"] VERSIONS_JSON=$(jq -c --null-input '$ARGS.positional' --args "$MIN" "$STABLE" "$BETA") echo "versions_json=$VERSIONS_JSON" >> $GITHUB_OUTPUT @@ -53,14 +57,16 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + # Logic: If version contains a dot or 'x', it's a version/3.x. Otherwise (beta), it's a channel. + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies - # We use --no-example to prevent SDK version conflicts in the example app during root package testing run: flutter pub get --no-example working-directory: ${{ matrix.package }} - name: Check format + # Ensure CI fails if code isn't formatted according to dart style run: dart format . --set-exit-if-changed working-directory: ${{ matrix.package }} continue-on-error: true @@ -82,12 +88,15 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + + - name: Install dependencies + run: flutter pub get --no-example + working-directory: ${{ matrix.package }} - name: Run unit tests - run: | - flutter pub get --no-example - flutter test + run: flutter test working-directory: ${{ matrix.package }} # --- ANDROID JOBS --- @@ -102,7 +111,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build Android APK run: | cd wakelock_plus/example @@ -122,9 +132,10 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' + channel: 'stable' # Integration tests run on stable to reduce emulator flakes - name: Enable KVM + # Hardware acceleration is required for Android emulators in CI run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules @@ -140,6 +151,7 @@ jobs: emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true working-directory: wakelock_plus/example + # One-line script to prevent backslash-parsing errors in the emulator-runner script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart # --- IOS JOBS --- @@ -154,7 +166,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build iOS run: | cd wakelock_plus/example @@ -163,7 +176,7 @@ jobs: ios_integration_test: needs: setup_matrix - runs-on: macos-26 + runs-on: macos-26 # Required for iPhone 17 / iOS 18 support timeout-minutes: 45 steps: - uses: actions/checkout@v6 @@ -180,7 +193,9 @@ jobs: run: | cd wakelock_plus/example flutter pub get - flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart + flutter drive \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart # --- MACOS JOBS --- @@ -194,7 +209,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build macOS run: | flutter config --enable-macos-desktop @@ -216,7 +232,10 @@ jobs: flutter config --enable-macos-desktop cd wakelock_plus/example flutter pub get - flutter drive -d macos --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart + flutter drive \ + -d macos \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart # --- LINUX JOBS --- @@ -230,7 +249,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies run: | sudo apt-get update @@ -252,6 +272,7 @@ jobs: channel: 'stable' - name: Install dependencies + # dbus-x11 and xvfb are required for plugins that interact with ScreenSaver services headlessly run: | sudo apt-get update sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb dbus-x11 @@ -261,7 +282,11 @@ jobs: flutter config --enable-linux-desktop cd wakelock_plus/example flutter pub get - xvfb-run dbus-run-session -- flutter drive -d linux --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart + # xvfb-run provides display, dbus-run-session provides session bus for ScreenSaver inhibition + xvfb-run dbus-run-session -- flutter drive \ + -d linux \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart # --- WINDOWS JOBS --- @@ -275,7 +300,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build Windows run: | flutter config --enable-windows-desktop @@ -293,6 +319,7 @@ jobs: channel: 'stable' - name: Run Integration Tests + # Use single line to prevent PowerShell parsing errors with backslashes run: | flutter config --enable-windows-desktop cd wakelock_plus/example @@ -311,7 +338,8 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - flutter-version: ${{ matrix.flutter_version }} + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build Web run: | cd wakelock_plus/example @@ -337,9 +365,18 @@ jobs: export DISPLAY=:99 Xvfb $DISPLAY -screen 0 1024x768x16 & sleep 5 + chromedriver --port=4444 & sleep 2 + flutter config --enable-web cd wakelock_plus/example flutter pub get - flutter drive -d chrome --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart --dart-define=CI=true --no-keep-app-running \ No newline at end of file + + # Use --no-keep-app-running to ensure the process exits cleanly after tests pass + flutter drive \ + -d chrome \ + --driver=test_driver/integration_test.dart \ + --target=integration_test/wakelock_plus_test.dart \ + --dart-define=CI=true \ + --no-keep-app-running \ No newline at end of file From cc3dcf17e875c800c4515fd19597b65efb9c152d Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:54:40 -0400 Subject: [PATCH 14/33] Example app is now set to the minimum supported Flutter version. --- wakelock_plus/example/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wakelock_plus/example/pubspec.yaml b/wakelock_plus/example/pubspec.yaml index e1db1da..9ef7d7c 100644 --- a/wakelock_plus/example/pubspec.yaml +++ b/wakelock_plus/example/pubspec.yaml @@ -5,8 +5,8 @@ description: Demonstrates how to use the wakelock_plus plugin. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: '>=3.11.0 <4.0.0' - flutter: ">=3.41.0" + sdk: '>=3.10.0 <4.0.0' + flutter: ">=3.38.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions From 43ae2700eec3bcb5d2a8b88500ee2acc4d700bcb Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 19:58:21 -0400 Subject: [PATCH 15/33] Format workflow jobs should continue on error when running it on the minimum Flutter version. --- .github/workflows/checks.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 8c2b463..ee65f92 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -69,7 +69,10 @@ jobs: # Ensure CI fails if code isn't formatted according to dart style run: dart format . --set-exit-if-changed working-directory: ${{ matrix.package }} - continue-on-error: true + # Only continue on error if this is the job for the MINIMUM Flutter version + # This allows formatting issues to be warnings on older supported versions + # but enforces them on the latest stable or primary development version. + continue-on-error: ${{ matrix.flutter-version == env.FLUTTER_VERSION_MINIMUM_DEFAULT }} - name: Analyze run: flutter analyze From 2251a167e0a7932f93c408c738375a65d2c8fbd6 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:01:11 -0400 Subject: [PATCH 16/33] Format workflow jobs should also continue on error when running it on the beta channel. --- .github/workflows/checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index ee65f92..d1ca47e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -69,10 +69,10 @@ jobs: # Ensure CI fails if code isn't formatted according to dart style run: dart format . --set-exit-if-changed working-directory: ${{ matrix.package }} - # Only continue on error if this is the job for the MINIMUM Flutter version + # Only continue on error if this is the job for the MINIMUM Flutter version or beta channel. # This allows formatting issues to be warnings on older supported versions # but enforces them on the latest stable or primary development version. - continue-on-error: ${{ matrix.flutter-version == env.FLUTTER_VERSION_MINIMUM_DEFAULT }} + continue-on-error: ${{ matrix.flutter-version == env.FLUTTER_VERSION_MINIMUM_DEFAULT || matrix.channel == env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT}} - name: Analyze run: flutter analyze From f4197c38fa2e20bfc6d571897f96ad8d3d54e0d9 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:02:59 -0400 Subject: [PATCH 17/33] Nit from previous commit. --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index d1ca47e..a22c55e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -72,7 +72,7 @@ jobs: # Only continue on error if this is the job for the MINIMUM Flutter version or beta channel. # This allows formatting issues to be warnings on older supported versions # but enforces them on the latest stable or primary development version. - continue-on-error: ${{ matrix.flutter-version == env.FLUTTER_VERSION_MINIMUM_DEFAULT || matrix.channel == env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT}} + continue-on-error: ${{ matrix.flutter-version == env.FLUTTER_VERSION_MINIMUM_DEFAULT || matrix.channel == env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }} - name: Analyze run: flutter analyze From fc367436fdbdc3da1ba2f9a28ab514b69d932f1b Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:06:28 -0400 Subject: [PATCH 18/33] Another nit from previous commit. --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index a22c55e..f478eb6 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -72,7 +72,7 @@ jobs: # Only continue on error if this is the job for the MINIMUM Flutter version or beta channel. # This allows formatting issues to be warnings on older supported versions # but enforces them on the latest stable or primary development version. - continue-on-error: ${{ matrix.flutter-version == env.FLUTTER_VERSION_MINIMUM_DEFAULT || matrix.channel == env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }} + continue-on-error: ${{ matrix.flutter_version == env.FLUTTER_VERSION_MINIMUM_DEFAULT || matrix.flutter_version == env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }} - name: Analyze run: flutter analyze From 3863133d9b474d47f5d7926f888ded11f8f46516 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:17:52 -0400 Subject: [PATCH 19/33] Fixed formatting. --- wakelock_plus/example/lib/main.dart | 22 ++-- .../lib/src/wakelock_plus_linux_plugin.dart | 2 +- .../lib/src/wakelock_plus_macos_plugin.dart | 4 +- .../lib/src/wakelock_plus_web_plugin.dart | 4 +- .../lib/src/web_impl/import_js_library.dart | 6 +- wakelock_plus/lib/wakelock_plus.dart | 4 +- wakelock_plus/pigeons/messages.dart | 28 ++--- .../test/wakelock_plus_web_plugin_test.dart | 4 +- .../lib/messages.g.dart | 108 +++++++++--------- .../test/messages.g.dart | 96 ++++++++++------ 10 files changed, 152 insertions(+), 126 deletions(-) diff --git a/wakelock_plus/example/lib/main.dart b/wakelock_plus/example/lib/main.dart index 4098ae0..b935bbf 100644 --- a/wakelock_plus/example/lib/main.dart +++ b/wakelock_plus/example/lib/main.dart @@ -23,16 +23,12 @@ class _WakelockPlusExampleAppState extends State { Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - appBar: AppBar( - title: const Text('Wakelock example app'), - ), + appBar: AppBar(title: const Text('Wakelock example app')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - const Spacer( - flex: 3, - ), + const Spacer(flex: 3), OutlinedButton( onPressed: () { // The following code will enable the wakelock on the device @@ -56,9 +52,7 @@ class _WakelockPlusExampleAppState extends State { }, child: const Text('disable wakelock'), ), - const Spacer( - flex: 2, - ), + const Spacer(flex: 2), FutureBuilder( future: WakelockPlus.enabled, builder: (context, AsyncSnapshot snapshot) { @@ -71,13 +65,13 @@ class _WakelockPlusExampleAppState extends State { return Container(); } - return Text('The wakelock is currently ' - '${data ? 'enabled' : 'disabled'}.'); + return Text( + 'The wakelock is currently ' + '${data ? 'enabled' : 'disabled'}.', + ); }, ), - const Spacer( - flex: 3, - ), + const Spacer(flex: 3), ], ), ), diff --git a/wakelock_plus/lib/src/wakelock_plus_linux_plugin.dart b/wakelock_plus/lib/src/wakelock_plus_linux_plugin.dart index 44c1818..187b39b 100644 --- a/wakelock_plus/lib/src/wakelock_plus_linux_plugin.dart +++ b/wakelock_plus/lib/src/wakelock_plus_linux_plugin.dart @@ -18,7 +18,7 @@ class WakelockPlusLinuxPlugin extends WakelockPlusPlatformInterface { /// Constructs an instance of [WakelockPlusLinuxPlugin]. WakelockPlusLinuxPlugin({@visibleForTesting DBusRemoteObject? object}) - : _object = object ?? _createRemoteObject(); + : _object = object ?? _createRemoteObject(); final DBusRemoteObject _object; int? _cookie; diff --git a/wakelock_plus/lib/src/wakelock_plus_macos_plugin.dart b/wakelock_plus/lib/src/wakelock_plus_macos_plugin.dart index 078b451..03ac0a8 100644 --- a/wakelock_plus/lib/src/wakelock_plus_macos_plugin.dart +++ b/wakelock_plus/lib/src/wakelock_plus_macos_plugin.dart @@ -21,9 +21,7 @@ class WakelockPlusMacOSPlugin extends WakelockPlusPlatformInterface { @override Future toggle({required bool enable}) async { - await _channel.invokeMethod('toggle', { - 'enable': enable, - }); + await _channel.invokeMethod('toggle', {'enable': enable}); } @override diff --git a/wakelock_plus/lib/src/wakelock_plus_web_plugin.dart b/wakelock_plus/lib/src/wakelock_plus_web_plugin.dart index 73cf3f3..a21ed32 100644 --- a/wakelock_plus/lib/src/wakelock_plus_web_plugin.dart +++ b/wakelock_plus/lib/src/wakelock_plus_web_plugin.dart @@ -17,7 +17,9 @@ class WakelockPlusWebPlugin extends WakelockPlusPlatformInterface { // Import a version of `NoSleep.js` that was adjusted for the wakelock // plugin. _jsLoaded = importJsLibrary( - url: 'assets/no_sleep.js', flutterPluginName: 'wakelock_plus'); + url: 'assets/no_sleep.js', + flutterPluginName: 'wakelock_plus', + ); WakelockPlusPlatformInterface.instance = WakelockPlusWebPlugin(); } diff --git a/wakelock_plus/lib/src/web_impl/import_js_library.dart b/wakelock_plus/lib/src/web_impl/import_js_library.dart index b998c6d..461b47e 100644 --- a/wakelock_plus/lib/src/web_impl/import_js_library.dart +++ b/wakelock_plus/lib/src/web_impl/import_js_library.dart @@ -8,8 +8,10 @@ import 'package:web/web.dart'; /// Imports a JS script file from the given [url] given the relative /// [flutterPluginName]. -Future importJsLibrary( - {required String url, String? flutterPluginName}) async { +Future importJsLibrary({ + required String url, + String? flutterPluginName, +}) async { if (flutterPluginName == null) { return _importJSLibraries([url]); } else { diff --git a/wakelock_plus/lib/wakelock_plus.dart b/wakelock_plus/lib/wakelock_plus.dart index 8b918ce..23f85da 100644 --- a/wakelock_plus/lib/wakelock_plus.dart +++ b/wakelock_plus/lib/wakelock_plus.dart @@ -63,9 +63,7 @@ class WakelockPlus { /// ``` /// /// You can await the [Future] to wait for the operation to complete. - static Future toggle({ - required bool enable, - }) { + static Future toggle({required bool enable}) { return wakelockPlusPlatformInstance.toggle(enable: enable); } diff --git a/wakelock_plus/pigeons/messages.dart b/wakelock_plus/pigeons/messages.dart index d2f1828..e6100b5 100644 --- a/wakelock_plus/pigeons/messages.dart +++ b/wakelock_plus/pigeons/messages.dart @@ -10,20 +10,22 @@ class IsEnabledMessage { bool? enabled; } -@ConfigurePigeon(PigeonOptions( - dartOut: '../wakelock_plus_platform_interface/lib/messages.g.dart', - dartTestOut: '../wakelock_plus_platform_interface/test/messages.g.dart', - objcHeaderOut: - 'ios/wakelock_plus/Sources/wakelock_plus/include/wakelock_plus/messages.g.h', - objcSourceOut: 'ios/wakelock_plus/Sources/wakelock_plus/messages.g.m', - objcOptions: ObjcOptions( - prefix: 'WAKELOCKPLUS', - headerIncludePath: './include/wakelock_plus/messages.g.h', +@ConfigurePigeon( + PigeonOptions( + dartOut: '../wakelock_plus_platform_interface/lib/messages.g.dart', + dartTestOut: '../wakelock_plus_platform_interface/test/messages.g.dart', + objcHeaderOut: + 'ios/wakelock_plus/Sources/wakelock_plus/include/wakelock_plus/messages.g.h', + objcSourceOut: 'ios/wakelock_plus/Sources/wakelock_plus/messages.g.m', + objcOptions: ObjcOptions( + prefix: 'WAKELOCKPLUS', + headerIncludePath: './include/wakelock_plus/messages.g.h', + ), + kotlinOptions: KotlinOptions(errorClassName: "WakelockPlusFlutterError"), + kotlinOut: + 'android/src/main/kotlin/dev/fluttercommunity/plus/wakelock/WakelockPlusMessages.g.kt', ), - kotlinOptions: KotlinOptions(errorClassName: "WakelockPlusFlutterError"), - kotlinOut: - 'android/src/main/kotlin/dev/fluttercommunity/plus/wakelock/WakelockPlusMessages.g.kt', -)) +) @HostApi(dartHostTestHandler: 'TestWakelockPlusApi') abstract class WakelockPlusApi { void toggle(ToggleMessage msg); diff --git a/wakelock_plus/test/wakelock_plus_web_plugin_test.dart b/wakelock_plus/test/wakelock_plus_web_plugin_test.dart index 869b576..11c0529 100644 --- a/wakelock_plus/test/wakelock_plus_web_plugin_test.dart +++ b/wakelock_plus/test/wakelock_plus_web_plugin_test.dart @@ -15,7 +15,9 @@ void main() { test('$WakelockPlusWebPlugin set as default instance', () { expect( - WakelockPlusPlatformInterface.instance, isA()); + WakelockPlusPlatformInterface.instance, + isA(), + ); }); test('initially disabled', () async { diff --git a/wakelock_plus_platform_interface/lib/messages.g.dart b/wakelock_plus_platform_interface/lib/messages.g.dart index 4a4ce96..6a2e4de 100644 --- a/wakelock_plus_platform_interface/lib/messages.g.dart +++ b/wakelock_plus_platform_interface/lib/messages.g.dart @@ -10,9 +10,9 @@ import 'package:flutter/services.dart'; import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; Object? _extractReplyValueOrThrow( - List? replyList, - String channelName, { - required bool isNullValid, + List? replyList, + String channelName, { + required bool isNullValid, }) { if (replyList == null) { throw PlatformException( @@ -34,8 +34,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } - -List wrapResponse({Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -44,43 +47,42 @@ List wrapResponse({Object? result, PlatformException? error, bool empty } return [error.code, error.message, error.details]; } + bool _deepEquals(Object? a, Object? b) { if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { - return a.length == b.length && a.entries.every((MapEntry entry) => - (b as Map).containsKey(entry.key) && - _deepEquals(entry.value, b[entry.key])); + return a.length == b.length && + a.entries.every( + (MapEntry entry) => + (b as Map).containsKey(entry.key) && + _deepEquals(entry.value, b[entry.key]), + ); } return a == b; } - /// Message for toggling the wakelock on the platform side. class ToggleMessage { - ToggleMessage({ - this.enable, - }); + ToggleMessage({this.enable}); bool? enable; List _toList() { - return [ - enable, - ]; + return [enable]; } Object encode() { - return _toList(); } + return _toList(); + } static ToggleMessage decode(Object result) { result as List; - return ToggleMessage( - enable: result[0] as bool?, - ); + return ToggleMessage(enable: result[0] as bool?); } @override @@ -97,32 +99,26 @@ class ToggleMessage { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()) -; + int get hashCode => Object.hashAll(_toList()); } /// Message for reporting the wakelock state from the platform side. class IsEnabledMessage { - IsEnabledMessage({ - this.enabled, - }); + IsEnabledMessage({this.enabled}); bool? enabled; List _toList() { - return [ - enabled, - ]; + return [enabled]; } Object encode() { - return _toList(); } + return _toList(); + } static IsEnabledMessage decode(Object result) { result as List; - return IsEnabledMessage( - enabled: result[0] as bool?, - ); + return IsEnabledMessage(enabled: result[0] as bool?); } @override @@ -139,11 +135,9 @@ class IsEnabledMessage { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()) -; + int get hashCode => Object.hashAll(_toList()); } - class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -151,10 +145,10 @@ class _PigeonCodec extends StandardMessageCodec { if (value is int) { buffer.putUint8(4); buffer.putInt64(value); - } else if (value is ToggleMessage) { + } else if (value is ToggleMessage) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is IsEnabledMessage) { + } else if (value is IsEnabledMessage) { buffer.putUint8(130); writeValue(buffer, value.encode()); } else { @@ -179,9 +173,13 @@ class WakelockPlusApi { /// Constructor for [WakelockPlusApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - WakelockPlusApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + WakelockPlusApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -189,25 +187,28 @@ class WakelockPlusApi { final String pigeonVar_messageChannelSuffix; Future toggle(ToggleMessage msg) async { - final pigeonVar_channelName = 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = + 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send([msg]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [msg], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( - pigeonVar_replyList, - pigeonVar_channelName, - isNullValid: true, - ) - ; + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); } Future isEnabled() async { - final pigeonVar_channelName = 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = + 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -217,11 +218,10 @@ class WakelockPlusApi { final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( - pigeonVar_replyList, - pigeonVar_channelName, - isNullValid: false, - ) - ; + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); return pigeonVar_replyValue! as IsEnabledMessage; } } diff --git a/wakelock_plus_platform_interface/test/messages.g.dart b/wakelock_plus_platform_interface/test/messages.g.dart index 945b212..8fb3d3b 100644 --- a/wakelock_plus_platform_interface/test/messages.g.dart +++ b/wakelock_plus_platform_interface/test/messages.g.dart @@ -10,7 +10,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:wakelock_plus_platform_interface/messages.g.dart'; - class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -18,10 +17,10 @@ class _PigeonCodec extends StandardMessageCodec { if (value is int) { buffer.putUint8(4); buffer.putInt64(value); - } else if (value is ToggleMessage) { + } else if (value is ToggleMessage) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is IsEnabledMessage) { + } else if (value is IsEnabledMessage) { buffer.putUint8(130); writeValue(buffer, value.encode()); } else { @@ -43,53 +42,82 @@ class _PigeonCodec extends StandardMessageCodec { } abstract class TestWakelockPlusApi { - static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); void toggle(ToggleMessage msg); IsEnabledMessage isEnabled(); - static void setUp(TestWakelockPlusApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) { - messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + static void setUp( + TestWakelockPlusApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$messageChannelSuffix', pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.toggle$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(pigeonVar_channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - final List args = message! as List; - final ToggleMessage arg_msg = args[0]! as ToggleMessage; - try { - api.toggle(arg_msg); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); - } - }); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final ToggleMessage arg_msg = args[0]! as ToggleMessage; + try { + api.toggle(arg_msg); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$messageChannelSuffix', pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.wakelock_plus_platform_interface.WakelockPlusApi.isEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(pigeonVar_channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(pigeonVar_channel, (Object? message) async { - try { - final IsEnabledMessage output = api.isEnabled(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); - } - }); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final IsEnabledMessage output = api.isEnabled(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } From 4d0eeb5e2fa8db1b70b5dddb90766fe833f582f7 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:22:21 -0400 Subject: [PATCH 20/33] Added a mock background D-Bus service for Linux integration tests. --- .github/workflows/checks.yml | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index f478eb6..b8fee64 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -268,6 +268,9 @@ jobs: linux_integration_test: needs: setup_matrix runs-on: ubuntu-latest + strategy: + matrix: + flutter_version: [ stable ] steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 @@ -275,21 +278,44 @@ jobs: channel: 'stable' - name: Install dependencies - # dbus-x11 and xvfb are required for plugins that interact with ScreenSaver services headlessly run: | sudo apt-get update - sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev xvfb dbus-x11 + sudo apt-get install -y \ + clang cmake ninja-build pkg-config \ + libgtk-3-dev liblzma-dev xvfb dbus-x11 \ + python3-dbus python3-gi - name: Run Integration Tests run: | flutter config --enable-linux-desktop cd wakelock_plus/example flutter pub get - # xvfb-run provides display, dbus-run-session provides session bus for ScreenSaver inhibition - xvfb-run dbus-run-session -- flutter drive \ + + # We use xvfb-run and dbus-run-session. + # Inside the session, we start a tiny Python background process that + # mocks the 'org.freedesktop.ScreenSaver' service so the plugin has + # a valid target to talk to. + xvfb-run dbus-run-session bash -c " + python3 -c \" + import dbus, dbus.service + from dbus.mainloop.glib import DBusGMainLoop + from gi.repository import GLib + class Mock(dbus.service.Object): + def __init__(self): + bus_name = dbus.service.BusName('org.freedesktop.ScreenSaver', bus=dbus.SessionBus()) + dbus.service.Object.__init__(self, bus_name, '/org/freedesktop/ScreenSaver') + @dbus.service.method('org.freedesktop.ScreenSaver', in_signature='ss', out_signature='u') + def Inhibit(self, a, r): return 1 + @dbus.service.method('org.freedesktop.ScreenSaver', in_signature='u', out_signature='') + def UnInhibit(self, c): pass + DBusGMainLoop(set_as_default=True) + Mock() + GLib.MainLoop().run()\" & + sleep 2 && \ + flutter drive \ -d linux \ --driver=test_driver/integration_test.dart \ - --target=integration_test/wakelock_plus_test.dart + --target=integration_test/wakelock_plus_test.dart" # --- WINDOWS JOBS --- From 3ba872c2e62ba2d554a630428ebd518fbf2f6a22 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:41:51 -0400 Subject: [PATCH 21/33] Scoped flutter analyze to just the lib and test directories. --- .github/workflows/checks.yml | 129 +++++++++++++++++++++-------------- 1 file changed, 79 insertions(+), 50 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index b8fee64..05bcd9f 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -3,18 +3,18 @@ name: checks on: workflow_dispatch: pull_request: - branches: - - main - paths: - - '**/lib/**' - - '**/android/**' - - '**/ios/**' - - '**/pubspec.yaml' - - '**/test/**' - - '**/test_driver/**' - - '**/assets/**' - - '**/integration_test/**' - - '.github/workflows/checks.yml' + branches: + - main + paths: + - '**/lib/**' + - '**/android/**' + - '**/ios/**' + - '**/pubspec.yaml' + - '**/test/**' + - '**/test_driver/**' + - '**/assets/**' + - '**/integration_test/**' + - '.github/workflows/checks.yml' env: # The version of Flutter to use should use the minimum Dart SDK version supported by the package. @@ -62,6 +62,7 @@ jobs: channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies + # --no-example is crucial here because the root package often has a lower min SDK than the example app run: flutter pub get --no-example working-directory: ${{ matrix.package }} @@ -69,13 +70,11 @@ jobs: # Ensure CI fails if code isn't formatted according to dart style run: dart format . --set-exit-if-changed working-directory: ${{ matrix.package }} - # Only continue on error if this is the job for the MINIMUM Flutter version or beta channel. - # This allows formatting issues to be warnings on older supported versions - # but enforces them on the latest stable or primary development version. continue-on-error: ${{ matrix.flutter_version == env.FLUTTER_VERSION_MINIMUM_DEFAULT || matrix.flutter_version == env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }} - name: Analyze - run: flutter analyze + # We explicitly analyze only lib and test to ignore the example app's integration tests + run: flutter analyze lib test working-directory: ${{ matrix.package }} unit_tests: @@ -102,7 +101,7 @@ jobs: run: flutter test working-directory: ${{ matrix.package }} - # --- ANDROID JOBS --- + # --- ANDROID --- android_example_build: needs: setup_matrix @@ -112,6 +111,10 @@ jobs: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 + - name: Install dependencies (Linux build hosts) + run: | + sudo apt-get update + sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev - uses: subosito/flutter-action@v2 with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} @@ -125,20 +128,22 @@ jobs: android_integration_test: needs: setup_matrix runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 60 strategy: matrix: - api-level: [24, 28, 31, 33, 35] + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + api-level: [24, 35] fail-fast: false - name: Android Integration (API ${{ matrix.api-level }}) + name: Android Integration (API ${{ matrix.api-level }} - ${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' # Integration tests run on stable to reduce emulator flakes + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Enable KVM - # Hardware acceleration is required for Android emulators in CI + # Linux runners require KVM to run Android emulators with hardware acceleration run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules @@ -154,10 +159,10 @@ jobs: emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true working-directory: wakelock_plus/example - # One-line script to prevent backslash-parsing errors in the emulator-runner + # We use a single line here because the emulator-runner's script block often misinterprets backslashes script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart - # --- IOS JOBS --- + # --- IOS --- ios_example_build: needs: setup_matrix @@ -179,15 +184,22 @@ jobs: ios_integration_test: needs: setup_matrix - runs-on: macos-26 # Required for iPhone 17 / iOS 18 support - timeout-minutes: 45 + # Per requirements: macOS-26 runner is required to access the iPhone 17 simulator environment + runs-on: macos-26 + timeout-minutes: 60 + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: iOS Integration (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Start iOS simulator + # Using standard simulator-action to handle the simulator lifecycle on macOS-26 uses: futureware-tech/simulator-action@v5 with: model: 'iPhone 17' @@ -200,7 +212,7 @@ jobs: --driver=test_driver/integration_test.dart \ --target=integration_test/wakelock_plus_test.dart - # --- MACOS JOBS --- + # --- MACOS --- macos_example_build: needs: setup_matrix @@ -224,11 +236,16 @@ jobs: macos_integration_test: needs: setup_matrix runs-on: macos-15 + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: macOS Integration (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Run Integration Tests run: | @@ -240,7 +257,7 @@ jobs: --driver=test_driver/integration_test.dart \ --target=integration_test/wakelock_plus_test.dart - # --- LINUX JOBS --- + # --- LINUX --- linux_example_build: needs: setup_matrix @@ -250,14 +267,14 @@ jobs: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} steps: - uses: actions/checkout@v6 - - uses: subosito/flutter-action@v2 - with: - flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev + - uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Build Linux run: | flutter config --enable-linux-desktop @@ -270,14 +287,18 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - flutter_version: [ stable ] + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + fail-fast: false + name: Linux Integration (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies + # dbus-x11 and xvfb are critical for plugins that interact with ScreenSaver services headlessly run: | sudo apt-get update sudo apt-get install -y \ @@ -290,11 +311,9 @@ jobs: flutter config --enable-linux-desktop cd wakelock_plus/example flutter pub get - - # We use xvfb-run and dbus-run-session. - # Inside the session, we start a tiny Python background process that - # mocks the 'org.freedesktop.ScreenSaver' service so the plugin has - # a valid target to talk to. + + # We use xvfb-run (display) and dbus-run-session (bus). + # Inside, we run a Python mock of 'org.freedesktop.ScreenSaver' so the plugin logic succeeds. xvfb-run dbus-run-session bash -c " python3 -c \" import dbus, dbus.service @@ -310,14 +329,14 @@ jobs: def UnInhibit(self, c): pass DBusGMainLoop(set_as_default=True) Mock() - GLib.MainLoop().run()\" & - sleep 2 && \ + GLib.MainLoop().run()\" & + sleep 5 && \ flutter drive \ -d linux \ --driver=test_driver/integration_test.dart \ --target=integration_test/wakelock_plus_test.dart" - # --- WINDOWS JOBS --- + # --- WINDOWS --- windows_example_build: needs: setup_matrix @@ -341,21 +360,26 @@ jobs: windows_integration_test: needs: setup_matrix runs-on: windows-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: Windows Integration (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Run Integration Tests - # Use single line to prevent PowerShell parsing errors with backslashes + # Use single line to prevent PowerShell ParserErrors with backslashes run: | flutter config --enable-windows-desktop cd wakelock_plus/example flutter pub get flutter drive -d windows --driver=test_driver/integration_test.dart --target=integration_test/wakelock_plus_test.dart - # --- WEB JOBS --- + # --- WEB --- web_example_build: needs: setup_matrix @@ -378,11 +402,16 @@ jobs: web_integration_test: needs: setup_matrix runs-on: ubuntu-latest + strategy: + matrix: + flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: Web Integration (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: - channel: 'stable' + flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install Web Dependencies run: | @@ -391,10 +420,10 @@ jobs: - name: Run Integration Tests run: | + # Start virtual framebuffer (Xvfb) and chromedriver for Chrome headless testing export DISPLAY=:99 Xvfb $DISPLAY -screen 0 1024x768x16 & sleep 5 - chromedriver --port=4444 & sleep 2 @@ -402,7 +431,7 @@ jobs: cd wakelock_plus/example flutter pub get - # Use --no-keep-app-running to ensure the process exits cleanly after tests pass + # Use --no-keep-app-running to ensure process exits after tests flutter drive \ -d chrome \ --driver=test_driver/integration_test.dart \ From d571063821588ffdc4dd8479fdb22c4b29989ff4 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:44:11 -0400 Subject: [PATCH 22/33] Straggler from previous commit, again. --- .github/workflows/checks.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 05bcd9f..1d8a68e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -3,18 +3,18 @@ name: checks on: workflow_dispatch: pull_request: - branches: - - main - paths: - - '**/lib/**' - - '**/android/**' - - '**/ios/**' - - '**/pubspec.yaml' - - '**/test/**' - - '**/test_driver/**' - - '**/assets/**' - - '**/integration_test/**' - - '.github/workflows/checks.yml' + branches: + - main + paths: + - '**/lib/**' + - '**/android/**' + - '**/ios/**' + - '**/pubspec.yaml' + - '**/test/**' + - '**/test_driver/**' + - '**/assets/**' + - '**/integration_test/**' + - '.github/workflows/checks.yml' env: # The version of Flutter to use should use the minimum Dart SDK version supported by the package. From f24706ceead66a602ca4fd5dfc8e1cb5c6df6fb0 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:52:23 -0400 Subject: [PATCH 23/33] More workflow cleanup, again. --- .github/workflows/checks.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 1d8a68e..bf26252 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -109,6 +109,7 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: Android Example Build (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - name: Install dependencies (Linux build hosts) @@ -132,7 +133,12 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} - api-level: [24, 35] + # 24: Min SDK (Nougat) + # 28: Pre-Scoped Storage / Legacy (Pie) + # 31: Android 12 (S) - Significant splash screen and permission changes + # 33: Android 13 (T) - Granular media permissions + # 35: Android 15 (Latest Stable) + api-level: [24, 28, 31, 33, 35] fail-fast: false name: Android Integration (API ${{ matrix.api-level }} - ${{ matrix.flutter_version }}) steps: @@ -166,10 +172,11 @@ jobs: ios_example_build: needs: setup_matrix - runs-on: macos-latest + runs-on: macos-26 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: iOS Example Build (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 @@ -216,10 +223,11 @@ jobs: macos_example_build: needs: setup_matrix - runs-on: macos-latest + runs-on: macos-26 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: macOS Example Build (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 @@ -235,7 +243,7 @@ jobs: macos_integration_test: needs: setup_matrix - runs-on: macos-15 + runs-on: macos-26 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -265,6 +273,7 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: Linux Example Build (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - name: Install dependencies @@ -344,6 +353,7 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: Windows Example Build (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 @@ -387,6 +397,7 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} + name: Web Example Build (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 From 2e898035c9657e97919b2c0e8792cc7eccf1874e Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 20:54:58 -0400 Subject: [PATCH 24/33] More workflow cleanup, yet again. --- .github/workflows/checks.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index bf26252..53309d0 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -133,12 +133,12 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} - # 24: Min SDK (Nougat) - # 28: Pre-Scoped Storage / Legacy (Pie) - # 31: Android 12 (S) - Significant splash screen and permission changes - # 33: Android 13 (T) - Granular media permissions - # 35: Android 15 (Latest Stable) - api-level: [24, 28, 31, 33, 35] + # 24: Min SDK (Nougat) + # 28: Pre-Scoped Storage / Legacy (Pie) + # 31: Android 12 (S) - Significant splash screen and permission changes + # 33: Android 13 (T) - Granular media permissions + # 35: Android 15 (Latest Stable) + api-level: [24, 28, 31, 33, 35] fail-fast: false name: Android Integration (API ${{ matrix.api-level }} - ${{ matrix.flutter_version }}) steps: From e436ad252bbbda7b6d90684e6f8d161570b904cf Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 22:59:51 -0400 Subject: [PATCH 25/33] Attempt at not hanging the web integration tests. --- .github/workflows/checks.yml | 47 ++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 53309d0..c7dc07c 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -106,6 +106,7 @@ jobs: android_example_build: needs: setup_matrix runs-on: ubuntu-latest + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -173,6 +174,7 @@ jobs: ios_example_build: needs: setup_matrix runs-on: macos-26 + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -224,6 +226,7 @@ jobs: macos_example_build: needs: setup_matrix runs-on: macos-26 + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -244,6 +247,7 @@ jobs: macos_integration_test: needs: setup_matrix runs-on: macos-26 + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -270,6 +274,7 @@ jobs: linux_example_build: needs: setup_matrix runs-on: ubuntu-latest + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -294,6 +299,7 @@ jobs: linux_integration_test: needs: setup_matrix runs-on: ubuntu-latest + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -350,6 +356,7 @@ jobs: windows_example_build: needs: setup_matrix runs-on: windows-latest + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -370,6 +377,7 @@ jobs: windows_integration_test: needs: setup_matrix runs-on: windows-latest + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -394,6 +402,7 @@ jobs: web_example_build: needs: setup_matrix runs-on: ubuntu-latest + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -413,6 +422,7 @@ jobs: web_integration_test: needs: setup_matrix runs-on: ubuntu-latest + timeout-minutes: 30 strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} @@ -424,28 +434,39 @@ jobs: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - - name: Install Web Dependencies + - name: Setup Chrome & Driver + uses: nanasess/setup-chromedriver@v2 + + - name: Start ChromeDriver & Xvfb run: | - sudo apt-get update - sudo apt-get install -y xvfb chromium-chromedriver + # 1. Define the display port + export DISPLAY=:99 + # 2. Start ChromeDriver on the standard port + chromedriver --url-base=/wd/hub --port=4444 & + # 3. Start Xvfb manually. This creates the 'screen' that 'export DISPLAY' points to. + sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & + sleep 5 - name: Run Integration Tests run: | - # Start virtual framebuffer (Xvfb) and chromedriver for Chrome headless testing + # We must export DISPLAY again in this step so the Flutter tool knows where the screen is. export DISPLAY=:99 - Xvfb $DISPLAY -screen 0 1024x768x16 & - sleep 5 - chromedriver --port=4444 & - sleep 2 - + flutter config --enable-web cd wakelock_plus/example flutter pub get - - # Use --no-keep-app-running to ensure process exits after tests - flutter drive \ + + # We DO NOT use 'xvfb-run' here because we already started Xvfb manually above. + # 'timeout' is still used to prevent the CI hang. + timeout 10m flutter drive \ -d chrome \ --driver=test_driver/integration_test.dart \ --target=integration_test/wakelock_plus_test.dart \ --dart-define=CI=true \ - --no-keep-app-running \ No newline at end of file + --no-keep-app-running || { + if [ $? -eq 124 ]; then + echo "Flutter drive reached timeout. Process was killed to prevent CI hang." + else + exit $? + fi + } \ No newline at end of file From 19e9a1d96f60ff0554aa0ba191d09d6648d6f176 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 23:09:15 -0400 Subject: [PATCH 26/33] Second attempt at not hanging the web integration tests. --- .github/workflows/checks.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index c7dc07c..495f3eb 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -62,7 +62,7 @@ jobs: channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - name: Install dependencies - # --no-example is crucial here because the root package often has a lower min SDK than the example app + # --no-example is crucial here so that we only get the library's dependencies run: flutter pub get --no-example working-directory: ${{ matrix.package }} @@ -70,6 +70,9 @@ jobs: # Ensure CI fails if code isn't formatted according to dart style run: dart format . --set-exit-if-changed working-directory: ${{ matrix.package }} + # Only skip errors if we're on the minimum default version, + # or if we're running the beta channel. + # The only version that matters as far as formatting is concerned is the latest version. continue-on-error: ${{ matrix.flutter_version == env.FLUTTER_VERSION_MINIMUM_DEFAULT || matrix.flutter_version == env.FLUTTER_VERSION_BETA_CHANNEL_DEFAULT }} - name: Analyze @@ -421,7 +424,8 @@ jobs: web_integration_test: needs: setup_matrix - runs-on: ubuntu-latest + runs-on: + ubuntu-latest timeout-minutes: 30 strategy: matrix: @@ -434,8 +438,10 @@ jobs: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} - - name: Setup Chrome & Driver - uses: nanasess/setup-chromedriver@v2 + - name: Install Web Dependencies + run: | + sudo apt-get update + sudo apt-get install -y xvfb chromium-chromedriver - name: Start ChromeDriver & Xvfb run: | From d621499a8711f24353851bc734534d7670798fe6 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 23:16:27 -0400 Subject: [PATCH 27/33] Third attempt at not hanging the web integration tests. --- .github/workflows/checks.yml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 495f3eb..74cc05a 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -424,8 +424,7 @@ jobs: web_integration_test: needs: setup_matrix - runs-on: - ubuntu-latest + runs-on: ubuntu-latest timeout-minutes: 30 strategy: matrix: @@ -441,29 +440,27 @@ jobs: - name: Install Web Dependencies run: | sudo apt-get update - sudo apt-get install -y xvfb chromium-chromedriver + # We only need xvfb. Chrome and Chromedriver are pre-installed on the runner. + sudo apt-get install -y xvfb - - name: Start ChromeDriver & Xvfb + - name: Start Xvfb run: | - # 1. Define the display port - export DISPLAY=:99 - # 2. Start ChromeDriver on the standard port - chromedriver --url-base=/wd/hub --port=4444 & - # 3. Start Xvfb manually. This creates the 'screen' that 'export DISPLAY' points to. + # Start Xvfb manually to create the virtual screen :99 sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & sleep 5 - name: Run Integration Tests run: | - # We must export DISPLAY again in this step so the Flutter tool knows where the screen is. + # Export the display so the browser launched by flutter_drive knows where to render export DISPLAY=:99 flutter config --enable-web cd wakelock_plus/example flutter pub get - # We DO NOT use 'xvfb-run' here because we already started Xvfb manually above. - # 'timeout' is still used to prevent the CI hang. + # We do NOT start chromedriver manually. + # flutter_drive will find the system-installed chromedriver and manage it. + # 'timeout' is used to forcefully exit the process if it hangs after finishing. timeout 10m flutter drive \ -d chrome \ --driver=test_driver/integration_test.dart \ From 63c763d7f30d9f3990385c3002a7499d0b99e3c0 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 23:25:58 -0400 Subject: [PATCH 28/33] Fourth attempt at not hanging the web integration tests. --- .github/workflows/checks.yml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 74cc05a..2264371 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -440,27 +440,34 @@ jobs: - name: Install Web Dependencies run: | sudo apt-get update - # We only need xvfb. Chrome and Chromedriver are pre-installed on the runner. - sudo apt-get install -y xvfb + # Install xvfb and the specific chromium-chromedriver + sudo apt-get install -y xvfb chromium-chromedriver - - name: Start Xvfb + - name: Start ChromeDriver & Xvfb run: | - # Start Xvfb manually to create the virtual screen :99 - sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & + # 1. Export DISPLAY so chromedriver knows which screen to use + export DISPLAY=:99 + + # 2. Start Xvfb manually with the resolution used by plus_plugins + Xvfb $DISPLAY -screen 0 1024x768x16 & + + # 3. Start chromedriver on the port expected by Flutter's web driver + # Note: We omit --url-base=/wd/hub to support modern W3C protocol + chromedriver --port=4444 & + + # 4. Give services time to initialize sleep 5 - name: Run Integration Tests run: | - # Export the display so the browser launched by flutter_drive knows where to render + # Must re-export DISPLAY in this step as well export DISPLAY=:99 flutter config --enable-web cd wakelock_plus/example flutter pub get - # We do NOT start chromedriver manually. - # flutter_drive will find the system-installed chromedriver and manage it. - # 'timeout' is used to forcefully exit the process if it hangs after finishing. + # Use timeout to prevent the CI hang common in headless web environments timeout 10m flutter drive \ -d chrome \ --driver=test_driver/integration_test.dart \ From 5e17f2fcdd5b6a7073838967c96a0acef44033e1 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Wed, 11 Mar 2026 23:39:05 -0400 Subject: [PATCH 29/33] Fifth attempt at not hanging the web integration tests. --- .github/workflows/checks.yml | 70 +++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 2264371..04ac887 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -4,17 +4,23 @@ on: workflow_dispatch: pull_request: branches: - - main + - main paths: - - '**/lib/**' - - '**/android/**' - - '**/ios/**' - - '**/pubspec.yaml' - - '**/test/**' - - '**/test_driver/**' - - '**/assets/**' - - '**/integration_test/**' - - '.github/workflows/checks.yml' + - '**/lib/**' + - '**/android/**' + - '**/ios/**' + - '**/pubspec.yaml' + - '**/test/**' + - '**/test_driver/**' + - '**/assets/**' + - '**/integration_test/**' + - '.github/workflows/checks.yml' + paths-ignore: + - '**.md' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: # The version of Flutter to use should use the minimum Dart SDK version supported by the package. @@ -60,6 +66,8 @@ jobs: # Logic: If version contains a dot or 'x', it's a version/3.x. Otherwise (beta), it's a channel. flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Install dependencies # --no-example is crucial here so that we only get the library's dependencies @@ -95,6 +103,8 @@ jobs: with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Install dependencies run: flutter pub get --no-example @@ -124,6 +134,8 @@ jobs: with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Build Android APK run: | cd wakelock_plus/example @@ -144,13 +156,15 @@ jobs: # 35: Android 15 (Latest Stable) api-level: [24, 28, 31, 33, 35] fail-fast: false - name: Android Integration (API ${{ matrix.api-level }} - ${{ matrix.flutter_version }}) + name: Android Integration Test (API ${{ matrix.api-level }} - ${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Enable KVM # Linux runners require KVM to run Android emulators with hardware acceleration @@ -188,6 +202,8 @@ jobs: with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Build iOS run: | cd wakelock_plus/example @@ -202,13 +218,15 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} - name: iOS Integration (${{ matrix.flutter_version }}) + name: iOS Integration Test (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Start iOS simulator # Using standard simulator-action to handle the simulator lifecycle on macOS-26 @@ -240,6 +258,8 @@ jobs: with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Build macOS run: | flutter config --enable-macos-desktop @@ -254,13 +274,15 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} - name: macOS Integration (${{ matrix.flutter_version }}) + name: macOS Integration Test (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Run Integration Tests run: | @@ -292,6 +314,8 @@ jobs: with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Build Linux run: | flutter config --enable-linux-desktop @@ -307,13 +331,15 @@ jobs: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} fail-fast: false - name: Linux Integration (${{ matrix.flutter_version }}) + name: Linux Integration Test (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Install dependencies # dbus-x11 and xvfb are critical for plugins that interact with ScreenSaver services headlessly @@ -370,6 +396,8 @@ jobs: with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Build Windows run: | flutter config --enable-windows-desktop @@ -384,13 +412,15 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} - name: Windows Integration (${{ matrix.flutter_version }}) + name: Windows Integration Test (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Run Integration Tests # Use single line to prevent PowerShell ParserErrors with backslashes @@ -416,6 +446,8 @@ jobs: with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Build Web run: | cd wakelock_plus/example @@ -429,13 +461,15 @@ jobs: strategy: matrix: flutter_version: ${{ fromJson(needs.setup_matrix.outputs.flutter_versions_json) }} - name: Web Integration (${{ matrix.flutter_version }}) + name: Web Integration Test (${{ matrix.flutter_version }}) steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@v2 with: flutter-version: ${{ (contains(matrix.flutter_version, '.') || contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} channel: ${{ (!contains(matrix.flutter_version, '.') && !contains(matrix.flutter_version, 'x')) && matrix.flutter_version || '' }} + cache: true + cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} - name: Install Web Dependencies run: | @@ -447,14 +481,10 @@ jobs: run: | # 1. Export DISPLAY so chromedriver knows which screen to use export DISPLAY=:99 - # 2. Start Xvfb manually with the resolution used by plus_plugins Xvfb $DISPLAY -screen 0 1024x768x16 & - # 3. Start chromedriver on the port expected by Flutter's web driver - # Note: We omit --url-base=/wd/hub to support modern W3C protocol chromedriver --port=4444 & - # 4. Give services time to initialize sleep 5 From bf6bdf22dcbde611409751116732f976f77977a4 Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Thu, 12 Mar 2026 00:17:23 -0400 Subject: [PATCH 30/33] Sixth attempt at not hanging the web integration tests. --- .github/workflows/checks.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 04ac887..f0c3bcc 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -15,8 +15,6 @@ on: - '**/assets/**' - '**/integration_test/**' - '.github/workflows/checks.yml' - paths-ignore: - - '**.md' concurrency: group: ${{ github.workflow }}-${{ github.ref }} From 8b4204850cfe5378daadcaf097c767c897eeaacf Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Thu, 12 Mar 2026 00:32:33 -0400 Subject: [PATCH 31/33] Upgraded the example web app's page as per the current standard. --- wakelock_plus/example/web/index.html | 31 +++++++--------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/wakelock_plus/example/web/index.html b/wakelock_plus/example/web/index.html index be820e8..89e7052 100644 --- a/wakelock_plus/example/web/index.html +++ b/wakelock_plus/example/web/index.html @@ -31,29 +31,14 @@ example - - - - - + + - + \ No newline at end of file From c0fec8775ac9ae008b06c043008a88e28f83428e Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Thu, 12 Mar 2026 12:00:35 -0400 Subject: [PATCH 32/33] Upgraded macos and iOS configurations in the example app. --- wakelock_plus/.gitignore | 1 + .../ios/Flutter/AppFrameworkInfo.plist | 2 -- wakelock_plus/example/ios/Podfile | 2 +- wakelock_plus/example/ios/Podfile.lock | 4 +-- .../ios/Runner.xcodeproj/project.pbxproj | 6 ++-- .../xcshareddata/xcschemes/Runner.xcscheme | 2 ++ .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 5 +++- wakelock_plus/example/ios/Runner/Info.plist | 29 ++++++++++++++++--- wakelock_plus/example/macos/Podfile | 2 +- wakelock_plus/example/macos/Podfile.lock | 10 +++---- .../macos/Runner.xcodeproj/project.pbxproj | 10 +++---- .../xcshareddata/xcschemes/Runner.xcscheme | 1 + .../example/macos/Runner/AppDelegate.swift | 4 +++ 14 files changed, 55 insertions(+), 25 deletions(-) diff --git a/wakelock_plus/.gitignore b/wakelock_plus/.gitignore index b69a950..1d0bf2d 100644 --- a/wakelock_plus/.gitignore +++ b/wakelock_plus/.gitignore @@ -68,6 +68,7 @@ pubspec.lock **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* +**/.build/ # Exceptions to above rules. !**/ios/**/default.mode1v3 diff --git a/wakelock_plus/example/ios/Flutter/AppFrameworkInfo.plist b/wakelock_plus/example/ios/Flutter/AppFrameworkInfo.plist index 7c56964..391a902 100644 --- a/wakelock_plus/example/ios/Flutter/AppFrameworkInfo.plist +++ b/wakelock_plus/example/ios/Flutter/AppFrameworkInfo.plist @@ -20,7 +20,5 @@ ???? CFBundleVersion 1.0 - MinimumOSVersion - 12.0 diff --git a/wakelock_plus/example/ios/Podfile b/wakelock_plus/example/ios/Podfile index 06630d1..ed16470 100644 --- a/wakelock_plus/example/ios/Podfile +++ b/wakelock_plus/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '12.0' +platform :ios, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/wakelock_plus/example/ios/Podfile.lock b/wakelock_plus/example/ios/Podfile.lock index 2fd83ad..9acc3a8 100644 --- a/wakelock_plus/example/ios/Podfile.lock +++ b/wakelock_plus/example/ios/Podfile.lock @@ -24,11 +24,11 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: - Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556 -PODFILE CHECKSUM: beab77b38961de946f08660e554f80ac174dc842 +PODFILE CHECKSUM: a5dd15803c05a42a9ae1068254e24631f03bf853 COCOAPODS: 1.16.2 diff --git a/wakelock_plus/example/ios/Runner.xcodeproj/project.pbxproj b/wakelock_plus/example/ios/Runner.xcodeproj/project.pbxproj index 11e1f77..ba455e4 100644 --- a/wakelock_plus/example/ios/Runner.xcodeproj/project.pbxproj +++ b/wakelock_plus/example/ios/Runner.xcodeproj/project.pbxproj @@ -463,7 +463,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -580,7 +580,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -629,7 +629,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/wakelock_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/wakelock_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 7bdc624..d7417c1 100644 --- a/wakelock_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/wakelock_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" shouldUseLaunchSchemeArgsEnv = "YES"> #import -@interface AppDelegate : FlutterAppDelegate +@interface AppDelegate : FlutterAppDelegate @end diff --git a/wakelock_plus/example/ios/Runner/AppDelegate.m b/wakelock_plus/example/ios/Runner/AppDelegate.m index 70e8393..cebafc9 100644 --- a/wakelock_plus/example/ios/Runner/AppDelegate.m +++ b/wakelock_plus/example/ios/Runner/AppDelegate.m @@ -5,9 +5,12 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. return [super application:application didFinishLaunchingWithOptions:launchOptions]; } +- (void)didInitializeImplicitFlutterEngine:(NSObject*)engineBridge { + [GeneratedPluginRegistrant registerWithRegistry:engineBridge.pluginRegistry]; +} + @end diff --git a/wakelock_plus/example/ios/Runner/Info.plist b/wakelock_plus/example/ios/Runner/Info.plist index 6745578..013ffbe 100644 --- a/wakelock_plus/example/ios/Runner/Info.plist +++ b/wakelock_plus/example/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -24,6 +26,29 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + FlutterSceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -41,9 +66,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/wakelock_plus/example/macos/Podfile b/wakelock_plus/example/macos/Podfile index c795730..b52666a 100644 --- a/wakelock_plus/example/macos/Podfile +++ b/wakelock_plus/example/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.14' +platform :osx, '10.15' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/wakelock_plus/example/macos/Podfile.lock b/wakelock_plus/example/macos/Podfile.lock index 2a585cb..7648763 100644 --- a/wakelock_plus/example/macos/Podfile.lock +++ b/wakelock_plus/example/macos/Podfile.lock @@ -19,10 +19,10 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos SPEC CHECKSUMS: - FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c - wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 + FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 + package_info_plus: f0052d280d17aa382b932f399edf32507174e870 + wakelock_plus: 917609be14d812ddd9e9528876538b2263aaa03b -PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 +PODFILE CHECKSUM: 9ebaf0ce3d369aaa26a9ea0e159195ed94724cf3 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/wakelock_plus/example/macos/Runner.xcodeproj/project.pbxproj b/wakelock_plus/example/macos/Runner.xcodeproj/project.pbxproj index bd47dd9..aa2ae1c 100644 --- a/wakelock_plus/example/macos/Runner.xcodeproj/project.pbxproj +++ b/wakelock_plus/example/macos/Runner.xcodeproj/project.pbxproj @@ -195,7 +195,6 @@ 40C6B7F8860B1BE2A6B07ADA /* Pods-RunnerTests.release.xcconfig */, AF138727C3933020F89B6B28 /* Pods-RunnerTests.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -342,6 +341,7 @@ }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -358,7 +358,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire\n"; }; 4AE49CEDD56F01D3AA086266 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; @@ -553,7 +553,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -632,7 +632,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -679,7 +679,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/wakelock_plus/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/wakelock_plus/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index f798615..26392b6 100644 --- a/wakelock_plus/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/wakelock_plus/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/wakelock_plus/example/macos/Runner/AppDelegate.swift b/wakelock_plus/example/macos/Runner/AppDelegate.swift index 8e02df2..b3c1761 100644 --- a/wakelock_plus/example/macos/Runner/AppDelegate.swift +++ b/wakelock_plus/example/macos/Runner/AppDelegate.swift @@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } From 8b5d060d5af3a5cb33f157ece4b4216ffc90332d Mon Sep 17 00:00:00 2001 From: Diego Tori Date: Thu, 12 Mar 2026 13:07:10 -0400 Subject: [PATCH 33/33] Attempt and reducing flakiness in the iOS Integration Tests. --- .github/workflows/checks.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index f0c3bcc..bf3ba78 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -231,6 +231,9 @@ jobs: uses: futureware-tech/simulator-action@v5 with: model: 'iPhone 17' + wait_for_boot: true + boot_timeout_seconds: 600 + boot_retries: 5 - name: Run Integration Tests run: |