Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .azure-templates/bootstrap_steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ steps:
npm config set prefix $NVM_DIR/versions/node/`node --version`
node --version

npm install -g appium@beta
npm install -g appium@next
6 changes: 5 additions & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ variables:
XCODE_VERSION: 11.5
IOS_PLATFORM_VERSION: 13.5
IOS_DEVICE_NAME: iPhone X
NODE_VERSION: 12.x
NODE_VERSION: 14.x
JDK_VERSION: 1.8

jobs:
- job: Android_E2E_Tests
steps:
- template: .azure-templates/bootstrap_steps.yml
- script: $NVM_DIR/versions/node/`node --version`/bin/appium driver install uiautomator2
displayName: Install UIA2 driver
- script: |
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;$(ANDROID_EMU_TARGET);$(ANDROID_EMU_TAG);$(ANDROID_EMU_ABI)'
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n "$(ANDROID_EMU_NAME)" -k 'system-images;$(ANDROID_EMU_TARGET);$(ANDROID_EMU_TAG);$(ANDROID_EMU_ABI)' --force
Expand Down Expand Up @@ -50,6 +52,8 @@ jobs:
sudo xcode-select -s /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer
xcrun simctl list
displayName: Simulator configuration
- script: $NVM_DIR/versions/node/`node --version`/bin/appium driver install xcuitest
displayName: Install XCUITest driver
- task: Gradle@2
inputs:
gradleWrapperFile: 'gradlew'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import com.google.common.annotations.VisibleForTesting;

import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;

import org.openqa.selenium.net.UrlChecker;
Expand All @@ -37,6 +38,7 @@
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.time.Duration;
import java.util.List;
Expand All @@ -52,7 +54,7 @@

