From 469997fb03a6c8c1e2c90c7e9a37d3dccb32d839 Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 10:51:48 +0530 Subject: [PATCH 01/14] feat: Add support for FlutterIOSDriver --- .github/workflows/gradle.yml | 21 ++++-- .../java_client/android/BaseFlutterTest.java | 23 +++++-- .../java_client/android/CommandTest.java | 56 +++++++++++++++ .../java_client/flutter/FlutterDriver.java | 23 +++++++ .../flutter/FlutterDriverOptions.java | 35 ++++++++++ .../SupportsGestureOnFlutterElements.java | 35 ++++++++++ .../flutter/android/FlutterAndroidDriver.java | 7 +- .../commands/DoubleClickParameter.java | 31 +++++++++ .../commands/DragAndDropParameter.java | 27 ++++++++ .../flutter/commands/LongPressParameter.java | 31 +++++++++ .../flutter/ios/FlutterIOSDriver.java | 69 +++++++++++++++++++ ...portsFlutterServerLaunchTimeoutOption.java | 36 ++++++++++ .../SupportsFlutterSystemPortOption.java | 33 +++++++++ 13 files changed, 409 insertions(+), 18 deletions(-) create mode 100644 src/main/java/io/appium/java_client/flutter/FlutterDriver.java create mode 100644 src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java create mode 100644 src/main/java/io/appium/java_client/flutter/SupportsGestureOnFlutterElements.java create mode 100644 src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java create mode 100644 src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java create mode 100644 src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java create mode 100644 src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java create mode 100644 src/main/java/io/appium/java_client/flutter/options/SupportsFlutterServerLaunchTimeoutOption.java create mode 100644 src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 8cdab0ef7..0c2040b71 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -27,6 +27,7 @@ env: IOS_DEVICE_NAME: iPhone 15 IOS_PLATFORM_VERSION: "17.5" FLUTTER_ANDROID_APP: "https://github.com/AppiumTestDistribution/appium-flutter-server/releases/latest/download/app-debug.apk" + FLUTTER_IOS_APP: "https://github.com/AppiumTestDistribution/appium-flutter-server/releases/latest/download/ios.zip" jobs: build: @@ -38,6 +39,10 @@ jobs: # Need to use specific (not `-latest`) version of macOS to be sure the required version of Xcode/simulator is available platform: macos-14 e2e-tests: ios + - java: 17 + # Need to use specific (not `-latest`) version of macOS to be sure the required version of Xcode/simulator is available + platform: macos-14 + e2e-tests: flutter-ios - java: 17 platform: ubuntu-latest e2e-tests: android @@ -77,13 +82,13 @@ jobs: ./gradlew clean build -PisCI -Pselenium.version=$latest_snapshot - name: Install Node.js - if: matrix.e2e-tests == 'android' || matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-android' + if: matrix.e2e-tests == 'android' || matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-android' || matrix.e2e-tests == 'flutter-ios' uses: actions/setup-node@v4 with: node-version: 'lts/*' - name: Install Appium - if: matrix.e2e-tests == 'android' || matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-android' + if: matrix.e2e-tests == 'android' || matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-android' || matrix.e2e-tests == 'flutter-ios' run: npm install --location=global appium - name: Install UIA2 driver @@ -117,22 +122,26 @@ jobs: target: ${{ env.ANDROID_EMU_TARGET }} - name: Select Xcode - if: matrix.e2e-tests == 'ios' + if: matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-ios' uses: maxim-lobanov/setup-xcode@v1 with: xcode-version: "${{ env.XCODE_VERSION }}" - name: Prepare iOS simulator - if: matrix.e2e-tests == 'ios' + if: matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-ios' uses: futureware-tech/simulator-action@v3 with: model: "${{ env.IOS_DEVICE_NAME }}" os_version: "${{ env.IOS_PLATFORM_VERSION }}" - name: Install XCUITest driver - if: matrix.e2e-tests == 'ios' + if: matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-ios' run: appium driver install xcuitest - name: Prebuild XCUITest driver - if: matrix.e2e-tests == 'ios' + if: matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-ios' run: appium driver run xcuitest build-wda - name: Run iOS E2E tests if: matrix.e2e-tests == 'ios' run: ./gradlew e2eIosTest -PisCI -Pselenium.version=$latest_snapshot + + - name: Run Flutter iOS E2E tests + if: matrix.e2e-tests == 'flutter-ios' + run: ./gradlew e2eFlutterTest -Pplatform="ios" -Pselenium.version=$latest_snapshot -PisCI -PflutterApp=${{ env.FLUTTER_IOS_APP }} diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index e18112d4a..f9d8f24e3 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -2,8 +2,12 @@ import io.appium.java_client.AppiumBy; import io.appium.java_client.android.options.UiAutomator2Options; +import io.appium.java_client.flutter.FlutterDriver; +import io.appium.java_client.flutter.FlutterDriverOptions; import io.appium.java_client.flutter.android.FlutterAndroidDriver; import io.appium.java_client.flutter.commands.ScrollParameter; +import io.appium.java_client.flutter.ios.FlutterIOSDriver; +import io.appium.java_client.ios.options.XCUITestOptions; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServiceBuilder; @@ -12,10 +16,10 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.openqa.selenium.By; -import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.WebElement; import java.net.MalformedURLException; +import java.time.Duration; import java.util.Optional; class BaseFlutterTest { @@ -29,7 +33,7 @@ class BaseFlutterTest { protected static final int PORT = 4723; private static AppiumDriverLocalService service; - protected static FlutterAndroidDriver driver; + protected static FlutterDriver driver; protected static final By LOGIN_BUTTON = AppiumBy.flutterText("Login"); /** @@ -46,16 +50,21 @@ public static void beforeClass() { @BeforeEach public void startSession() throws MalformedURLException { + FlutterDriverOptions flutterOptions = new FlutterDriverOptions() + .setFlutterSystemPort(9999) + .setFlutterServerLaunchTimeout(Duration.ofSeconds(10)); + if (IS_ANDROID) { - // TODO: update it with FlutterDriverOptions once implemented UiAutomator2Options options = new UiAutomator2Options() - .setAutomationName(AutomationName.FLUTTER_INTEGRATION) .setApp(System.getProperty("flutterApp")) .eventTimings(); - driver = new FlutterAndroidDriver(service.getUrl(), options); + driver = new FlutterAndroidDriver(service.getUrl(), options.merge(flutterOptions)); } else { - throw new InvalidArgumentException( - "Currently flutter driver implementation only supports android platform"); + XCUITestOptions options = new XCUITestOptions() + .setAutomationName(AutomationName.FLUTTER_INTEGRATION) + .setApp(System.getProperty("flutterApp")) + .eventTimings(); + driver = new FlutterIOSDriver(service.getUrl(), options.merge(flutterOptions)); } } diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java index 80f32002d..30d513446 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java @@ -3,7 +3,11 @@ import io.appium.java_client.AppiumBy; import io.appium.java_client.flutter.commands.ScrollParameter; import io.appium.java_client.flutter.commands.WaitParameter; +import io.appium.java_client.flutter.commands.DoubleClickParameter; +import io.appium.java_client.flutter.commands.LongPressParameter; +import io.appium.java_client.flutter.commands.DragAndDropParameter; import org.junit.jupiter.api.Test; +import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -59,4 +63,56 @@ public void testScrollTillVisibleCommand() { assertFalse(Boolean.parseBoolean(lastElement.getAttribute("displayed"))); } + @Test + public void testDoubleClickCommand() { + driver.findElement(BaseFlutterTest.LOGIN_BUTTON).click(); + openScreen("Double Tap"); + + WebElement doubleTapButton = driver + .findElement(AppiumBy.flutterKey("double_tap_button")) + .findElement(AppiumBy.flutterText("Double Tap")); + assertEquals("Double Tap", doubleTapButton.getText()); + + AppiumBy.FlutterBy okButton = AppiumBy.flutterText("Ok"); + AppiumBy.FlutterBy successPopup = AppiumBy.flutterTextContaining("Successful"); + + driver.performDoubleClick(new DoubleClickParameter().setElement(doubleTapButton)); + assertEquals(driver.findElement(successPopup).getText(), "Double Tap Successful"); + driver.findElement(okButton).click(); + + driver.performDoubleClick(new DoubleClickParameter() + .setElement(doubleTapButton) + .setOffset(new Point(10, 2)) + ); + assertEquals(driver.findElement(successPopup).getText(), "Double Tap Successful"); + driver.findElement(okButton).click(); + } + + @Test + public void testLongPressCommand() { + driver.findElement(BaseFlutterTest.LOGIN_BUTTON).click(); + openScreen("Long Press"); + + AppiumBy.FlutterBy successPopup = AppiumBy.flutterText("It was a long press"); + WebElement longPressButton = driver + .findElement(AppiumBy.flutterKey("long_press_button")); + + driver.performLongPress(new LongPressParameter().setElement(longPressButton)); + assertEquals(driver.findElement(successPopup).getText(), "It was a long press"); + assertTrue(driver.findElement(successPopup).isDisplayed()); + } + + @Test + public void testDragAndDropCommand() { + driver.findElement(BaseFlutterTest.LOGIN_BUTTON).click(); + openScreen("Drag & Drop"); + + driver.performDragAndDrop(new DragAndDropParameter( + driver.findElement(AppiumBy.flutterKey("drag_me")), + driver.findElement(AppiumBy.flutterKey("drop_zone")) + )); + assertTrue(driver.findElement(AppiumBy.flutterText("The box is dropped")).isDisplayed()); + assertEquals(driver.findElement(AppiumBy.flutterText("The box is dropped")).getText(), "The box is dropped"); + + } } diff --git a/src/main/java/io/appium/java_client/flutter/FlutterDriver.java b/src/main/java/io/appium/java_client/flutter/FlutterDriver.java new file mode 100644 index 000000000..6dd3853e8 --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/FlutterDriver.java @@ -0,0 +1,23 @@ +package io.appium.java_client.flutter; + +import org.openqa.selenium.WebDriver; + +/** + * The {@code FlutterDriver} interface represents a driver that controls interactions with + * Flutter applications, extending WebDriver and providing additional capabilities for + * interacting with Flutter-specific elements and behaviors. + * + *

