getAbout() {
- Response response = this.getBuilder("/applications", SeeTestApis.PM).get();
- if (response.getStatus() != Response.Status.OK.getStatusCode()) {
- log().debug("No SeeTest host found. (Response status {})", response.getStatus());
- return Optional.empty();
- }
+ try {
+ Response response = this.getBuilder("/applications", SeeTestApis.PM).get();
+ if (response.getStatus() != Response.Status.OK.getStatusCode()) {
+ log().debug("No SeeTest host found. (Response status {})", response.getStatus());
+ return Optional.empty();
+ }
- Gson gson = new Gson();
- JsonArray jsonArray = gson.fromJson(response.readEntity(String.class), JsonArray.class);
- if (jsonArray.isJsonArray()) {
- return Optional.of(jsonArray);
- } else {
- log().debug("Cannot read about response: {}", response.readEntity(String.class));
+ Gson gson = new Gson();
+ JsonArray jsonArray = gson.fromJson(response.readEntity(String.class), JsonArray.class);
+ if (jsonArray.isJsonArray()) {
+ return Optional.of(jsonArray);
+ } else {
+ log().debug("Cannot read about response: {}", response.readEntity(String.class));
+ return Optional.empty();
+ }
+ } catch (Exception e) {
+ log().warn("Cannot get information from SeeTest server");
return Optional.empty();
}
+
}
private Invocation.Builder getBuilder(String path, SeeTestApis api) {
diff --git a/appium/build.gradle b/appium/build.gradle
index bf20960e..3569e6d2 100644
--- a/appium/build.gradle
+++ b/appium/build.gradle
@@ -5,7 +5,11 @@ dependencies {
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'org.apache.commons:commons-lang3:3.12.0'
+ // For AppiumClassFinder
+ implementation 'org.reflections:reflections:0.9.12'
+
testImplementation 'io.testerra:driver-ui:' + testerraTestVersion
+// testImplementation 'io.testerra:driver-ui'
testImplementation 'io.testerra:report-ng:' + testerraTestVersion
testImplementation 'io.appium:java-client:7.3.0'
}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumContext.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumContext.java
new file mode 100644
index 00000000..237978b1
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumContext.java
@@ -0,0 +1,51 @@
+/*
+ * Testerra
+ *
+ * (C) 2022, Daniel Eckardt, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.appium;
+
+import io.appium.java_client.AppiumDriver;
+
+/**
+ * Created on 2023-03-27
+ *
+ * @author mgn
+ */
+public enum AppiumContext {
+
+ /**
+ * The context ({@link AppiumDriver#getContext()}) of the current view of the application is an operating system native.
+ */
+ NATIVE_APP,
+ /**
+ * The context ({@link AppiumDriver#getContext()}) of the current view of the application is a (embedded) browser. {@see
+ * http://appium.io/docs/en/writing-running-appium/web/hybrid/index.html}
+ */
+ WEBVIEW;
+
+ public static AppiumContext parse(String string) {
+ // there's only two NATIVE_APP contexts (NATIVE_APP and NATIVE_APP_INSTRUMENTED),
+ // but an infinite amount of WEBVIEW contexts, like WEBVIEW, SAFARI, CHROMIUM, WEBVIEW_1, WEBVIEW_2 etc.
+ // that's why we just assume that any context starting with NATIVE_APP is native and the rest WEBVIEW:
+ AppiumContext result = string == null || string.toLowerCase().startsWith("native_app") ? NATIVE_APP : WEBVIEW;
+// LOGGER.debug(String.format("Parsed %s as %s", string, result));
+ return result;
+ }
+
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/Browsers.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/Browsers.java
index 026c1f18..155d710b 100644
--- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/Browsers.java
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/Browsers.java
@@ -25,7 +25,9 @@
* A list ob supported browsers
*/
public class Browsers {
- public static final String windows ="windows";
+ public static final String windows = "windows";
public static final String mobile_chrome = "mobile_chrome";
public static final String mobile_safari = "mobile_safari";
+ // Default value for AppiumDriverRequest
+ public static final String mobile = "mobile";
}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java
index a1d3660a..4735a69a 100644
--- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java
@@ -25,13 +25,14 @@
import com.google.inject.Scopes;
import com.google.inject.multibindings.Multibinder;
import eu.tsystems.mms.tic.testframework.appium.WinAppDriverFactory;
-import eu.tsystems.mms.tic.testframework.hooks.ModuleHook;
import eu.tsystems.mms.tic.testframework.mobile.driver.AppiumDriverFactory;
+import eu.tsystems.mms.tic.testframework.utils.AppiumExecutionUtils;
+import eu.tsystems.mms.tic.testframework.utils.ExecutionUtils;
import eu.tsystems.mms.tic.testframework.webdriver.WebDriverFactory;
/**
* Add AppiumDriverFactory and WinAppDriverFactory
- *
+ *
* Date: 24.06.2020
* Time: 10:29
*
@@ -44,5 +45,6 @@ protected void configure() {
Multibinder webDriverFactoryBinder = Multibinder.newSetBinder(binder(), WebDriverFactory.class);
webDriverFactoryBinder.addBinding().to(AppiumDriverFactory.class).in(Scopes.SINGLETON);
webDriverFactoryBinder.addBinding().to(WinAppDriverFactory.class).in(Scopes.SINGLETON);
+ bind(ExecutionUtils.class).to(AppiumExecutionUtils.class).in(Scopes.SINGLETON);
}
}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/AppiumPage.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/AppiumPage.java
new file mode 100644
index 00000000..59a5593f
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/AppiumPage.java
@@ -0,0 +1,54 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.mobile;
+
+import eu.tsystems.mms.tic.testframework.mobile.guielement.CreateAppiumGuiElementAction;
+import eu.tsystems.mms.tic.testframework.pageobjects.Page;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.AbstractPage;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.action.AbstractFieldAction;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.action.SetNameFieldAction;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.WebDriver;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Created on 2023-02-09
+ *
+ * @author mgn
+ */
+public class AppiumPage extends Page {
+
+ public AppiumPage(WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ @Override
+ protected Optional> addCustomFieldActions(Field field, AbstractPage declaringPage) {
+ log().info("Custom field action");
+ CreateAppiumGuiElementAction action = new CreateAppiumGuiElementAction(field, declaringPage);
+ SetNameFieldAction nameFieldAction = new SetNameFieldAction(field, declaringPage);
+ return Optional.of(List.of(action, nameFieldAction));
+ }
+
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java
index fa6b911e..dfa46b89 100644
--- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java
@@ -42,6 +42,7 @@
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.MobileBrowserType;
import org.apache.commons.lang3.StringUtils;
+import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.events.EventFiringWebDriver;
@@ -93,6 +94,17 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques
}
}
+ switch (webDriverRequest.getBrowser()) {
+ case Browsers.mobile_chrome:
+ requestCapabilities.setBrowserName(MobileBrowserType.CHROME);
+ break;
+ case Browsers.mobile_safari:
+ requestCapabilities.setBrowserName(MobileBrowserType.SAFARI);
+ break;
+ default:
+ log().info("No mobile browser requested.");
+ }
+
return finalRequest;
}
@@ -117,26 +129,38 @@ private WebDriver startNewAppiumSession(WebDriverRequest webDriverRequest, Sessi
IExecutionContextController executionContextController = Testerra.getInjector().getInstance(IExecutionContextController.class);
DefaultCapabilityUtils utils = new DefaultCapabilityUtils();
+ // TODO: Move to prepareWebDriverRequest
utils.putIfAbsent(finalCapabilities, AppiumDriverRequest.CAPABILITY_NAME_TEST_NAME, executionContextController.getExecutionContext().getRunConfig().getReportName());
AppiumDriver appiumDriver = null;
- switch (webDriverRequest.getBrowser()) {
- case Browsers.mobile_safari: {
- finalCapabilities.setBrowserName(MobileBrowserType.SAFARI);
+ Platform mobilePlatform = new MobileOsChecker().getPlatform(webDriverRequest);
+ switch (mobilePlatform) {
+ case IOS:
appiumDriver = new IOSDriver<>(appiumUrl, finalCapabilities);
break;
- }
- case Browsers.mobile_chrome: {
- finalCapabilities.setBrowserName(MobileBrowserType.CHROME);
+ case ANDROID:
appiumDriver = new AndroidDriver<>(appiumUrl, finalCapabilities);
break;
- }
}
+
+// switch (webDriverRequest.getBrowser()) {
+// case Browsers.mobile_safari: {
+// finalCapabilities.setBrowserName(MobileBrowserType.SAFARI);
+// appiumDriver = new IOSDriver<>(appiumUrl, finalCapabilities);
+// break;
+// }
+// case Browsers.mobile_chrome: {
+// finalCapabilities.setBrowserName(MobileBrowserType.CHROME);
+// appiumDriver = new AndroidDriver<>(appiumUrl, finalCapabilities);
+// break;
+// }
+// }
if (appiumDriver != null) {
AppiumDeviceQuery appiumDeviceQuery = new AppiumDeviceQuery(appiumDriver.getCapabilities());
sessionContext.setActualBrowserName(appiumDeviceQuery.toString());
} else {
- throw new RuntimeException("Mobile Browser not supported: " + webDriverRequest.getBrowser());
+ throw new RuntimeException("Cannot create new Appium session - ambiguous capabilities found:\n " + finalCapabilities.toString());
+// throw new RuntimeException("Mobile Browser not supported: " + webDriverRequest.getBrowser());
}
return appiumDriver;
}
@@ -149,19 +173,23 @@ public void setupNewWebDriverSession(EventFiringWebDriver webDriver, SessionCont
.unwrapWebDriver(webDriver, AppiumDriver.class)
.ifPresent(driver -> driverString.set(driver.getClass().toString()));
- appiumDriverRequest.getBaseUrl().ifPresent(url -> {
- log().info("Open {} on {}", url, driverString.get());
- webDriver.get(url.toString());
- });
+ // In case of app automation it es not possible to call a URL
+ if (StringUtils.isNotBlank(appiumDriverRequest.getDesiredCapabilities().getBrowserName())) {
+ appiumDriverRequest.getBaseUrl().ifPresent(url -> {
+ log().info("Open {} on {}", url, driverString.get());
+ webDriver.get(url.toString());
+ });
+ }
}
@Override
public List getSupportedBrowsers() {
- return Arrays.asList(Browsers.mobile_chrome, Browsers.mobile_safari);
+ return Arrays.asList(Browsers.mobile_chrome, Browsers.mobile_safari, Browsers.mobile);
}
@Override
public GuiElementCore createCore(GuiElementData guiElementData) {
return new AppiumGuiElementCoreAdapter(guiElementData);
}
+
}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverManager.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverManager.java
deleted file mode 100644
index 5b932273..00000000
--- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverManager.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Testerra
- *
- * (C) 2020, Eric Kubenka, T-Systems Multimedia Solutions GmbH, Deutsche Telekom AG
- *
- * Deutsche Telekom AG and all other contributors /
- * copyright owners license this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this
- * file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-package eu.tsystems.mms.tic.testframework.mobile.driver;
-
-import eu.tsystems.mms.tic.testframework.webdrivermanager.IWebDriverManager;
-import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverProxy;
-import io.appium.java_client.AppiumDriver;
-import io.appium.java_client.MobileElement;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.support.events.EventFiringWebDriver;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-/**
- * Date: 08.09.2020
- * Time: 11:43
- *
- * @author Eric Kubenka
- * @deprecated Use {@link IWebDriverManager#unwrapWebDriver(WebDriver, Class)} instead
- */
-public class AppiumDriverManager {
-
- /**
- * Returns an {@link AppiumDriver}
- *
- * @param driver {@link WebDriver}
- * @return AppiumDriver
- */
- public AppiumDriver fromWebDriver(WebDriver driver) {
-
- final WebDriver rawDriver = ((EventFiringWebDriver) driver).getWrappedDriver();
- final InvocationHandler invocationHandler = Proxy.getInvocationHandler(rawDriver);
- final WebDriver rawAppiumDriver = ((WebDriverProxy) invocationHandler).getWrappedWebDriver();
-
- return (AppiumDriver) rawAppiumDriver;
- }
-}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java
new file mode 100644
index 00000000..52e3746d
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java
@@ -0,0 +1,76 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.mobile.driver;
+
+import eu.tsystems.mms.tic.testframework.appium.Browsers;
+import eu.tsystems.mms.tic.testframework.common.Testerra;
+import eu.tsystems.mms.tic.testframework.report.model.context.SessionContext;
+import eu.tsystems.mms.tic.testframework.webdrivermanager.IWebDriverManager;
+import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverRequest;
+import io.appium.java_client.remote.AndroidMobileCapabilityType;
+import io.appium.java_client.remote.IOSMobileCapabilityType;
+import io.appium.java_client.remote.MobileCapabilityType;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.WebDriver;
+
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Created on 2023-03-02
+ *
+ * @author mgn
+ */
+public class MobileOsChecker {
+
+ public Platform getPlatform(WebDriverRequest webDriverRequest) {
+ Map capabilities = webDriverRequest.getCapabilities();
+ if (webDriverRequest.getBrowser().equals(Browsers.mobile_chrome)
+ || "Espresso".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME))
+ || "UiAutomator2".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME))
+ || "UiAutomator".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME))
+ || capabilities.containsKey(AndroidMobileCapabilityType.APP_PACKAGE)
+ || capabilities.containsKey(AndroidMobileCapabilityType.APP_ACTIVITY)
+ ) {
+ return Platform.ANDROID;
+ }
+ if (webDriverRequest.getBrowser().equals(Browsers.mobile_safari)
+ || "XCUITest".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME))
+ || "UIAutomation".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME))
+ || capabilities.containsKey(IOSMobileCapabilityType.BUNDLE_ID)
+ ) {
+ return Platform.IOS;
+ }
+
+ return Platform.ANY;
+ }
+
+ public Platform getPlatform(WebDriver driver) {
+ IWebDriverManager instance = Testerra.getInjector().getInstance(IWebDriverManager.class);
+ Optional optional = instance.getSessionContext(driver).map(SessionContext::getWebDriverRequest);
+ if (optional.isPresent()) {
+ return getPlatform(optional.get());
+ } else {
+ return Platform.ANY;
+ }
+ }
+
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java
index 6e199216..f35b61e7 100644
--- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java
@@ -22,12 +22,14 @@
package eu.tsystems.mms.tic.testframework.mobile.guielement;
+import eu.tsystems.mms.tic.testframework.common.Testerra;
import eu.tsystems.mms.tic.testframework.logging.Loggable;
import eu.tsystems.mms.tic.testframework.pageobjects.GuiElement;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.AbstractWebDriverCore;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementCore;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementData;
import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider;
+import eu.tsystems.mms.tic.testframework.utils.ExecutionUtils;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.TouchAction;
import io.appium.java_client.touch.LongPressOptions;
@@ -40,6 +42,8 @@
import java.time.Duration;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+import java.util.function.Supplier;
/**
* Implements {@link GuiElementCore} to fullfill Testerra {@link GuiElement} functionality.
@@ -52,6 +56,8 @@ public class AppiumGuiElementCoreAdapter extends AbstractWebDriverCore implement
private AppiumDriver appiumDriver;
+ private ExecutionUtils executionUtils = Testerra.getInjector().getInstance(ExecutionUtils.class);
+
public AppiumGuiElementCoreAdapter(GuiElementData guiElementData) {
super(guiElementData);
appiumDriver = WEB_DRIVER_MANAGER.unwrapWebDriver(this.guiElementData.getWebDriver(), AppiumDriver.class).orElseThrow();
@@ -147,9 +153,16 @@ public boolean isVisible(boolean complete) {
public boolean isSelected() {
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
this.findWebElement(webElement -> {
- final String checked = webElement.getAttribute("checked");
final String selected = webElement.getAttribute("selected");
- atomicBoolean.set(checked.equalsIgnoreCase("true") || selected.equalsIgnoreCase("true"));
+// final String text = webElement.getText();
+ String value = executionUtils.getFailsafe(() -> webElement.getAttribute("value")).orElse("");
+ String checked = executionUtils.getFailsafe(() -> webElement.getAttribute("checked")).orElse("");
+
+ atomicBoolean.set(
+ "true".equalsIgnoreCase(checked)
+ || "true".equalsIgnoreCase(selected)
+ || "1".equals(value)
+ );
});
return atomicBoolean.get();
}
@@ -160,4 +173,42 @@ public boolean isSelectable() {
throw new MobileActionNotSupportedException("isSelectable() is not supported on mobile elements");
}
+
+ /**
+ * Appium on apps does not support webElement.getAttribute("value"), but webElement.getText() is working
+ */
+ @Override
+ public void type(String text) {
+ if (text == null) {
+ log().warn("Text to type is null. Typing nothing.");
+ return;
+ }
+ if (text.isEmpty()) {
+ log().warn("Text to type is empty!");
+ }
+
+ findWebElement(webElement -> {
+ webElement.clear();
+ webElement.sendKeys(text);
+
+// String valueProperty = webElement.getAttribute("value");
+ String valueProperty = webElement.getText();
+ if (valueProperty != null) {
+ if (!valueProperty.equals(text)) {
+ log().warn("Writing text to input field didn't work. Trying again.");
+
+ webElement.clear();
+ webElement.sendKeys(text);
+
+// if (!webElement.getAttribute("value").equals(text)) {
+ if (!webElement.getText().equals(text)) {
+ log().error("Writing text to input field didn't work on second try!");
+ }
+ }
+ } else {
+ log().warn("Cannot perform value check after type() because " + this.toString() +
+ " doesn't have a value property. Consider using sendKeys() instead.");
+ }
+ });
+ }
}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java
new file mode 100644
index 00000000..cb794f34
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java
@@ -0,0 +1,120 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.mobile.guielement;
+
+import eu.tsystems.mms.tic.testframework.common.Testerra;
+import eu.tsystems.mms.tic.testframework.internal.NameableChild;
+import eu.tsystems.mms.tic.testframework.logging.Loggable;
+import eu.tsystems.mms.tic.testframework.mobile.driver.MobileOsChecker;
+import eu.tsystems.mms.tic.testframework.pageobjects.UiElement;
+import eu.tsystems.mms.tic.testframework.pageobjects.UiElementFinder;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.AbstractPage;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.action.AbstractFieldAction;
+import eu.tsystems.mms.tic.testframework.report.model.context.SessionContext;
+import eu.tsystems.mms.tic.testframework.testing.UiElementFinderFactoryProvider;
+import eu.tsystems.mms.tic.testframework.webdrivermanager.IWebDriverManager;
+import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverRequest;
+import io.appium.java_client.pagefactory.DefaultElementByBuilder;
+import io.appium.java_client.remote.MobileCapabilityType;
+import org.apache.commons.lang3.StringUtils;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.WebDriver;
+
+import java.lang.reflect.Field;
+import java.util.Optional;
+
+/**
+ * Created on 2023-02-09
+ *
+ * @author mgn
+ */
+public class CreateAppiumGuiElementAction extends AbstractFieldAction implements UiElementFinderFactoryProvider, Loggable {
+
+ public CreateAppiumGuiElementAction(Field field, AbstractPage declaringPage) {
+ super(field, declaringPage);
+ }
+
+ @Override
+ protected boolean before() {
+ return true;
+ }
+
+ @Override
+ protected void execute() {
+ try {
+ // UiElements that have already been created may not be updated with new locator.
+ if (field.get(this.declaringPage) != null) {
+ return;
+ }
+ } catch (IllegalAccessException e) {
+ return;
+ }
+
+ Platform mobilePlatform = new MobileOsChecker().getPlatform(this.declaringPage.getWebDriver());
+ String automationName = getAutomationEngine(this.declaringPage.getWebDriver(), mobilePlatform);
+
+ // TODO: Check if no Appium annotations are available --> should be logged because of default by
+ DefaultElementByBuilder byBuilder = new DefaultElementByBuilder(mobilePlatform.toString(), automationName);
+ byBuilder.setAnnotated(field);
+ // Note: The DefaultElementByBuilder creates a default By 'By.id(" optional = instance.getSessionContext(driver).map(SessionContext::getWebDriverRequest);
+ if (optional.isPresent()) {
+ String automationEngine = optional.get().getCapabilities().get(MobileCapabilityType.AUTOMATION_NAME).toString();
+ if (StringUtils.isNotBlank(automationEngine)) {
+ return automationEngine;
+ } else {
+ // Use default values for automation engine
+ switch (platform) {
+ case ANDROID:
+ return "UiAutomator2";
+ case IOS:
+ return "XCUITest";
+ default:
+ throw new RuntimeException("Cannot get automation engine: Invalid platform " + platform);
+ }
+ }
+ }
+ throw new RuntimeException("Cannot get automation engine: Cannot get request from WebDriver session.");
+ }
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumClassFinder.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumClassFinder.java
new file mode 100644
index 00000000..3814e37a
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumClassFinder.java
@@ -0,0 +1,173 @@
+package eu.tsystems.mms.tic.testframework.mobile.pageobject;
+
+import eu.tsystems.mms.tic.testframework.logging.Loggable;
+import eu.tsystems.mms.tic.testframework.mobile.driver.MobileOsChecker;
+import eu.tsystems.mms.tic.testframework.pageobjects.Page;
+import eu.tsystems.mms.tic.testframework.pageobjects.PageObject;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.WebDriver;
+import org.reflections.Reflections;
+import org.reflections.scanners.SubTypesScanner;
+import org.reflections.util.ClasspathHelper;
+import org.reflections.util.ConfigurationBuilder;
+
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created on 2023-03-13
+ *
+ * @author mgn
+ */
+public class AppiumClassFinder implements Loggable {
+
+ private static AppiumClassFinder INSTANCE;
+
+ /**
+ * This call takes some time. It has an impact to the duration of the first page check (takes ca 2-3 seconds longer).
+ */
+ private final Reflections reflections = new Reflections(filter(configure()));
+
+ private AppiumClassFinder() {
+ }
+
+ public static AppiumClassFinder getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new AppiumClassFinder();
+ }
+ return INSTANCE;
+ }
+
+ public Class getBestMatchingClass(Class baseClass, WebDriver webDriver) {
+ MobileOsChecker osChecker = new MobileOsChecker();
+ Platform platform = osChecker.getPlatform(webDriver);
+
+ Class extends PageObject> matchedClass = AppiumClassFinder.Caches.getCache(baseClass, platform);
+
+ if (matchedClass == null) {
+ // scan and fill cache
+ this.findSubPagesOf(baseClass);
+ matchedClass = AppiumClassFinder.Caches.getCache(baseClass, platform);
+
+ if (matchedClass == null) {
+ throw new RuntimeException("Something went wrong scanning this class for sub types: " + baseClass.getName());
+ }
+ }
+
+ return (Class) matchedClass;
+ }
+
+ private void findSubPagesOf(final Class pageClass) {
+ log().debug("Searching for subtypes of class {}", pageClass);
+ Class baseClass = null;
+ if (!Modifier.isAbstract(pageClass.getModifiers())) {
+ baseClass = pageClass;
+ AppiumClassFinder.Caches.setCache(baseClass, this.getMatchingPlatform(baseClass.getSimpleName()), baseClass);
+ }
+
+ Set extends Class> subClasses = reflections.getSubTypesOf((Class) baseClass);
+ for (Class subClass : subClasses) {
+ String subClassName = subClass.getSimpleName();
+
+ if (Modifier.isAbstract(subClass.getModifiers())) {
+ log().debug("Not taking {} into consideration, because it is abstract", subClassName);
+ } else {
+ if (this.matchingPattern(subClassName, baseClass.getSimpleName())) {
+ AppiumClassFinder.Caches.setCache(baseClass, this.getMatchingPlatform(subClassName), subClass);
+ }
+ }
+ }
+ }
+
+ public void clearCache() {
+ AppiumClassFinder.Caches.IMPLEMENTATIONS_CACHE.clear();
+ }
+
+ private boolean matchingPattern(String className, String baseClassName) {
+ Pattern pattern = Pattern.compile("(?i)^(ios|android)" + baseClassName);
+ Matcher matcher = pattern.matcher(className);
+ return matcher.find();
+ }
+
+ private Platform getMatchingPlatform(String className) {
+ if (className.toLowerCase().contains(Platform.IOS.toString().toLowerCase())) {
+ return Platform.IOS;
+ }
+ if (className.toLowerCase().contains(Platform.ANDROID.toString().toLowerCase())) {
+ return Platform.ANDROID;
+ }
+ return Platform.ANY;
+ }
+
+ private ConfigurationBuilder configure() {
+ return new ConfigurationBuilder().setUrls(ClasspathHelper.forJavaClassPath());
+ }
+
+ /**
+ * This method should prune resources we are not interested in, but not change the interesting results.
+ */
+ private ConfigurationBuilder filter(final ConfigurationBuilder configuration) {
+ configuration.setScanners(new SubTypesScanner()); // drops TypeAnnotationScanner
+ configuration.useParallelExecutor();
+ return configuration;
+ }
+
+ /**
+ * Store already found classes in a map like:
+ * MainClass.class: [
+ * Platform.ANY: MainClass.class
+ * Platform.IOS: IOSMainClass.class
+ * Platform.ANDROID: AndroidMainClass.class
+ * ]
+ */
+ private static class Caches {
+
+ private static final Platform DEFAULT_PLATFORM = Platform.ANY;
+
+ private static final Map, Map>> IMPLEMENTATIONS_CACHE = new ConcurrentHashMap<>();
+
+ private static Class extends PageObject> getCache(Class extends PageObject> pageClass, Platform platform) {
+ if (platform != Platform.ANDROID && platform != Platform.IOS) {
+ platform = DEFAULT_PLATFORM;
+ }
+
+ synchronized (IMPLEMENTATIONS_CACHE) {
+ if (!IMPLEMENTATIONS_CACHE.containsKey(pageClass)) {
+ return null;
+ }
+
+ Map> map = IMPLEMENTATIONS_CACHE.get(pageClass);
+ Class extends PageObject> matchedClass = map.get(platform);
+ if (matchedClass == null) {
+ matchedClass = map.get(DEFAULT_PLATFORM);
+ }
+ return matchedClass;
+ }
+ }
+
+ /**
+ * Returns the best matching class from map. If no platform specific map exists, the baseclass will return.
+ */
+ private static void setCache(Class extends PageObject> pageClass, Platform platform, Class extends PageObject> prioritizedClassInfos) {
+ if (platform != Platform.ANDROID && platform != Platform.IOS) {
+ platform = DEFAULT_PLATFORM;
+ }
+
+ synchronized (IMPLEMENTATIONS_CACHE) {
+ if (!IMPLEMENTATIONS_CACHE.containsKey(pageClass)) {
+ IMPLEMENTATIONS_CACHE.put(pageClass, new HashMap<>());
+ }
+ Map> map = IMPLEMENTATIONS_CACHE.get(pageClass);
+
+ map.put(platform, prioritizedClassInfos);
+ }
+ }
+ }
+
+
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumPageFactory.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumPageFactory.java
new file mode 100644
index 00000000..706f8b0d
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumPageFactory.java
@@ -0,0 +1,27 @@
+package eu.tsystems.mms.tic.testframework.mobile.pageobject;
+
+import eu.tsystems.mms.tic.testframework.enums.CheckRule;
+import eu.tsystems.mms.tic.testframework.pageobjects.Page;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.DefaultPageFactory;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.PageFactory;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * Created on 2023-03-13
+ *
+ * @author mgn
+ */
+public class AppiumPageFactory extends DefaultPageFactory {
+
+ @Override
+ public T createPageWithCheckRule(Class pageClass, WebDriver webDriver, CheckRule checkRule) {
+ return super.createPageWithCheckRule(AppiumClassFinder.getInstance().getBestMatchingClass(pageClass, webDriver), webDriver, checkRule);
+ }
+
+ @Override
+ public PageFactory clearThreadLocalPagesPrefix() {
+ AppiumClassFinder.getInstance().clearCache();
+ return super.clearThreadLocalPagesPrefix();
+ }
+
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumExecutionUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumExecutionUtils.java
new file mode 100644
index 00000000..91e820a4
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumExecutionUtils.java
@@ -0,0 +1,47 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems Multimedia Solutions GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package eu.tsystems.mms.tic.testframework.utils;
+
+import java.util.Optional;
+import java.util.function.Supplier;
+
+/**
+ * Created on 2023-03-10
+ *
+ * @author mgn
+ */
+public class AppiumExecutionUtils implements ExecutionUtils {
+
+ /**
+ * The only change against default is the log level in the catch block.
+ * This is needed to keep clean the logs because of some restrictions of Appium for native apps.
+ */
+ public Optional getFailsafe(Supplier supplier) {
+ try {
+ T returnVal = supplier.get();
+ return Optional.ofNullable(returnVal);
+ } catch (Throwable e) {
+ log().debug("Property is not supported at this platform\n", e);
+ return Optional.empty();
+ }
+ }
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumProperties.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumProperties.java
index 64a7ae5a..cdf4cc70 100644
--- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumProperties.java
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumProperties.java
@@ -12,8 +12,9 @@ public enum AppiumProperties implements IProperties {
MOBILE_GRID_URL("tt.mobile.grid.url", ""),
MOBILE_GRID_ACCESS_KEY("tt.mobile.grid.access.key", ""),
// MOBILE_APPIUM_DEVICE_QUERY("tt.mobile.device.query", ""),
- MOBILE_APPIUM_DEVICE_QUERY_IOS("tt.mobile.device.query.ios", "@os='ios' and @category='PHONE'"),
- MOBILE_APPIUM_DEVICE_QUERY_ANDROID("tt.mobile.device.query.android", "@os='android' and @category='PHONE'"),
+// MOBILE_APPIUM_DEVICE_QUERY_IOS("tt.mobile.device.query.ios", "@os='ios' and @category='PHONE'"),
+ MOBILE_APPIUM_DEVICE_QUERY_IOS("tt.mobile.device.query.ios", ""),
+ MOBILE_APPIUM_DEVICE_QUERY_ANDROID("tt.mobile.device.query.android", ""),
;
private final String property;
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java
new file mode 100644
index 00000000..6673048e
--- /dev/null
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java
@@ -0,0 +1,93 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.utils;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import eu.tsystems.mms.tic.testframework.appium.AppiumContext;
+import eu.tsystems.mms.tic.testframework.logging.Loggable;
+import eu.tsystems.mms.tic.testframework.mobile.driver.MobileOsChecker;
+import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider;
+import io.appium.java_client.AppiumDriver;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.WebDriver;
+
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Created on 2023-03-08
+ *
+ * @author mgn
+ */
+public class AppiumUtils implements WebDriverManagerProvider, Loggable {
+
+ public String runCommand(WebDriver driver, String command, String... args) {
+ log().info("Shell command (native): {}, {}", command, Arrays.toString(args)); // ImmutableList does NOT work here...
+ return String.valueOf(JSUtils.executeScript(driver, "mobile: shell", ImmutableMap.of("command", command, "args", Lists.newArrayList(args))));
+ }
+
+ public void launchIOSApp(WebDriver driver, String bundleId) {
+ log().info("Start application '{}'", bundleId);
+ MobileOsChecker checker = new MobileOsChecker();
+ Platform platform = checker.getPlatform(driver);
+ if (platform == Platform.IOS) {
+ JSUtils.executeScript(driver, "mobile: launchApp", ImmutableMap.of("bundleId", bundleId));
+ JSUtils.executeScript(driver, "mobile: activateApp", ImmutableMap.of("bundleId", bundleId));
+ } else {
+ throw new RuntimeException("Cannot start application " + bundleId + " at " + platform);
+ }
+ }
+
+ /**
+ * Switch the Appium Context if available
+ */
+ public void switchContext(WebDriver driver, AppiumContext desiredContext) {
+ Optional appiumDriver = WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class);
+ if (appiumDriver.isEmpty()) {
+ throw new RuntimeException("Current Webdriver is not an Appium driver.");
+ }
+ String currentContext = appiumDriver.get().getContext();
+ AppiumContext parsedInitialContext = AppiumContext.parse(currentContext);
+ log().info("Current context: {} ({})", currentContext, parsedInitialContext);
+
+ if (parsedInitialContext.equals(desiredContext)) {
+ log().info("Already in context {}", desiredContext);
+ return;
+ }
+
+ Set contextHandles = appiumDriver.get().getContextHandles();
+ log().info("Available contexts: {}", contextHandles);
+ contextHandles.stream()
+ .filter(contextHandle -> AppiumContext.parse(contextHandle).equals(desiredContext))
+ .findFirst()
+ .ifPresentOrElse(handle -> {
+ log().info("Switch to context {} ({})", handle, desiredContext);
+ appiumDriver.get().context(handle);
+ }, () -> {
+ log().error("Couldn't find a {} context in {}", desiredContext, contextHandles);
+ throw new RuntimeException(String.format("Cannot switch in %s, because it does not exist. (%s)", desiredContext, contextHandles));
+ });
+
+ }
+
+}
diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java
index 07c5e750..4c5be9a8 100644
--- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java
+++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java
@@ -21,7 +21,10 @@
package eu.tsystems.mms.tic.testframework.webdrivermanager;
+import eu.tsystems.mms.tic.testframework.appium.Browsers;
import eu.tsystems.mms.tic.testframework.utils.AppiumProperties;
+import io.appium.java_client.remote.MobileCapabilityType;
+import org.apache.commons.lang3.StringUtils;
import java.net.MalformedURLException;
import java.net.URL;
@@ -35,6 +38,7 @@ public class AppiumDriverRequest extends SeleniumWebDriverRequest {
public AppiumDriverRequest() {
setAccessKey(AppiumProperties.MOBILE_GRID_ACCESS_KEY.asString());
+ this.setBrowser(Browsers.mobile);
}
@Override
@@ -50,10 +54,44 @@ public Optional getServerUrl() {
}
public void setDeviceQuery(String deviceQuery) {
- this.getDesiredCapabilities().setCapability(DEVICE_QUERY, deviceQuery);
+ if (StringUtils.isNotBlank(deviceQuery)) {
+ this.getDesiredCapabilities().setCapability(DEVICE_QUERY, deviceQuery);
+ }
}
public void setAccessKey(String accessKey) {
this.getDesiredCapabilities().setCapability(ACCESS_KEY, accessKey);
}
+
+ public void setAppiumEngine(String engine) {
+ this.getDesiredCapabilities().setCapability(MobileCapabilityType.AUTOMATION_NAME, engine);
+ }
+
+ public String getAppiumEngine() {
+ return this.getDesiredCapabilities().getCapability(MobileCapabilityType.AUTOMATION_NAME).toString();
+ }
+
+ public void setDeviceName(String deviceName) {
+ this.getDesiredCapabilities().setCapability(MobileCapabilityType.DEVICE_NAME, deviceName);
+ }
+
+ public String getDeviceName() {
+ return this.getDesiredCapabilities().getCapability(MobileCapabilityType.DEVICE_NAME).toString();
+ }
+
+ public void setPlatformVersion(String platformVersion) {
+ this.getDesiredCapabilities().setCapability(MobileCapabilityType.PLATFORM_VERSION, platformVersion);
+ }
+
+ public String getPlatformVersion() {
+ return this.getDesiredCapabilities().getCapability(MobileCapabilityType.PLATFORM_VERSION).toString();
+ }
+
+ public void setDeviceId(String id) {
+ this.getDesiredCapabilities().setCapability(MobileCapabilityType.UDID, id);
+ }
+
+ public String getDeviceId() {
+ return this.getDesiredCapabilities().getCapability(MobileCapabilityType.UDID).toString();
+ }
}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/ioc/AppiumConnectorTestModule.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/ioc/AppiumConnectorTestModule.java
new file mode 100644
index 00000000..12b0700d
--- /dev/null
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/ioc/AppiumConnectorTestModule.java
@@ -0,0 +1,19 @@
+package eu.tsystems.mms.tic.testframework.mobile.systemundertest.ioc;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import eu.tsystems.mms.tic.testframework.mobile.pageobject.AppiumPageFactory;
+import eu.tsystems.mms.tic.testframework.pageobjects.internal.PageFactory;
+
+/**
+ * Created on 2023-03-13
+ *
+ * @author mgn
+ */
+public class AppiumConnectorTestModule extends AbstractModule {
+
+ protected void configure() {
+ bind(PageFactory.class).to(AppiumPageFactory.class).in(Scopes.SINGLETON);
+ }
+
+}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/StartPage.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/StartPage.java
index ec3c7928..9a993f0f 100644
--- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/StartPage.java
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/StartPage.java
@@ -23,9 +23,7 @@
package eu.tsystems.mms.tic.testframework.mobile.systemundertest.page;
import eu.tsystems.mms.tic.testframework.pageobjects.Check;
-import eu.tsystems.mms.tic.testframework.pageobjects.GuiElement;
-import eu.tsystems.mms.tic.testframework.pageobjects.Locate;
-import eu.tsystems.mms.tic.testframework.pageobjects.factory.PageFactory;
+import eu.tsystems.mms.tic.testframework.pageobjects.UiElement;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
@@ -40,10 +38,10 @@
public class StartPage extends AbstractInternetPage {
@Check
- private GuiElement linkLogin = new GuiElement(this.getWebDriver(), Locate.by(By.linkText("Form Authentication")));
+ private UiElement linkLogin = find(By.linkText("Form Authentication"));
@Check
- private GuiElement linkTables = new GuiElement(this.getWebDriver(), Locate.by(By.linkText("Sortable Data Tables")));
+ private UiElement linkTables = find(By.linkText("Sortable Data Tables"));
/**
* Constructor for existing sessions.
@@ -51,21 +49,18 @@ public class StartPage extends AbstractInternetPage {
* @param driver .
*/
public StartPage(WebDriver driver) {
-
super(driver);
}
public LoginPage goToLoginPage() {
-
this.linkLogin.scrollIntoView();
this.linkLogin.click();
- return PageFactory.create(LoginPage.class, this.getWebDriver());
+ return createPage(LoginPage.class);
}
public TablePage goToTablePage() {
-
this.linkTables.scrollIntoView();
this.linkTables.click();
- return PageFactory.create(TablePage.class, this.getWebDriver());
+ return createPage(TablePage.class);
}
}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/IosWifiSettingsPage.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/IosWifiSettingsPage.java
new file mode 100644
index 00000000..1e9810cd
--- /dev/null
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/IosWifiSettingsPage.java
@@ -0,0 +1,15 @@
+package eu.tsystems.mms.tic.testframework.mobile.systemundertest.page.nativeos;
+
+import org.openqa.selenium.WebDriver;
+
+/**
+ * Created on 2023-03-13
+ *
+ * @author mgn
+ */
+public class IosWifiSettingsPage extends WifiSettingsPage{
+ public IosWifiSettingsPage(WebDriver webDriver) {
+ super(webDriver);
+ log().info("You are using the specific IOS WifiSettings page.");
+ }
+}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/SettingsPage.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/SettingsPage.java
new file mode 100644
index 00000000..1b7d1a1e
--- /dev/null
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/SettingsPage.java
@@ -0,0 +1,52 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.mobile.systemundertest.page.nativeos;
+
+import eu.tsystems.mms.tic.testframework.mobile.AppiumPage;
+import eu.tsystems.mms.tic.testframework.pageobjects.Check;
+import eu.tsystems.mms.tic.testframework.pageobjects.UiElement;
+import io.appium.java_client.pagefactory.iOSXCUITFindBy;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * Created on 2023-03-08
+ *
+ * @author mgn
+ */
+public class SettingsPage extends AppiumPage {
+
+ @Check
+ private UiElement title = find(By.xpath("//XCUIElementTypeStaticText[@value='Einstellungen']"));
+
+ @Check
+ @iOSXCUITFindBy(xpath = "//*[@type='XCUIElementTypeStaticText' and @value='WLAN']")
+ private UiElement buttonWLAN;
+
+ public SettingsPage(WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ public WifiSettingsPage gotoWifiSettings() {
+ this.buttonWLAN.click();
+ return createPage(WifiSettingsPage.class);
+ }
+}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/WifiSettingsPage.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/WifiSettingsPage.java
new file mode 100644
index 00000000..62c0fe14
--- /dev/null
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/systemundertest/page/nativeos/WifiSettingsPage.java
@@ -0,0 +1,64 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.mobile.systemundertest.page.nativeos;
+
+import eu.tsystems.mms.tic.testframework.mobile.AppiumPage;
+import eu.tsystems.mms.tic.testframework.pageobjects.Check;
+import eu.tsystems.mms.tic.testframework.pageobjects.TestableUiElement;
+import eu.tsystems.mms.tic.testframework.pageobjects.UiElement;
+import io.appium.java_client.pagefactory.AndroidFindBy;
+import io.appium.java_client.pagefactory.iOSXCUITFindBy;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * Created on 2023-03-08
+ *
+ * @author mgn
+ */
+public class WifiSettingsPage extends AppiumPage {
+
+ @Check
+ @AndroidFindBy(xpath = "//*[@text='WLAN' or @text='Wi-Fi']") // this is language specific (english + german)
+ @iOSXCUITFindBy(xpath = "//*[@type='XCUIElementTypeNavigationBar']//*[@label='WLAN']") // native Appium identifier
+ protected UiElement headline;
+
+ @Check
+ @AndroidFindBy(xpath = "//*[@class='android.widget.Switch' or @id='switch_widget' or @id='checkbox' or @id='switchWidget']")
+ // this is language specific (english + german)
+ @iOSXCUITFindBy(xpath = "//*[@label='WLAN' and @type='XCUIElementTypeSwitch']")
+ protected UiElement wlanToggle;
+
+ public WifiSettingsPage(WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ public void deactivateWifi() {
+ this.wlanToggle.select(false);
+ }
+
+ public void activateWifi() {
+ this.wlanToggle.select(true);
+ }
+
+ public TestableUiElement getWlanToggle() {
+ return this.wlanToggle;
+ }
+}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java
new file mode 100644
index 00000000..82cdf42b
--- /dev/null
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java
@@ -0,0 +1,132 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.mobile.test.apps;
+
+import eu.tsystems.mms.tic.testframework.mobile.driver.MobileOsChecker;
+import eu.tsystems.mms.tic.testframework.mobile.systemundertest.page.nativeos.SettingsPage;
+import eu.tsystems.mms.tic.testframework.mobile.systemundertest.page.nativeos.WifiSettingsPage;
+import eu.tsystems.mms.tic.testframework.mobile.test.AbstractAppiumTest;
+import eu.tsystems.mms.tic.testframework.report.model.steps.TestStep;
+import eu.tsystems.mms.tic.testframework.utils.AppiumUtils;
+import eu.tsystems.mms.tic.testframework.utils.TimerUtils;
+import eu.tsystems.mms.tic.testframework.utils.UITestUtils;
+import eu.tsystems.mms.tic.testframework.webdrivermanager.AppiumDriverRequest;
+import io.appium.java_client.remote.AndroidMobileCapabilityType;
+import io.appium.java_client.remote.MobileCapabilityType;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.WebDriver;
+import org.testng.annotations.Test;
+
+import java.net.MalformedURLException;
+
+/**
+ * Created on 2023-02-07
+ *
+ * @author mgn
+ */
+public class TesterraMobileAppTest extends AbstractAppiumTest {
+
+ @Test
+ public void testT01AndroidApp() {
+ AppiumDriverRequest request = new AppiumDriverRequest();
+ request.setDeviceQuery("contains(@name, 'Galaxy S20')");
+ request.getDesiredCapabilities().setCapability("appiumVersion", "1.22.3");
+
+ request.getDesiredCapabilities().setCapability(MobileCapabilityType.APP, "cloud:eu.tsystems.mms.tic.mdc.app.android/.HomeActivity");
+ request.getDesiredCapabilities().setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "eu.tsystems.mms.tic.mdc.app.android");
+ request.getDesiredCapabilities().setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".HomeActivity");
+ request.setAppiumEngine("UiAutomator2");
+
+ WebDriver webDriver = WEB_DRIVER_MANAGER.getWebDriver(request);
+ TimerUtils.sleep(4000);
+ }
+
+ @Test
+ public void testT10NativeIOSSettings() {
+ AppiumDriverRequest request = new AppiumDriverRequest();
+ request.setDeviceQuery("contains(@name, 'iPhone X')");
+ request.getDesiredCapabilities().setCapability("appiumVersion", "1.22.3");
+ request.setAppiumEngine("XCUITest");
+ WebDriver webDriver = WEB_DRIVER_MANAGER.getWebDriver(request);
+
+ WifiSettingsPage wifiSettingsPage = openWifiSettings(webDriver);
+ switchWiFi(wifiSettingsPage);
+ TimerUtils.sleep(5000);
+
+ UITestUtils.takeScreenshots();
+ }
+
+ @Test
+ public void testT12NativeAndWebAccessIOS() {
+ AppiumDriverRequest request = new AppiumDriverRequest();
+ request.setDeviceQuery("contains(@name, 'iPhone X')");
+ request.getDesiredCapabilities().setCapability("appiumVersion", "1.22.3");
+ request.setAppiumEngine("XCUITest");
+ WebDriver webDriver = WEB_DRIVER_MANAGER.getWebDriver(request);
+
+
+
+ WifiSettingsPage wifiSettingsPage = openWifiSettings(webDriver);
+ switchWiFi(wifiSettingsPage);
+
+
+ UITestUtils.takeScreenshots();
+ }
+
+ @Test
+ public void testT11NativeAndroidSettings() {
+ AppiumDriverRequest request = new AppiumDriverRequest();
+ request.setDeviceQuery("contains(@name, 'Samsung Galaxy S20')");
+ request.getDesiredCapabilities().setCapability("appiumVersion", "1.22.3");
+ request.setAppiumEngine("UiAutomator2");
+ WebDriver webDriver = WEB_DRIVER_MANAGER.getWebDriver(request);
+
+ WifiSettingsPage wifiSettingsPage = openWifiSettings(webDriver);
+ switchWiFi(wifiSettingsPage);
+ }
+
+ private WifiSettingsPage openWifiSettings(WebDriver driver) {
+ TestStep.begin("Open Wifi settings");
+ MobileOsChecker checker = new MobileOsChecker();
+ Platform platform = checker.getPlatform(driver);
+ switch (platform) {
+ case IOS:
+ new AppiumUtils().launchIOSApp(driver, "com.apple.Preferences");
+ SettingsPage settingsPage = PAGE_FACTORY.createPage(SettingsPage.class, driver);
+ return settingsPage.gotoWifiSettings();
+ case ANDROID:
+ new AppiumUtils().runCommand(driver, "am", "start", "-a", "android.settings.WIFI_SETTINGS");
+ return PAGE_FACTORY.createPage(WifiSettingsPage.class, driver);
+ }
+ throw new RuntimeException("Invalid platform");
+ }
+
+ private void switchWiFi(WifiSettingsPage wifiSettingsPage) {
+ TestStep.begin("Deactivate wifi");
+ wifiSettingsPage.deactivateWifi();
+ wifiSettingsPage.getWlanToggle().assertThat().selected(false);
+
+ TestStep.begin("Activate wifi");
+ wifiSettingsPage.activateWifi();
+ wifiSettingsPage.getWlanToggle().assertThat().selected(true);
+ }
+
+}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/VanillaAppiumAppTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/VanillaAppiumAppTest.java
new file mode 100644
index 00000000..39b5be04
--- /dev/null
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/VanillaAppiumAppTest.java
@@ -0,0 +1,79 @@
+/*
+ * Testerra
+ *
+ * (C) 2023, Martin Großmann, T-Systems MMS GmbH, Deutsche Telekom AG
+ *
+ * Deutsche Telekom AG and all other contributors /
+ * copyright owners license this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package eu.tsystems.mms.tic.testframework.mobile.test.apps;
+
+import eu.tsystems.mms.tic.testframework.mobile.test.AbstractAppiumTest;
+import eu.tsystems.mms.tic.testframework.utils.AppiumProperties;
+import eu.tsystems.mms.tic.testframework.utils.TimerUtils;
+import io.appium.java_client.android.AndroidDriver;
+import io.appium.java_client.android.AndroidElement;
+import io.appium.java_client.remote.AndroidMobileCapabilityType;
+import io.appium.java_client.remote.MobileCapabilityType;
+import org.openqa.selenium.remote.DesiredCapabilities;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Created on 2023-02-07
+ *
+ * @author mgn
+ */
+public class VanillaAppiumAppTest extends AbstractAppiumTest {
+
+ protected AndroidDriver driver = null;
+
+ @BeforeMethod
+ public void setUp() throws MalformedURLException {
+ final String accessKey = AppiumProperties.MOBILE_GRID_ACCESS_KEY.asString();
+ Assert.assertNotNull(accessKey, "No access key loaded");
+
+ DesiredCapabilities dc = new DesiredCapabilities();
+ dc.setCapability("testName", "Demo Tests");
+ dc.setCapability("accessKey", accessKey);
+ dc.setCapability("deviceQuery", "contains(@name, 'Galaxy S20') and @version='13.0'");
+ dc.setCapability("appiumVersion", "1.22.3");
+ dc.setCapability(MobileCapabilityType.APP, "cloud:eu.tsystems.mms.tic.mdc.app.android/.HomeActivity");
+ dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "eu.tsystems.mms.tic.mdc.app.android");
+ dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".HomeActivity");
+ dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UIAutomator2");
+ URL url = new URL(AppiumProperties.MOBILE_GRID_URL.asString());
+ // driver = new IOSDriver<>(new URL(PropertyManager.getProperty("tt.mobile.grid.url")), dc);
+ driver = new AndroidDriver<>(url, dc);
+ }
+
+ @Test
+ public void testT01CheckApp() {
+ TimerUtils.sleep(5000);
+ }
+
+ @AfterMethod
+ public void tearDown() {
+
+ log().info("Report URL: " + driver.getCapabilities().getCapability("reportUrl"));
+ driver.quit();
+ }
+
+}
diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java
index 6be21efd..27b54b1d 100644
--- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java
+++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java
@@ -28,8 +28,8 @@
import eu.tsystems.mms.tic.testframework.report.Report;
import eu.tsystems.mms.tic.testframework.report.TesterraListener;
import eu.tsystems.mms.tic.testframework.utils.AppiumProperties;
-import io.appium.java_client.android.AndroidDriver;
-import io.appium.java_client.android.AndroidElement;
+import io.appium.java_client.ios.IOSDriver;
+import io.appium.java_client.ios.IOSElement;
import io.appium.java_client.remote.MobileBrowserType;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
@@ -56,8 +56,8 @@
*/
public class VanillaAppiumDriverTest extends AbstractAppiumTest implements Loggable, PropertyManagerProvider {
- // protected IOSDriver driver = null;
- protected AndroidDriver driver = null;
+ protected IOSDriver driver = null;
+// protected AndroidDriver driver = null;
@BeforeMethod
public void setUp() throws MalformedURLException {
@@ -67,18 +67,24 @@ public void setUp() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("testName", "Demo Tests");
dc.setCapability("accessKey", accessKey);
- // dc.setCapability("deviceQuery", "@os='ios' and @category='PHONE'");
- dc.setCapability("deviceQuery", AppiumProperties.MOBILE_APPIUM_DEVICE_QUERY_ANDROID);
- // dc.setBrowserName(MobileBrowserType.SAFARI);
- dc.setBrowserName(MobileBrowserType.CHROMIUM);
+ dc.setCapability("appiumVersion", "1.22.3");
+// dc.setCapability("deviceQuery", "contains(@name, 'Samsung Galaxy S20')");
+// dc.setCapability("deviceQuery", "contains(@name, 'Google Pixel 6')");
+// dc.setCapability("deviceQuery", AppiumProperties.MOBILE_APPIUM_DEVICE_QUERY_ANDROID);
+ dc.setCapability("deviceQuery", "contains(@name, 'Apple iPhone X (')");
+// dc.setCapability(MobileCapabilityType.UDID, "...");
+ dc.setBrowserName(MobileBrowserType.SAFARI);
+// dc.setBrowserName(MobileBrowserType.CHROME);
URL url = new URL(AppiumProperties.MOBILE_GRID_URL.asString());
- // driver = new IOSDriver<>(new URL(PropertyManager.getProperty("tt.mobile.grid.url")), dc);
- driver = new AndroidDriver<>(url, dc);
+ log().info(dc.toString());
+
+ driver = new IOSDriver<>(url, dc);
+// driver = new AndroidDriver<>(url, dc);
+
}
@Test
public void testT01_DoGoogleSearch() {
-
driver.rotate(ScreenOrientation.PORTRAIT);
driver.get("https://www.google.com");
new WebDriverWait(driver, 10).until(driver1 -> {
@@ -94,7 +100,6 @@ public void testT01_DoGoogleSearch() {
@AfterMethod
public void tearDown() {
-
log().info("Report URL: " + driver.getCapabilities().getCapability("reportUrl"));
driver.quit();
}
diff --git a/appium/src/test/resources/test.properties b/appium/src/test/resources/test.properties
index 77f0b741..c95bb1a6 100644
--- a/appium/src/test/resources/test.properties
+++ b/appium/src/test/resources/test.properties
@@ -1,6 +1,6 @@
#tt.browser=mobile_chrome
-tt.browser=mobile_safari
+#tt.browser=mobile_safari
tt.watchdog.enable=false
tt.baseurl=https://the-internet.herokuapp.com/
#tt.mobile.device.query.ios=@os='ios' and @category='PHONE'
diff --git a/settings.gradle b/settings.gradle
index f38489f2..907772ff 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,5 +2,5 @@ rootProject.name = 'testerra-appium-connector'
include 'appium'
include 'appium-seetest'
-//includeBuild("../testerra")
+//includeBuild("../github_testerra")