public final class AppiumDriverLocalService extends DriverService {

private static final String URL_MASK = "http://%s:%d/wd/hub";
private static final String URL_MASK = "http://%s:%d/";
private static final Logger LOG = LoggerFactory.getLogger(AppiumDriverLocalService.class);
private static final Pattern LOG_MESSAGE_PATTERN = Pattern.compile("^(.*)\\R");
private static final Pattern LOGGER_CONTEXT_PATTERN = Pattern.compile("^(\\[debug\\] )?\\[(.+?)\\]");
Expand All @@ -66,11 +68,14 @@ public final class AppiumDriverLocalService extends DriverService {
private final ReentrantLock lock = new ReentrantLock(true); //uses "fair" thread ordering policy
private final ListOutputStream stream = new ListOutputStream().add(System.out);
private final URL url;
private String basePath;

private CommandLine process = null;

AppiumDriverLocalService(String ipAddress, File nodeJSExec, int nodeJSPort, Duration startupTimeout,
List<String> nodeJSArgs, Map<String, String> nodeJSEnvironment) throws IOException {
AppiumDriverLocalService(String ipAddress, File nodeJSExec,
int nodeJSPort, Duration startupTimeout,
List<String> nodeJSArgs, Map<String, String> nodeJSEnvironment
) throws IOException {
super(nodeJSExec, nodeJSPort, startupTimeout, nodeJSArgs, nodeJSEnvironment);
this.nodeJSExec = nodeJSExec;
this.nodeJSArgs = nodeJSArgs;
Expand All @@ -87,14 +92,34 @@ public static AppiumDriverLocalService buildService(AppiumServiceBuilder builder
return builder.build();
}

public AppiumDriverLocalService withBasePath(String basePath) {
this.basePath = basePath;
return this;
}

public String getBasePath() {
return this.basePath;
}

@SneakyThrows
private static URL addSuffix(URL url, String suffix) {
return url.toURI().resolve("." + (suffix.startsWith("/") ? suffix : "/" + suffix)).toURL();
}

@SneakyThrows
@SuppressWarnings("SameParameterValue")
private static URL replaceHost(URL source, String oldHost, String newHost) {
return new URL(source.toString().replace(oldHost, newHost));
}

/**
* Base URL.
*
* @return The base URL for the managed appium server.
*/
@Override
public URL getUrl() {
return url;
return basePath == null ? url : addSuffix(url, basePath);
}

@Override
Expand Down Expand Up @@ -125,7 +150,7 @@ public boolean isRunning() {

private void ping(Duration timeout) throws UrlChecker.TimeoutException, MalformedURLException {
// The operating system might block direct access to the universal broadcast IP address
URL status = new URL(url.toString().replace(BROADCAST_IP_ADDRESS, "127.0.0.1") + "/status");
URL status = addSuffix(replaceHost(getUrl(), BROADCAST_IP_ADDRESS, "127.0.0.1"), "/status");
new UrlChecker().waitUntilAvailable(timeout.toMillis(), TimeUnit.MILLISECONDS, status);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileBrowserType;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.service.local.flags.GeneralServerFlag;
import io.appium.java_client.service.local.flags.ServerArgument;

import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
Expand Down Expand Up @@ -446,16 +448,15 @@ public AppiumServiceBuilder withLogFile(File logFile) {
return super.withLogFile(logFile);
}

@SneakyThrows
@Override
protected AppiumDriverLocalService createDriverService(File nodeJSExecutable, int nodeJSPort,
Duration startupTimeout,
List<String> nodeArguments,
Map<String, String> nodeEnvironment) {
try {
return new AppiumDriverLocalService(ipAddress, nodeJSExecutable, nodeJSPort, startupTimeout, nodeArguments,
nodeEnvironment);
} catch (IOException e) {
throw new RuntimeException(e);
}
String basePath = serverArguments.getOrDefault(
GeneralServerFlag.BASEPATH.getArgument(), serverArguments.get("-pa"));
return new AppiumDriverLocalService(ipAddress, nodeJSExecutable, nodeJSPort, startupTimeout, nodeArguments,
nodeEnvironment).withBasePath(basePath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package io.appium.java_client.service.local.flags;


/**
* Here is the list of common Appium server arguments.
*/
Expand All @@ -43,7 +42,10 @@ public enum GeneralServerFlag implements ServerArgument {
* Pre-launch the application before allowing the first session
* (Requires –app and, for Android, –app-pkg and –app-activity).
* Default: false
*
* @deprecated This argument has been removed from Appium 2.0
*/
@Deprecated
PRE_LAUNCH("--pre-launch"),
/**
* The message log level to be shown.
Expand Down Expand Up @@ -75,14 +77,6 @@ public enum GeneralServerFlag implements ServerArgument {
* --nodeconfig /abs/path/to/nodeconfig.json
*/
CONFIGURATION_FILE("--nodeconfig"),
/**
* IP Address of robot. Sample: --robot-address 0.0.0.0
*/
ROBOT_ADDRESS("--robot-address"),
/**
* Port for robot. Sample: --robot-port 4242
*/
ROBOT_PORT("--robot-port"),
/**
* Show info about the Appium server configuration and exit. Default: false
*/
Expand Down Expand Up @@ -140,33 +134,21 @@ public enum GeneralServerFlag implements ServerArgument {
* Plugins are available with Appium as of Appium 2.0.
* To activate all plugins, you can use the single string "all" as the value (e.g --plugins=all)
* Default: []
* Sample: --plugins=device-farm,images
* Sample: --use-plugins=device-farm,images
*/
PLUGINS("--plugins"),
USE_PLUGINS("--use-plugins"),
/**
* A comma-separated list of installed driver names that should be active for this server.
* All drivers will be active by default.
* Default: []
* Sample: --drivers=uiautomator2,xcuitest
* Sample: --use-drivers=uiautomator2,xcuitest
*/
DRIVERS("--drivers"),
USE_DRIVERS("--use-drivers"),
/**
* Base path to use as the prefix for all webdriver routes running on this server.
* Sample: --base-path=/wd/hub
*/
BASEPATH("--base-path"),
/**
* Set the default desired client arguments for a plugin.
* Default: []
* Sample: [ '{"images":{"foo1": "bar1", "foo2": "bar2"}}' | /path/to/pluginArgs.json ]
*/
PLUGINARGS("--plugin-args"),
/**
* Set the default desired client arguments for a driver.
* Default: []
* Sample: [ '{"xcuitest": {"foo1": "bar1", "foo2": "bar2"}}' | /path/to/driverArgs.json ]
*/
DRIVERARGS("--driver-args");
BASEPATH("--base-path");

private final String arg;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,29 @@

import io.appium.java_client.android.options.UiAutomator2Options;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException;

import io.appium.java_client.service.local.AppiumServiceBuilder;
import org.junit.AfterClass;
import org.junit.BeforeClass;

import static io.appium.java_client.TestResources.apiDemosApk;

public class BaseAndroidTest {
public static final String APP_ID = "io.appium.android.apis";
protected static final int PORT = 4723;

private static AppiumDriverLocalService service;
protected static AndroidDriver driver;

/**
* initialization.
*/
@BeforeClass public static void beforeClass() {
service = AppiumDriverLocalService.buildDefaultService();
service = new AppiumServiceBuilder()
.withIPAddress("127.0.0.1")
.usingPort(PORT)
.build();
service.start();
if (service == null || !service.isRunning()) {
throw new AppiumServerHasNotBeenStartedLocallyException(
"An appium server node is not started!");
}

UiAutomator2Options options = new UiAutomator2Options()
.setDeviceName("Android Emulator")
Expand Down
10 changes: 5 additions & 5 deletions src/test/java/io/appium/java_client/ios/AppIOSTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.junit.BeforeClass;
import org.openqa.selenium.SessionNotCreatedException;

import java.net.URL;
import java.time.Duration;

import static io.appium.java_client.TestResources.testAppZip;
Expand All @@ -16,22 +15,23 @@ public class AppIOSTest extends BaseIOSTest {

@BeforeClass
public static void beforeClass() throws Exception {
final String ip = startAppiumServer();
startAppiumServer();

if (service == null || !service.isRunning()) {
if (!service.isRunning()) {
throw new AppiumServerHasNotBeenStartedLocallyException("An appium server node is not started!");
}

XCUITestOptions options = new XCUITestOptions()
.setPlatformVersion(PLATFORM_VERSION)
.setDeviceName(DEVICE_NAME)
.setCommandTimeouts(Duration.ofSeconds(240))
.setApp(testAppZip().toAbsolutePath().toString())
.setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT);
try {
driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options);
driver = new IOSDriver(service.getUrl(), options);
} catch (SessionNotCreatedException e) {
options.useNewWDA();
driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options);
driver = new IOSDriver(service.getUrl(), options);
}
}
}
11 changes: 8 additions & 3 deletions src/test/java/io/appium/java_client/ios/BaseIOSTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ public class BaseIOSTest {
protected static IOSDriver driver;
protected static final int PORT = 4723;
public static final String DEVICE_NAME = System.getenv("IOS_DEVICE_NAME") != null
? System.getenv("IOS_DEVICE_NAME") : "iPhone 12";
? System.getenv("IOS_DEVICE_NAME")
: "iPhone 12";
public static final String PLATFORM_VERSION = System.getenv("IOS_PLATFORM_VERSION") != null
? System.getenv("IOS_PLATFORM_VERSION") : "14.5";
? System.getenv("IOS_PLATFORM_VERSION")
: "14.5";
public static final Duration WDA_LAUNCH_TIMEOUT = Duration.ofSeconds(240);

/**
Expand All @@ -44,7 +46,10 @@ public class BaseIOSTest {
* @throws UnknownHostException when it is impossible to get ip address of a local host
*/
public static String startAppiumServer() throws UnknownHostException, SocketException {
service = new AppiumServiceBuilder().usingPort(PORT).build();
service = new AppiumServiceBuilder()
.withIPAddress("127.0.0.1")
.usingPort(PORT)
.build();
service.start();
return getLocalIp4Address();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import org.openqa.selenium.SessionNotCreatedException;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.function.Supplier;

Expand All @@ -46,13 +44,7 @@ public static void beforeClass() throws IOException {
.setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT)
.setCommandTimeouts(Duration.ofSeconds(240))
.setApp(vodQaAppZip().toAbsolutePath().toString());
Supplier<IOSDriver> createDriver = () -> {
try {
return new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
};
Supplier<IOSDriver> createDriver = () -> new IOSDriver(service.getUrl(), options);
try {
driver = createDriver.get();
} catch (SessionNotCreatedException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.junit.BeforeClass;

import java.io.IOException;
import java.net.URL;

public class BaseSafariTest extends BaseIOSTest {

Expand All @@ -38,6 +37,6 @@ public class BaseSafariTest extends BaseIOSTest {
.setDeviceName(DEVICE_NAME)
.setPlatformVersion(PLATFORM_VERSION)
.setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT);
driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options);
driver = new IOSDriver(service.getUrl(), options);
}
}
Loading