This interface serves as a common entity for drivers that support Flutter applications + * on different platforms, such as Android and iOS.

+ * + * @see WebDriver + * @see SupportsGestureOnFlutterElements + * @see SupportsScrollingOfFlutterElements + * @see SupportsWaitingForFlutterElements + */ +public interface FlutterDriver extends + WebDriver, + SupportsGestureOnFlutterElements, + SupportsScrollingOfFlutterElements, + SupportsWaitingForFlutterElements { +} diff --git a/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java b/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java new file mode 100644 index 000000000..b6c2e16f8 --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java @@ -0,0 +1,35 @@ +package io.appium.java_client.flutter; + +import io.appium.java_client.flutter.options.SupportsFlutterServerLaunchTimeoutOption; +import io.appium.java_client.flutter.options.SupportsFlutterSystemPortOption; +import io.appium.java_client.remote.AutomationName; +import io.appium.java_client.remote.options.BaseOptions; +import org.openqa.selenium.Capabilities; + +import java.util.Map; + +/** + * https://github.com/AppiumTestDistribution/appium-flutter-integration-driver#capabilities-for-appium-flutter-integration-driver + */ +public class FlutterDriverOptions extends BaseOptions implements + SupportsFlutterSystemPortOption, + SupportsFlutterServerLaunchTimeoutOption { + + public FlutterDriverOptions() { + setCommonOptions(); + } + + public FlutterDriverOptions(Capabilities source) { + super(source); + setCommonOptions(); + } + + public FlutterDriverOptions(Map source) { + super(source); + setCommonOptions(); + } + + private void setCommonOptions() { + setAutomationName(AutomationName.FLUTTER_INTEGRATION); + } +} diff --git a/src/main/java/io/appium/java_client/flutter/SupportsGestureOnFlutterElements.java b/src/main/java/io/appium/java_client/flutter/SupportsGestureOnFlutterElements.java new file mode 100644 index 000000000..7e80e8a97 --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/SupportsGestureOnFlutterElements.java @@ -0,0 +1,35 @@ +package io.appium.java_client.flutter; + +import io.appium.java_client.flutter.commands.DoubleClickParameter; +import io.appium.java_client.flutter.commands.DragAndDropParameter; +import io.appium.java_client.flutter.commands.LongPressParameter; + +public interface SupportsGestureOnFlutterElements extends CanExecuteFlutterScripts { + + /** + * Performs a double click action on an element. + * + * @param parameter The parameters for double-clicking, specifying element details. + */ + default void performDoubleClick(DoubleClickParameter parameter) { + executeFlutterCommand("doubleClick", parameter); + } + + /** + * Performs a long press action on an element. + * + * @param parameter The parameters for long pressing, specifying element details. + */ + default void performLongPress(LongPressParameter parameter) { + executeFlutterCommand("longPress", parameter); + } + + /** + * Performs a drag-and-drop action between two elements. + * + * @param parameter The parameters for drag-and-drop, specifying source and target elements. + */ + default void performDragAndDrop(DragAndDropParameter parameter) { + executeFlutterCommand("dragAndDrop", parameter); + } +} diff --git a/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java b/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java index f7be154ff..6afa21c45 100644 --- a/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java +++ b/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java @@ -2,8 +2,7 @@ import io.appium.java_client.AppiumClientConfig; import io.appium.java_client.android.AndroidDriver; -import io.appium.java_client.flutter.SupportsScrollingOfFlutterElements; -import io.appium.java_client.flutter.SupportsWaitingForFlutterElements; +import io.appium.java_client.flutter.FlutterDriver; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServiceBuilder; import org.openqa.selenium.Capabilities; @@ -16,9 +15,7 @@ /** * Custom AndroidDriver implementation with additional Flutter-specific capabilities. */ -public class FlutterAndroidDriver extends AndroidDriver implements - SupportsWaitingForFlutterElements, - SupportsScrollingOfFlutterElements { +public class FlutterAndroidDriver extends AndroidDriver implements FlutterDriver { public FlutterAndroidDriver(HttpCommandExecutor executor, Capabilities capabilities) { super(executor, capabilities); diff --git a/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java new file mode 100644 index 000000000..3c534ea80 --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java @@ -0,0 +1,31 @@ +package io.appium.java_client.flutter.commands; + +import com.google.common.base.Preconditions; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Accessors(chain = true) +@Setter +public class DoubleClickParameter extends FlutterCommandParameter { + private WebElement element; + private Point offset; + + @Override + public Map toJson() { + Preconditions.checkArgument(element != null || offset != null, + "Must supply a valid element or offset to perform flutter gesture event"); + + Map params = new HashMap<>(); + Optional.ofNullable(element).ifPresent(element -> params.put("origin", element)); + Optional.ofNullable(offset).ifPresent(offset -> + params.put("offset", Map.of("x", offset.getX(), "y", offset.getY()))); + return Collections.unmodifiableMap(params); + } +} \ No newline at end of file diff --git a/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java new file mode 100644 index 000000000..8c52e9b04 --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java @@ -0,0 +1,27 @@ +package io.appium.java_client.flutter.commands; + +import com.google.common.base.Preconditions; +import lombok.Getter; +import lombok.experimental.Accessors; +import org.openqa.selenium.WebElement; + +import java.util.Map; + +@Accessors(chain = true) +@Getter +public class DragAndDropParameter extends FlutterCommandParameter { + private final WebElement source; + private final WebElement target; + + public DragAndDropParameter(WebElement source, WebElement target) { + Preconditions.checkArgument(source != null && target != null, + "Must supply valid source and target element to perform drag and drop event"); + this.source = source; + this.target = target; + } + + @Override + public Map toJson() { + return Map.of("source", source, "target", target); + } +} \ No newline at end of file diff --git a/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java new file mode 100644 index 000000000..fb8f501ff --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java @@ -0,0 +1,31 @@ +package io.appium.java_client.flutter.commands; + +import com.google.common.base.Preconditions; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Accessors(chain = true) +@Setter +public class LongPressParameter extends FlutterCommandParameter { + private WebElement element; + private Point offset; + + @Override + public Map toJson() { + Preconditions.checkArgument(element != null || offset != null, + "Must supply a valid element or offset to perform flutter gesture event"); + + Map params = new HashMap<>(); + Optional.ofNullable(element).ifPresent(element -> params.put("origin", element)); + Optional.ofNullable(offset).ifPresent(offset -> + params.put("offset", Map.of("x", offset.getX(), "y", offset.getY()))); + return Collections.unmodifiableMap(params); + } +} \ No newline at end of file diff --git a/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java b/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java new file mode 100644 index 000000000..bc0ff6f7c --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java @@ -0,0 +1,69 @@ +package io.appium.java_client.flutter.ios; + +import io.appium.java_client.AppiumClientConfig; +import io.appium.java_client.flutter.FlutterDriver; +import io.appium.java_client.ios.IOSDriver; +import io.appium.java_client.service.local.AppiumDriverLocalService; +import io.appium.java_client.service.local.AppiumServiceBuilder; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.remote.HttpCommandExecutor; +import org.openqa.selenium.remote.http.ClientConfig; +import org.openqa.selenium.remote.http.HttpClient; + +import java.net.URL; + +/** + * Custom IOSDriver implementation with additional Flutter-specific capabilities. + */ +public class FlutterIOSDriver extends IOSDriver implements FlutterDriver { + + public FlutterIOSDriver(HttpCommandExecutor executor, Capabilities capabilities) { + super(executor, capabilities); + } + + public FlutterIOSDriver(URL remoteAddress, Capabilities capabilities) { + super(remoteAddress, capabilities); + } + + public FlutterIOSDriver(URL remoteAddress, HttpClient.Factory httpClientFactory, Capabilities capabilities) { + super(remoteAddress, httpClientFactory, capabilities); + } + + public FlutterIOSDriver(AppiumDriverLocalService service, Capabilities capabilities) { + super(service, capabilities); + } + + public FlutterIOSDriver( + AppiumDriverLocalService service, HttpClient.Factory httpClientFactory, Capabilities capabilities) { + super(service, httpClientFactory, capabilities); + } + + public FlutterIOSDriver(AppiumServiceBuilder builder, Capabilities capabilities) { + super(builder, capabilities); + } + + public FlutterIOSDriver( + AppiumServiceBuilder builder, HttpClient.Factory httpClientFactory, Capabilities capabilities) { + super(builder, httpClientFactory, capabilities); + } + + public FlutterIOSDriver(HttpClient.Factory httpClientFactory, Capabilities capabilities) { + super(httpClientFactory, capabilities); + } + + public FlutterIOSDriver(ClientConfig clientConfig, Capabilities capabilities) { + super(clientConfig, capabilities); + } + + public FlutterIOSDriver(AppiumClientConfig appiumClientConfig, Capabilities capabilities) { + super(appiumClientConfig, capabilities); + } + + public FlutterIOSDriver(URL remoteSessionAddress) { + super(remoteSessionAddress); + } + + public FlutterIOSDriver(Capabilities capabilities) { + super(capabilities); + } +} \ No newline at end of file diff --git a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterServerLaunchTimeoutOption.java b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterServerLaunchTimeoutOption.java new file mode 100644 index 000000000..52b51a8eb --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterServerLaunchTimeoutOption.java @@ -0,0 +1,36 @@ +package io.appium.java_client.flutter.options; + +import io.appium.java_client.internal.CapabilityHelpers; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +public interface SupportsFlutterServerLaunchTimeoutOption> extends + Capabilities, CanSetCapability { + String FLUTTER_SERVER_LAUNCH_TIMEOUT_OPTION = "flutterServerLaunchTimeout"; + + /** + * Timeout to wait for FlutterServer to be pingable, + * e.g. finishes building. Defaults to 60000ms. + * + * @param timeout Timeout to wait until FlutterServer is listening. + * @return self instance for chaining. + */ + default T setFlutterServerLaunchTimeout(Duration timeout) { + return amend(FLUTTER_SERVER_LAUNCH_TIMEOUT_OPTION, timeout.toMillis()); + } + + /** + * Get the maximum timeout to wait until FlutterServer is listening. + * + * @return Timeout value. + */ + default Optional getFlutterServerLaunchTimeout() { + return Optional.ofNullable( + CapabilityHelpers.toDuration(getCapability(FLUTTER_SERVER_LAUNCH_TIMEOUT_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java new file mode 100644 index 000000000..016f73347 --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java @@ -0,0 +1,33 @@ +package io.appium.java_client.flutter.options; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toInteger; + +public interface SupportsFlutterSystemPortOption> extends + Capabilities, CanSetCapability { + String FLUTTER_SYSTEM_PORT_OPTION = "flutterSystemPort"; + + /** + * Set the port where Flutter server starts. + * + * @param flutterSystemPort is the port number + * @return self instance for chaining. + */ + default T setFlutterSystemPort(Integer flutterSystemPort) { + return amend(FLUTTER_SYSTEM_PORT_OPTION, flutterSystemPort); + } + + /** + * Get the number of the port Flutter server starts on the system. + * + * @return Port number + */ + default Optional getFlutterSystemPort() { + return Optional.ofNullable(toInteger(getCapability(FLUTTER_SYSTEM_PORT_OPTION))); + } +} \ No newline at end of file From a5913ad46027f25d4e60d0ccae7654941011e34b Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 11:14:47 +0530 Subject: [PATCH 02/14] Checkstyle fixes --- .../appium/java_client/android/BaseFlutterTest.java | 2 -- .../io/appium/java_client/android/CommandTest.java | 6 +++--- .../flutter/commands/DoubleClickParameter.java | 3 ++- .../flutter/commands/DragAndDropParameter.java | 12 +++++++++--- .../flutter/commands/LongPressParameter.java | 2 +- .../flutter/commands/ScrollParameter.java | 1 - .../java_client/flutter/ios/FlutterIOSDriver.java | 2 +- .../options/SupportsFlutterSystemPortOption.java | 2 +- 8 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index f9d8f24e3..f79cb58b0 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -8,7 +8,6 @@ import io.appium.java_client.flutter.commands.ScrollParameter; import io.appium.java_client.flutter.ios.FlutterIOSDriver; import io.appium.java_client.ios.options.XCUITestOptions; -import io.appium.java_client.remote.AutomationName; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServiceBuilder; import org.junit.jupiter.api.AfterAll; @@ -61,7 +60,6 @@ public void startSession() throws MalformedURLException { driver = new FlutterAndroidDriver(service.getUrl(), options.merge(flutterOptions)); } else { XCUITestOptions options = new XCUITestOptions() - .setAutomationName(AutomationName.FLUTTER_INTEGRATION) .setApp(System.getProperty("flutterApp")) .eventTimings(); driver = new FlutterIOSDriver(service.getUrl(), options.merge(flutterOptions)); diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java index 30d513446..81f72e225 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java @@ -1,11 +1,11 @@ package io.appium.java_client.android; import io.appium.java_client.AppiumBy; -import io.appium.java_client.flutter.commands.ScrollParameter; -import io.appium.java_client.flutter.commands.WaitParameter; import io.appium.java_client.flutter.commands.DoubleClickParameter; -import io.appium.java_client.flutter.commands.LongPressParameter; import io.appium.java_client.flutter.commands.DragAndDropParameter; +import io.appium.java_client.flutter.commands.LongPressParameter; +import io.appium.java_client.flutter.commands.ScrollParameter; +import io.appium.java_client.flutter.commands.WaitParameter; import org.junit.jupiter.api.Test; import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; diff --git a/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java index 3c534ea80..cea14321c 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java @@ -17,6 +17,7 @@ public class DoubleClickParameter extends FlutterCommandParameter { private WebElement element; private Point offset; + @Override public Map toJson() { Preconditions.checkArgument(element != null || offset != null, @@ -28,4 +29,4 @@ public Map toJson() { params.put("offset", Map.of("x", offset.getX(), "y", offset.getY()))); return Collections.unmodifiableMap(params); } -} \ No newline at end of file +} diff --git a/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java index 8c52e9b04..ced55597a 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java @@ -1,18 +1,24 @@ package io.appium.java_client.flutter.commands; import com.google.common.base.Preconditions; -import lombok.Getter; import lombok.experimental.Accessors; import org.openqa.selenium.WebElement; import java.util.Map; @Accessors(chain = true) -@Getter public class DragAndDropParameter extends FlutterCommandParameter { private final WebElement source; private final WebElement target; + /** + * Constructs a new instance of {@code DragAndDropParameter} with the given source and target {@link WebElement}s. + * Throws an {@link IllegalArgumentException} if either {@code source} or {@code target} is {@code null}. + * + * @param source The source {@link WebElement} from which the drag operation starts. + * @param target The target {@link WebElement} where the drag operation ends. + * @throws IllegalArgumentException if {@code source} or {@code target} is {@code null}. + */ public DragAndDropParameter(WebElement source, WebElement target) { Preconditions.checkArgument(source != null && target != null, "Must supply valid source and target element to perform drag and drop event"); @@ -24,4 +30,4 @@ public DragAndDropParameter(WebElement source, WebElement target) { public Map toJson() { return Map.of("source", source, "target", target); } -} \ No newline at end of file +} diff --git a/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java index fb8f501ff..2cdcd4087 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java @@ -28,4 +28,4 @@ public Map toJson() { params.put("offset", Map.of("x", offset.getX(), "y", offset.getY()))); return Collections.unmodifiableMap(params); } -} \ No newline at end of file +} diff --git a/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java b/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java index 695cb060d..3010362d1 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java @@ -14,7 +14,6 @@ import java.util.Optional; @Accessors(chain = true) -@Getter @Setter public class ScrollParameter extends FlutterCommandParameter { private AppiumBy.FlutterBy scrollTo; diff --git a/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java b/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java index bc0ff6f7c..b46234f62 100644 --- a/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java +++ b/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java @@ -66,4 +66,4 @@ public FlutterIOSDriver(URL remoteSessionAddress) { public FlutterIOSDriver(Capabilities capabilities) { super(capabilities); } -} \ No newline at end of file +} diff --git a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java index 016f73347..06b0f3cac 100644 --- a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java +++ b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java @@ -30,4 +30,4 @@ default T setFlutterSystemPort(Integer flutterSystemPort) { default Optional getFlutterSystemPort() { return Optional.ofNullable(toInteger(getCapability(FLUTTER_SYSTEM_PORT_OPTION))); } -} \ No newline at end of file +} From 67ecf4dd808d5199497763e7da01d939fd0fe1bf Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 11:28:20 +0530 Subject: [PATCH 03/14] Install integration driver in CI --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 0c2040b71..303e34cc1 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -96,7 +96,7 @@ jobs: run: appium driver install uiautomator2 - name: Install Flutter Integration driver - if: matrix.e2e-tests == 'flutter-android' + if: matrix.e2e-tests == 'flutter-android' || matrix.e2e-tests == 'flutter-ios' run: appium driver install appium-flutter-integration-driver --source npm - name: Run Android E2E tests From 620f6e7a0c20447bb68e327dc317cdeae30a99da Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 12:49:20 +0530 Subject: [PATCH 04/14] Code review fixes --- .../java_client/android/BaseFlutterTest.java | 23 +++++++----- .../flutter/FlutterDriverOptions.java | 14 ++++++- .../commands/DoubleClickParameter.java | 4 +- .../commands/DragAndDropParameter.java | 2 + .../flutter/commands/LongPressParameter.java | 2 + .../flutter/commands/ScrollParameter.java | 1 + ...pportsFlutterElementWaitTimeoutOption.java | 37 +++++++++++++++++++ 7 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index f79cb58b0..da5a78563 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -51,18 +51,21 @@ public static void beforeClass() { public void startSession() throws MalformedURLException { FlutterDriverOptions flutterOptions = new FlutterDriverOptions() .setFlutterSystemPort(9999) - .setFlutterServerLaunchTimeout(Duration.ofSeconds(10)); - + .setFlutterServerLaunchTimeout(Duration.ofSeconds(30)) + .setFlutterElementWaitTimeout(Duration.ofSeconds(3)); if (IS_ANDROID) { - UiAutomator2Options options = new UiAutomator2Options() - .setApp(System.getProperty("flutterApp")) - .eventTimings(); - driver = new FlutterAndroidDriver(service.getUrl(), options.merge(flutterOptions)); + driver = new FlutterAndroidDriver(service.getUrl(), flutterOptions + .setUiAutomator2Options(new UiAutomator2Options() + .setApp(System.getProperty("flutterApp")) + .eventTimings())); } else { - XCUITestOptions options = new XCUITestOptions() - .setApp(System.getProperty("flutterApp")) - .eventTimings(); - driver = new FlutterIOSDriver(service.getUrl(), options.merge(flutterOptions)); + driver = new FlutterIOSDriver(service.getUrl(), flutterOptions + .setXCUITestOptions(new XCUITestOptions() + .setApp(System.getProperty("flutterApp")) + .setWdaLaunchTimeout(Duration.ofMinutes(2)) + .eventTimings() + ) + ); } } diff --git a/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java b/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java index b6c2e16f8..ed5c456d5 100644 --- a/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java +++ b/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java @@ -1,7 +1,10 @@ package io.appium.java_client.flutter; +import io.appium.java_client.android.options.UiAutomator2Options; +import io.appium.java_client.flutter.options.SupportsFlutterElementWaitTimeoutOption; import io.appium.java_client.flutter.options.SupportsFlutterServerLaunchTimeoutOption; import io.appium.java_client.flutter.options.SupportsFlutterSystemPortOption; +import io.appium.java_client.ios.options.XCUITestOptions; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.remote.options.BaseOptions; import org.openqa.selenium.Capabilities; @@ -13,7 +16,8 @@ */ public class FlutterDriverOptions extends BaseOptions implements SupportsFlutterSystemPortOption, - SupportsFlutterServerLaunchTimeoutOption { + SupportsFlutterServerLaunchTimeoutOption, + SupportsFlutterElementWaitTimeoutOption { public FlutterDriverOptions() { setCommonOptions(); @@ -29,6 +33,14 @@ public FlutterDriverOptions(Map source) { setCommonOptions(); } + public FlutterDriverOptions setUiAutomator2Options(UiAutomator2Options uiAutomator2Options) { + return merge(uiAutomator2Options); + } + + public FlutterDriverOptions setXCUITestOptions(XCUITestOptions xcuiTestOptions) { + return merge(xcuiTestOptions); + } + private void setCommonOptions() { setAutomationName(AutomationName.FLUTTER_INTEGRATION); } diff --git a/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java index cea14321c..bda8da206 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java @@ -1,6 +1,7 @@ package io.appium.java_client.flutter.commands; import com.google.common.base.Preconditions; +import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.openqa.selenium.Point; @@ -13,11 +14,12 @@ @Accessors(chain = true) @Setter +@Getter public class DoubleClickParameter extends FlutterCommandParameter { private WebElement element; private Point offset; - + @Override public Map toJson() { Preconditions.checkArgument(element != null || offset != null, diff --git a/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java index ced55597a..8946450e1 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java @@ -1,12 +1,14 @@ package io.appium.java_client.flutter.commands; import com.google.common.base.Preconditions; +import lombok.Getter; import lombok.experimental.Accessors; import org.openqa.selenium.WebElement; import java.util.Map; @Accessors(chain = true) +@Getter public class DragAndDropParameter extends FlutterCommandParameter { private final WebElement source; private final WebElement target; diff --git a/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java index 2cdcd4087..b82ba1ffa 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java @@ -1,6 +1,7 @@ package io.appium.java_client.flutter.commands; import com.google.common.base.Preconditions; +import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.openqa.selenium.Point; @@ -13,6 +14,7 @@ @Accessors(chain = true) @Setter +@Getter public class LongPressParameter extends FlutterCommandParameter { private WebElement element; private Point offset; diff --git a/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java b/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java index 3010362d1..b1942a9dc 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java @@ -15,6 +15,7 @@ @Accessors(chain = true) @Setter +@Getter public class ScrollParameter extends FlutterCommandParameter { private AppiumBy.FlutterBy scrollTo; private WebElement scrollView; diff --git a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java new file mode 100644 index 000000000..3369641b3 --- /dev/null +++ b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java @@ -0,0 +1,37 @@ +package io.appium.java_client.flutter.options; + +import io.appium.java_client.internal.CapabilityHelpers; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +public interface SupportsFlutterElementWaitTimeoutOption> extends + Capabilities, CanSetCapability { + String FLUTTER_ELEMENT_WAIT_TIMEOUT_OPTION = "flutterElementWaitTimeout"; + + /** + * Sets the Flutter element wait timeout. + * Defaults to 5 seconds. + * + * @param timeout The duration to wait for Flutter elements during findElement method + * @return self instance for chaining. + */ + default T setFlutterElementWaitTimeout(Duration timeout) { + return amend(FLUTTER_ELEMENT_WAIT_TIMEOUT_OPTION, timeout.toMillis()); + } + + /** + * Retrieves the current Flutter element wait timeout if set. + * + * @return An {@link Optional} containing the duration of the Flutter element wait timeout, + * or empty if not set + */ + default Optional getFlutterElementWaitTimeout() { + return Optional.ofNullable( + CapabilityHelpers.toDuration(getCapability(FLUTTER_ELEMENT_WAIT_TIMEOUT_OPTION)) + ); + } +} From 65e42ca1ba70fceeea0a79b9fb07bb09d6450f55 Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 12:55:54 +0530 Subject: [PATCH 05/14] Chekstyle fix --- .../options/SupportsFlutterElementWaitTimeoutOption.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java index 3369641b3..794c955d4 100644 --- a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java +++ b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterElementWaitTimeoutOption.java @@ -26,8 +26,7 @@ default T setFlutterElementWaitTimeout(Duration timeout) { /** * Retrieves the current Flutter element wait timeout if set. * - * @return An {@link Optional} containing the duration of the Flutter element wait timeout, - * or empty if not set + * @return An {@link Optional} containing the duration of the Flutter element wait timeout, or empty if not set. */ default Optional getFlutterElementWaitTimeout() { return Optional.ofNullable( From 9c47142fec3c4d6cd82958160d205b2d2062b8e7 Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 13:20:04 +0530 Subject: [PATCH 06/14] Chekstyle fix --- .../java/io/appium/java_client/android/BaseFlutterTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index da5a78563..d6bc36263 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -57,7 +57,8 @@ public void startSession() throws MalformedURLException { driver = new FlutterAndroidDriver(service.getUrl(), flutterOptions .setUiAutomator2Options(new UiAutomator2Options() .setApp(System.getProperty("flutterApp")) - .eventTimings())); + .eventTimings()) + ); } else { driver = new FlutterIOSDriver(service.getUrl(), flutterOptions .setXCUITestOptions(new XCUITestOptions() From 8040a15c405882b15f0960c03478fee8d93888ca Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 13:50:33 +0530 Subject: [PATCH 07/14] Empty commit to trigger workflow From 13f7e29d71104ea6774f31cebafcc0be41dccfdf Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 14:57:51 +0530 Subject: [PATCH 08/14] CR fixes 2 --- .../java_client/android/BaseFlutterTest.java | 4 ++-- .../flutter/FlutterDriverOptions.java | 18 +++++++++++------- ....java => FlutterIntegrationTestDriver.java} | 2 +- .../flutter/android/FlutterAndroidDriver.java | 4 ++-- .../flutter/ios/FlutterIOSDriver.java | 4 ++-- .../SupportsFlutterSystemPortOption.java | 2 +- 6 files changed, 19 insertions(+), 15 deletions(-) rename src/main/java/io/appium/java_client/flutter/{FlutterDriver.java => FlutterIntegrationTestDriver.java} (93%) diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index d6bc36263..4e1033024 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -2,8 +2,8 @@ import io.appium.java_client.AppiumBy; import io.appium.java_client.android.options.UiAutomator2Options; -import io.appium.java_client.flutter.FlutterDriver; import io.appium.java_client.flutter.FlutterDriverOptions; +import io.appium.java_client.flutter.FlutterIntegrationTestDriver; import io.appium.java_client.flutter.android.FlutterAndroidDriver; import io.appium.java_client.flutter.commands.ScrollParameter; import io.appium.java_client.flutter.ios.FlutterIOSDriver; @@ -32,7 +32,7 @@ class BaseFlutterTest { protected static final int PORT = 4723; private static AppiumDriverLocalService service; - protected static FlutterDriver driver; + protected static FlutterIntegrationTestDriver driver; protected static final By LOGIN_BUTTON = AppiumBy.flutterText("Login"); /** diff --git a/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java b/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java index ed5c456d5..e50b5d134 100644 --- a/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java +++ b/src/main/java/io/appium/java_client/flutter/FlutterDriverOptions.java @@ -20,28 +20,32 @@ public class FlutterDriverOptions extends BaseOptions impl SupportsFlutterElementWaitTimeoutOption { public FlutterDriverOptions() { - setCommonOptions(); + setDefaultOptions(); } public FlutterDriverOptions(Capabilities source) { super(source); - setCommonOptions(); + setDefaultOptions(); } public FlutterDriverOptions(Map source) { super(source); - setCommonOptions(); + setDefaultOptions(); } public FlutterDriverOptions setUiAutomator2Options(UiAutomator2Options uiAutomator2Options) { - return merge(uiAutomator2Options); + return setDefaultOptions(merge(uiAutomator2Options)); } public FlutterDriverOptions setXCUITestOptions(XCUITestOptions xcuiTestOptions) { - return merge(xcuiTestOptions); + return setDefaultOptions(merge(xcuiTestOptions)); } - private void setCommonOptions() { - setAutomationName(AutomationName.FLUTTER_INTEGRATION); + private void setDefaultOptions() { + setDefaultOptions(this); + } + + private FlutterDriverOptions setDefaultOptions(FlutterDriverOptions flutterDriverOptions) { + return flutterDriverOptions.setAutomationName(AutomationName.FLUTTER_INTEGRATION); } } diff --git a/src/main/java/io/appium/java_client/flutter/FlutterDriver.java b/src/main/java/io/appium/java_client/flutter/FlutterIntegrationTestDriver.java similarity index 93% rename from src/main/java/io/appium/java_client/flutter/FlutterDriver.java rename to src/main/java/io/appium/java_client/flutter/FlutterIntegrationTestDriver.java index 6dd3853e8..dce74507c 100644 --- a/src/main/java/io/appium/java_client/flutter/FlutterDriver.java +++ b/src/main/java/io/appium/java_client/flutter/FlutterIntegrationTestDriver.java @@ -15,7 +15,7 @@ * @see SupportsScrollingOfFlutterElements * @see SupportsWaitingForFlutterElements */ -public interface FlutterDriver extends +public interface FlutterIntegrationTestDriver extends WebDriver, SupportsGestureOnFlutterElements, SupportsScrollingOfFlutterElements, diff --git a/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java b/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java index 6afa21c45..8bbf45cbf 100644 --- a/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java +++ b/src/main/java/io/appium/java_client/flutter/android/FlutterAndroidDriver.java @@ -2,7 +2,7 @@ import io.appium.java_client.AppiumClientConfig; import io.appium.java_client.android.AndroidDriver; -import io.appium.java_client.flutter.FlutterDriver; +import io.appium.java_client.flutter.FlutterIntegrationTestDriver; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServiceBuilder; import org.openqa.selenium.Capabilities; @@ -15,7 +15,7 @@ /** * Custom AndroidDriver implementation with additional Flutter-specific capabilities. */ -public class FlutterAndroidDriver extends AndroidDriver implements FlutterDriver { +public class FlutterAndroidDriver extends AndroidDriver implements FlutterIntegrationTestDriver { public FlutterAndroidDriver(HttpCommandExecutor executor, Capabilities capabilities) { super(executor, capabilities); diff --git a/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java b/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java index b46234f62..2d8c9c991 100644 --- a/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java +++ b/src/main/java/io/appium/java_client/flutter/ios/FlutterIOSDriver.java @@ -1,7 +1,7 @@ package io.appium.java_client.flutter.ios; import io.appium.java_client.AppiumClientConfig; -import io.appium.java_client.flutter.FlutterDriver; +import io.appium.java_client.flutter.FlutterIntegrationTestDriver; import io.appium.java_client.ios.IOSDriver; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServiceBuilder; @@ -15,7 +15,7 @@ /** * Custom IOSDriver implementation with additional Flutter-specific capabilities. */ -public class FlutterIOSDriver extends IOSDriver implements FlutterDriver { +public class FlutterIOSDriver extends IOSDriver implements FlutterIntegrationTestDriver { public FlutterIOSDriver(HttpCommandExecutor executor, Capabilities capabilities) { super(executor, capabilities); diff --git a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java index 06b0f3cac..3f25ccec3 100644 --- a/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java +++ b/src/main/java/io/appium/java_client/flutter/options/SupportsFlutterSystemPortOption.java @@ -18,7 +18,7 @@ public interface SupportsFlutterSystemPortOption> exten * @param flutterSystemPort is the port number * @return self instance for chaining. */ - default T setFlutterSystemPort(Integer flutterSystemPort) { + default T setFlutterSystemPort(int flutterSystemPort) { return amend(FLUTTER_SYSTEM_PORT_OPTION, flutterSystemPort); } From ac174f6bc0e244714993313d705b3b754111af2a Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 15:55:16 +0530 Subject: [PATCH 09/14] ci fixes and remove guava reference --- .github/workflows/gradle.yml | 4 ++-- .../io/appium/java_client/android/BaseFlutterTest.java | 10 ++++++---- .../io/appium/java_client/android/CommandTest.java | 10 +++++----- .../io/appium/java_client/android/FinderTests.java | 10 +++++----- .../flutter/commands/DoubleClickParameter.java | 4 ++-- .../flutter/commands/DragAndDropParameter.java | 4 ++-- .../flutter/commands/LongPressParameter.java | 4 ++-- .../java_client/flutter/commands/ScrollParameter.java | 6 +++--- .../java_client/flutter/commands/WaitParameter.java | 4 ++-- 9 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 303e34cc1..fa895d9bb 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -82,13 +82,13 @@ jobs: ./gradlew clean build -PisCI -Pselenium.version=$latest_snapshot - name: Install Node.js - if: matrix.e2e-tests == 'android' || matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-android' || matrix.e2e-tests == 'flutter-ios' + if: ${{ matrix.e2e-tests }} uses: actions/setup-node@v4 with: node-version: 'lts/*' - name: Install Appium - if: matrix.e2e-tests == 'android' || matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-android' || matrix.e2e-tests == 'flutter-ios' + if: ${{ matrix.e2e-tests }} run: npm install --location=global appium - name: Install UIA2 driver diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index 4e1033024..37204e289 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -48,7 +48,7 @@ public static void beforeClass() { } @BeforeEach - public void startSession() throws MalformedURLException { + void startSession() throws MalformedURLException { FlutterDriverOptions flutterOptions = new FlutterDriverOptions() .setFlutterSystemPort(9999) .setFlutterServerLaunchTimeout(Duration.ofSeconds(30)) @@ -64,6 +64,8 @@ public void startSession() throws MalformedURLException { .setXCUITestOptions(new XCUITestOptions() .setApp(System.getProperty("flutterApp")) .setWdaLaunchTimeout(Duration.ofMinutes(2)) + .setNoReset(true) + .setFullReset(false) .eventTimings() ) ); @@ -71,20 +73,20 @@ public void startSession() throws MalformedURLException { } @AfterEach - public void stopSession() { + void stopSession() { if (driver != null) { driver.quit(); } } @AfterAll - public static void afterClass() { + static void afterClass() { if (service.isRunning()) { service.stop(); } } - public void openScreen(String screenTitle) { + void openScreen(String screenTitle) { ScrollParameter scrollOptions = new ScrollParameter( AppiumBy.flutterText(screenTitle), ScrollParameter.ScrollDirection.DOWN); WebElement element = driver.scrollTillVisible(scrollOptions); diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java index 81f72e225..efee1c74b 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/CommandTest.java @@ -20,7 +20,7 @@ class CommandTest extends BaseFlutterTest { private static final AppiumBy.FlutterBy TOGGLE_BUTTON = AppiumBy.flutterKey("toggle_button"); @Test - public void testWaitCommand() { + void testWaitCommand() { WebElement loginButton = driver.findElement(BaseFlutterTest.LOGIN_BUTTON); loginButton.click(); openScreen("Lazy Loading"); @@ -43,7 +43,7 @@ public void testWaitCommand() { } @Test - public void testScrollTillVisibleCommand() { + void testScrollTillVisibleCommand() { WebElement loginButton = driver.findElement(BaseFlutterTest.LOGIN_BUTTON); loginButton.click(); openScreen("Vertical Swiping"); @@ -64,7 +64,7 @@ public void testScrollTillVisibleCommand() { } @Test - public void testDoubleClickCommand() { + void testDoubleClickCommand() { driver.findElement(BaseFlutterTest.LOGIN_BUTTON).click(); openScreen("Double Tap"); @@ -89,7 +89,7 @@ public void testDoubleClickCommand() { } @Test - public void testLongPressCommand() { + void testLongPressCommand() { driver.findElement(BaseFlutterTest.LOGIN_BUTTON).click(); openScreen("Long Press"); @@ -103,7 +103,7 @@ public void testLongPressCommand() { } @Test - public void testDragAndDropCommand() { + void testDragAndDropCommand() { driver.findElement(BaseFlutterTest.LOGIN_BUTTON).click(); openScreen("Drag & Drop"); diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/FinderTests.java b/src/e2eFlutterTest/java/io/appium/java_client/android/FinderTests.java index dc2361869..e8f78e414 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/FinderTests.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/FinderTests.java @@ -10,7 +10,7 @@ class FinderTests extends BaseFlutterTest { @Test - public void testFlutterByKey() { + void testFlutterByKey() { WebElement userNameField = driver.findElement(AppiumBy.flutterKey("username_text_field")); assertEquals("admin", userNameField.getText()); userNameField.clear(); @@ -19,13 +19,13 @@ public void testFlutterByKey() { } @Test - public void testFlutterByType() { + void testFlutterByType() { WebElement loginButton = driver.findElement(AppiumBy.flutterType("ElevatedButton")); assertEquals(loginButton.findElement(AppiumBy.flutterType("Text")).getText(), "Login"); } @Test - public void testFlutterText() { + void testFlutterText() { WebElement loginButton = driver.findElement(AppiumBy.flutterText("Login")); assertEquals(loginButton.getText(), "Login"); loginButton.click(); @@ -34,7 +34,7 @@ public void testFlutterText() { } @Test - public void testFlutterTextContaining() { + void testFlutterTextContaining() { WebElement loginButton = driver.findElement(BaseFlutterTest.LOGIN_BUTTON); loginButton.click(); assertEquals(driver.findElement(AppiumBy.flutterTextContaining("Vertical")).getText(), @@ -42,7 +42,7 @@ public void testFlutterTextContaining() { } @Test - public void testFlutterSemanticsLabel() { + void testFlutterSemanticsLabel() { WebElement loginButton = driver.findElement(BaseFlutterTest.LOGIN_BUTTON); loginButton.click(); openScreen("Lazy Loading"); diff --git a/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java index bda8da206..859f26057 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/DoubleClickParameter.java @@ -1,11 +1,11 @@ package io.appium.java_client.flutter.commands; -import com.google.common.base.Preconditions; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.Require; import java.util.Collections; import java.util.HashMap; @@ -22,7 +22,7 @@ public class DoubleClickParameter extends FlutterCommandParameter { @Override public Map toJson() { - Preconditions.checkArgument(element != null || offset != null, + Require.precondition(element != null || offset != null, "Must supply a valid element or offset to perform flutter gesture event"); Map params = new HashMap<>(); diff --git a/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java index 8946450e1..14bc04cbf 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/DragAndDropParameter.java @@ -1,9 +1,9 @@ package io.appium.java_client.flutter.commands; -import com.google.common.base.Preconditions; import lombok.Getter; import lombok.experimental.Accessors; import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.Require; import java.util.Map; @@ -22,7 +22,7 @@ public class DragAndDropParameter extends FlutterCommandParameter { * @throws IllegalArgumentException if {@code source} or {@code target} is {@code null}. */ public DragAndDropParameter(WebElement source, WebElement target) { - Preconditions.checkArgument(source != null && target != null, + Require.precondition(source != null && target != null, "Must supply valid source and target element to perform drag and drop event"); this.source = source; this.target = target; diff --git a/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java index b82ba1ffa..36f80772d 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/LongPressParameter.java @@ -1,11 +1,11 @@ package io.appium.java_client.flutter.commands; -import com.google.common.base.Preconditions; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.Require; import java.util.Collections; import java.util.HashMap; @@ -21,7 +21,7 @@ public class LongPressParameter extends FlutterCommandParameter { @Override public Map toJson() { - Preconditions.checkArgument(element != null || offset != null, + Require.precondition(element != null || offset != null, "Must supply a valid element or offset to perform flutter gesture event"); Map params = new HashMap<>(); diff --git a/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java b/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java index b1942a9dc..773ece810 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/ScrollParameter.java @@ -1,11 +1,11 @@ package io.appium.java_client.flutter.commands; -import com.google.common.base.Preconditions; import io.appium.java_client.AppiumBy; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.Require; import java.time.Duration; import java.util.Collections; @@ -14,8 +14,8 @@ import java.util.Optional; @Accessors(chain = true) -@Setter @Getter +@Setter public class ScrollParameter extends FlutterCommandParameter { private AppiumBy.FlutterBy scrollTo; private WebElement scrollView; @@ -45,7 +45,7 @@ public ScrollParameter(AppiumBy.FlutterBy scrollTo) { * @throws IllegalArgumentException if scrollTo is null */ public ScrollParameter(AppiumBy.FlutterBy scrollTo, ScrollDirection scrollDirection) { - Preconditions.checkArgument(scrollTo != null, "Must supply a valid locator for scrollTo"); + Require.precondition(scrollTo != null, "Must supply a valid locator for scrollTo"); this.scrollTo = scrollTo; this.scrollDirection = scrollDirection; } diff --git a/src/main/java/io/appium/java_client/flutter/commands/WaitParameter.java b/src/main/java/io/appium/java_client/flutter/commands/WaitParameter.java index 89e0a19cf..d9f057032 100644 --- a/src/main/java/io/appium/java_client/flutter/commands/WaitParameter.java +++ b/src/main/java/io/appium/java_client/flutter/commands/WaitParameter.java @@ -1,11 +1,11 @@ package io.appium.java_client.flutter.commands; -import com.google.common.base.Preconditions; import io.appium.java_client.AppiumBy; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.Require; import java.time.Duration; import java.util.Collections; @@ -23,7 +23,7 @@ public class WaitParameter extends FlutterCommandParameter { @Override public Map toJson() { - Preconditions.checkArgument(element != null || locator != null, + Require.precondition(element != null || locator != null, "Must supply a valid element or locator to wait for"); Map params = new HashMap<>(); Optional.ofNullable(element) From a19bd1debfd5824ed3761967c354c1ec67a1cc89 Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 18:45:56 +0530 Subject: [PATCH 10/14] Fix selenium version --- .github/workflows/gradle.yml | 11 ++++++----- .../appium/java_client/android/BaseFlutterTest.java | 13 +++++++++++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index fa895d9bb..3c005ef7b 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -75,11 +75,12 @@ jobs: - name: Build with Gradle run: | - latest_snapshot=$(curl -sf https://oss.sonatype.org/content/repositories/snapshots/org/seleniumhq/selenium/selenium-api/ | \ - python -c "import sys,re; print(re.findall(r'\d+\.\d+\.\d+-SNAPSHOT', sys.stdin.read())[-1])") - echo ">>> $latest_snapshot" - echo "latest_snapshot=$latest_snapshot" >> "$GITHUB_ENV" - ./gradlew clean build -PisCI -Pselenium.version=$latest_snapshot + # latest_snapshot=$(curl -sf https://oss.sonatype.org/content/repositories/snapshots/org/seleniumhq/selenium/selenium-api/ | \ + # python -c "import sys,re; print(re.findall(r'\d+\.\d+\.\d+-SNAPSHOT', sys.stdin.read())[-1])") + latest_snapshot=4.24.0-SNAPSHOT + echo ">>> $latest_snapshot" + echo "latest_snapshot=$latest_snapshot" >> "$GITHUB_ENV" + ./gradlew clean build -PisCI -Pselenium.version=$latest_snapshot - name: Install Node.js if: ${{ matrix.e2e-tests }} diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index 37204e289..266f6a512 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -50,20 +50,29 @@ public static void beforeClass() { @BeforeEach void startSession() throws MalformedURLException { FlutterDriverOptions flutterOptions = new FlutterDriverOptions() - .setFlutterSystemPort(9999) .setFlutterServerLaunchTimeout(Duration.ofSeconds(30)) .setFlutterElementWaitTimeout(Duration.ofSeconds(3)); if (IS_ANDROID) { driver = new FlutterAndroidDriver(service.getUrl(), flutterOptions + .setFlutterSystemPort(9999) .setUiAutomator2Options(new UiAutomator2Options() .setApp(System.getProperty("flutterApp")) .eventTimings()) ); } else { + String deviceName = System.getenv("IOS_DEVICE_NAME") != null + ? System.getenv("IOS_DEVICE_NAME") + : "iPhone 12"; + String platformVersion = System.getenv("IOS_PLATFORM_VERSION") != null + ? System.getenv("IOS_PLATFORM_VERSION") + : "14.5"; driver = new FlutterIOSDriver(service.getUrl(), flutterOptions .setXCUITestOptions(new XCUITestOptions() .setApp(System.getProperty("flutterApp")) - .setWdaLaunchTimeout(Duration.ofMinutes(2)) + .setDeviceName(deviceName) + .setPlatformVersion(platformVersion) + .setWdaLaunchTimeout(Duration.ofMinutes(4)) + .setSimulatorStartupTimeout(Duration.ofMinutes(5)) .setNoReset(true) .setFullReset(false) .eventTimings() From a7316684775648d7bf1dc94b2501c1fb396fbf3e Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 19:44:18 +0530 Subject: [PATCH 11/14] Revert timeout --- .../java/io/appium/java_client/android/BaseFlutterTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index 266f6a512..e1e42aa24 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -73,8 +73,6 @@ void startSession() throws MalformedURLException { .setPlatformVersion(platformVersion) .setWdaLaunchTimeout(Duration.ofMinutes(4)) .setSimulatorStartupTimeout(Duration.ofMinutes(5)) - .setNoReset(true) - .setFullReset(false) .eventTimings() ) ); From 145bc4f7221b2dc0d5e1fdfd581cd8d7f6715a2e Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 20:10:26 +0530 Subject: [PATCH 12/14] Add flutter system port --- .../java/io/appium/java_client/android/BaseFlutterTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index e1e42aa24..2273ad91c 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -50,11 +50,11 @@ public static void beforeClass() { @BeforeEach void startSession() throws MalformedURLException { FlutterDriverOptions flutterOptions = new FlutterDriverOptions() - .setFlutterServerLaunchTimeout(Duration.ofSeconds(30)) + .setFlutterServerLaunchTimeout(Duration.ofMinutes(2)) + .setFlutterSystemPort(9999) .setFlutterElementWaitTimeout(Duration.ofSeconds(3)); if (IS_ANDROID) { driver = new FlutterAndroidDriver(service.getUrl(), flutterOptions - .setFlutterSystemPort(9999) .setUiAutomator2Options(new UiAutomator2Options() .setApp(System.getProperty("flutterApp")) .eventTimings()) From 6c90326273962175f5737d327726960f22e714bc Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 21:14:04 +0530 Subject: [PATCH 13/14] Revert selenium version --- .github/workflows/gradle.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 3c005ef7b..93527e84a 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -75,12 +75,11 @@ jobs: - name: Build with Gradle run: | - # latest_snapshot=$(curl -sf https://oss.sonatype.org/content/repositories/snapshots/org/seleniumhq/selenium/selenium-api/ | \ - # python -c "import sys,re; print(re.findall(r'\d+\.\d+\.\d+-SNAPSHOT', sys.stdin.read())[-1])") - latest_snapshot=4.24.0-SNAPSHOT - echo ">>> $latest_snapshot" - echo "latest_snapshot=$latest_snapshot" >> "$GITHUB_ENV" - ./gradlew clean build -PisCI -Pselenium.version=$latest_snapshot + latest_snapshot=$(curl -sf https://oss.sonatype.org/content/repositories/snapshots/org/seleniumhq/selenium/selenium-api/ | \ + python -c "import sys,re; print(re.findall(r'\d+\.\d+\.\d+-SNAPSHOT', sys.stdin.read())[-1])") + echo ">>> $latest_snapshot" + echo "latest_snapshot=$latest_snapshot" >> "$GITHUB_ENV" + ./gradlew clean build -PisCI -Pselenium.version=$latest_snapshot - name: Install Node.js if: ${{ matrix.e2e-tests }} From 963ca29c6d0161cb5ace5bdb5fcff91e801e37d5 Mon Sep 17 00:00:00 2001 From: Sudharsan Selvaraj Date: Tue, 23 Jul 2024 22:05:00 +0530 Subject: [PATCH 14/14] Increase default element wait timeout --- .../java/io/appium/java_client/android/BaseFlutterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index 2273ad91c..b2dc6f1eb 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -52,7 +52,7 @@ void startSession() throws MalformedURLException { FlutterDriverOptions flutterOptions = new FlutterDriverOptions() .setFlutterServerLaunchTimeout(Duration.ofMinutes(2)) .setFlutterSystemPort(9999) - .setFlutterElementWaitTimeout(Duration.ofSeconds(3)); + .setFlutterElementWaitTimeout(Duration.ofSeconds(10)); if (IS_ANDROID) { driver = new FlutterAndroidDriver(service.getUrl(), flutterOptions .setUiAutomator2Options(new UiAutomator2Options()