From 25cb6ea7605f5650d4e2c5978c69624e3558af9e Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 17 Oct 2019 21:53:41 +0200 Subject: [PATCH 1/6] refactor: Update the implementation of Appium executables detection --- .../service/local/AppiumServiceBuilder.java | 270 +++++++----------- .../local/InvalidServerInstanceException.java | 8 +- .../java_client/service/local/Scripts.java | 80 ------ src/main/resources/scripts/getExe.js | 1 - .../scripts/get_path_to_default_node.sh | 4 - 5 files changed, 111 insertions(+), 252 deletions(-) delete mode 100644 src/main/java/io/appium/java_client/service/local/Scripts.java delete mode 100644 src/main/resources/scripts/getExe.js delete mode 100644 src/main/resources/scripts/get_path_to_default_node.sh diff --git a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java index 86b9d2855..c7633f2b6 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java @@ -27,29 +27,34 @@ import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.flags.ServerArgument; -import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.validator.routines.InetAddressValidator; import org.openqa.selenium.Capabilities; import org.openqa.selenium.Platform; -import org.openqa.selenium.os.CommandLine; +import org.openqa.selenium.os.ExecutableFinder; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.service.DriverService; +import javax.annotation.Nullable; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.function.Function; public final class AppiumServiceBuilder - extends DriverService.Builder { + extends DriverService.Builder { /** * The environmental variable used to define @@ -63,34 +68,24 @@ public final class AppiumServiceBuilder * the path to executable NodeJS file (node.exe for WIN and * node for Linux/MacOS X). */ - public static final String NODE_PATH = "NODE_BINARY_PATH"; - public static final String DEFAULT_LOCAL_IP_ADDRESS = "0.0.0.0"; + private static final String NODE_PATH = "NODE_BINARY_PATH"; + + private static final String DEFAULT_LOCAL_IP_ADDRESS = "0.0.0.0"; private static final List PATH_CAPABILITIES = ImmutableList.of(AndroidMobileCapabilityType.KEYSTORE_PATH, AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, MobileCapabilityType.APP); - private static final String APPIUM_FOLDER = "appium"; - private static final String BUILD_FOLDER = "build"; - private static final String LIB_FOLDER = "lib"; - private static final String MAIN_JS = "main.js"; - private static final String ERROR_NODE_NOT_FOUND = "There is no installed nodes! Please " - + "install node via NPM (https://www.npmjs.com/package/appium#using-node-js) or download and " - + "install Appium app (http://appium.io/downloads.html)"; - private static final String APPIUM_NODE_MASK = - File.separator + BUILD_FOLDER - + File.separator + LIB_FOLDER - + File.separator + MAIN_JS; + private static final Path APPIUM_PATH_SUFFIX = Paths.get("appium", "build", "lib", "main.js"); public static final int DEFAULT_APPIUM_PORT = 4723; - private static final String BASH = "bash"; - private static final String CMD_EXE = "cmd.exe"; - private static final String NODE = "node"; - final Map serverArguments = new HashMap<>(); + private final Map serverArguments = new HashMap<>(); private File appiumJS; + private File node; private String ipAddress = DEFAULT_LOCAL_IP_ADDRESS; - private File npmScript; - private File getNodeJSExecutable; private DesiredCapabilities capabilities; + private static final Function APPIUM_JS_NOT_EXIST_ERROR = (fullPath) -> String.format( + "The main Appium script does not exist at '%s'", fullPath.getAbsolutePath()); + private static final Function NODE_JS_NOT_EXIST_ERROR = (fullPath) -> + String.format("The main NodeJS executable does not exist at '%s'", fullPath.getAbsolutePath()); - //The first starting is slow sometimes on some - //environment + // The first starting is slow sometimes on some environment private long startupTimeout = 120; private TimeUnit timeUnit = TimeUnit.SECONDS; @@ -108,14 +103,15 @@ public AppiumServiceBuilder() { * "{@code proxy}" don't tend to count to the score). * Higher the score, higher the possibility of getting grid sessions created sooner. */ - @Override public int score(Capabilities capabilites) { + @Override + public int score(Capabilities capabilities) { int score = 0; - if (capabilites.getCapability(PLATFORM_NAME) != null) { + if (capabilities.getCapability(PLATFORM_NAME) != null) { score++; } - String browserName = capabilites.getBrowserName(); + String browserName = capabilities.getBrowserName(); if (browserName.equals(BrowserType.CHROME) || browserName.equals(BrowserType.ANDROID) || browserName.equals(BrowserType.SAFARI)) { score++; @@ -124,120 +120,60 @@ public AppiumServiceBuilder() { return score; } - private static void validateNodeStructure(File node) { - String absoluteNodePath = node.getAbsolutePath(); - - if (!node.exists()) { - throw new InvalidServerInstanceException( - "The invalid appium node " + absoluteNodePath + " has been defined", - new IOException("The node " + absoluteNodePath + "doesn't exist")); + private static File validatePath(@Nullable String fullPath, String errMsg) { + if (fullPath == null) { + throw new InvalidServerInstanceException(errMsg); } - } - - private static void disposeCachedFile(File file) throws Throwable { - if (file != null) { - FileUtils.forceDelete(file); + File result = new File(fullPath); + if (!result.exists()) { + throw new InvalidServerInstanceException(errMsg); } + return result; } - private void setUpNPMScript() { - if (npmScript != null) { - return; - } - - if (!Platform.getCurrent().is(Platform.WINDOWS)) { - npmScript = Scripts.GET_PATH_TO_DEFAULT_NODE_UNIX.getScriptFile(); - } + private static File findBinary(String name, String errMsg) { + return validatePath(new ExecutableFinder().find(name), errMsg); } - private void setUpGetNodeJSExecutableScript() { - if (getNodeJSExecutable != null) { - return; - } - - getNodeJSExecutable = Scripts.GET_NODE_JS_EXECUTABLE.getScriptFile(); + private static File findNpm() { + return findBinary("npm", + "Node Package Manager (npm) is either not installed or its executable is not present in PATH"); } - private File findNodeInCurrentFileSystem() { - setUpNPMScript(); - - String instancePath; - CommandLine commandLine; + private static File findMainScript() { + File npm = findNpm(); + ProcessBuilder pb = new ProcessBuilder(npm.getAbsolutePath(), "root", "-g"); + String nodeModulesRoot; try { - if (Platform.getCurrent().is(Platform.WINDOWS)) { - commandLine = new CommandLine(CMD_EXE, "/C", "npm root -g"); - } else { - commandLine = new CommandLine(BASH, "-l", npmScript.getAbsolutePath()); - } - commandLine.execute(); - } catch (Throwable e) { - throw new RuntimeException(e); + nodeModulesRoot = IOUtils.toString(pb.start().getInputStream(), StandardCharsets.UTF_8).trim(); + } catch (IOException e) { + throw new InvalidServerInstanceException( + "Cannot retrieve the path to the folder where NodeJS modules are located", e); } - - instancePath = (commandLine.getStdOut()).trim(); - try { - File defaultAppiumNode; - if (StringUtils.isBlank(instancePath) || !(defaultAppiumNode = - new File(instancePath + File.separator - + APPIUM_FOLDER)).exists()) { - String errorOutput = commandLine.getStdOut(); - throw new InvalidServerInstanceException(ERROR_NODE_NOT_FOUND, - new IOException(errorOutput)); - } - //appium servers v1.5.x and higher - File result; - if ((result = new File(defaultAppiumNode, APPIUM_NODE_MASK)).exists()) { - return result; - } - - throw new InvalidServerInstanceException(ERROR_NODE_NOT_FOUND, new IOException( - "Could not find a file " + APPIUM_NODE_MASK - + " in the " - + defaultAppiumNode + " directory")); - } finally { - commandLine.destroy(); + File mainAppiumJs = Paths.get(nodeModulesRoot, APPIUM_PATH_SUFFIX.toString()).toFile(); + if (!mainAppiumJs.exists()) { + throw new InvalidServerInstanceException(APPIUM_JS_NOT_EXIST_ERROR.apply(mainAppiumJs)); } + return mainAppiumJs; } - @Override protected File findDefaultExecutable() { - - String nodeJSExec = System.getProperty(NODE_PATH); - if (StringUtils.isBlank(nodeJSExec)) { - nodeJSExec = System.getenv(NODE_PATH); - } - if (!StringUtils.isBlank(nodeJSExec)) { - File result = new File(nodeJSExec); - if (result.exists()) { - return result; - } + @Override + protected File findDefaultExecutable() { + if (this.node != null) { + validatePath(this.node.getAbsolutePath(), NODE_JS_NOT_EXIST_ERROR.apply(this.node)); + return this.node; } - CommandLine commandLine; - setUpGetNodeJSExecutableScript(); - try { - if (Platform.getCurrent().is(Platform.WINDOWS)) { - commandLine = new CommandLine(NODE + ".exe", getNodeJSExecutable.getAbsolutePath()); - } else { - commandLine = new CommandLine(NODE, getNodeJSExecutable.getAbsolutePath()); - } - commandLine.execute(); - } catch (Throwable t) { - throw new InvalidNodeJSInstance("Node.js is not installed!", t); + File node = loadPathFromEnv(NODE_PATH); + if (node != null) { + validatePath(node.getAbsolutePath(), NODE_JS_NOT_EXIST_ERROR.apply(node)); + this.node = node; + return this.node; } - - String filePath = (commandLine.getStdOut()).trim(); - - try { - if (StringUtils.isBlank(filePath) || !new File(filePath).exists()) { - String errorOutput = commandLine.getStdOut(); - String errorMessage = "Can't get a path to the default Node.js instance"; - throw new InvalidNodeJSInstance(errorMessage, new IOException(errorOutput)); - } - return new File(filePath); - } finally { - commandLine.destroy(); - } + this.node = findBinary("node", + "NodeJS is either not installed or its executable not present in PATH"); + return this.node; } /** @@ -264,14 +200,22 @@ public AppiumServiceBuilder withArgument(ServerArgument argument) { */ public AppiumServiceBuilder withArgument(ServerArgument argument, String value) { String argName = argument.getArgument().trim().toLowerCase(); - if ("--port".equals(argName) || "-p".equals(argName)) { - usingPort(Integer.valueOf(value)); - } else if ("--address".equals(argName) || "-a".equals(argName)) { - withIPAddress(value); - } else if ("--log".equals(argName) || "-g".equals(argName)) { - withLogFile(new File(value)); - } else { - serverArguments.put(argName, value); + switch (argName) { + case "--port": + case "-p": + usingPort(Integer.parseInt(value)); + break; + case "--address": + case "-a": + withIPAddress(value); + break; + case "--log": + case "-g": + withLogFile(new File(value)); + break; + default: + serverArguments.put(argName, value); + break; } return this; } @@ -325,24 +269,29 @@ public AppiumServiceBuilder withStartUpTimeOut(long time, TimeUnit timeUnit) { return this; } - private void checkAppiumJS() { - if (appiumJS != null) { - validateNodeStructure(appiumJS); - return; + @Nullable + private static File loadPathFromEnv(String envVarName) { + String fullPath = System.getProperty(envVarName); + if (StringUtils.isBlank(fullPath)) { + fullPath = System.getenv(envVarName); } + return StringUtils.isBlank(fullPath) ? null : new File(fullPath); + } - String appiumJS = System.getProperty(APPIUM_PATH); - if (StringUtils.isBlank(appiumJS)) { - appiumJS = System.getenv(APPIUM_PATH); + private void loadPathToMainScript() { + if (this.appiumJS != null) { + validatePath(this.appiumJS.getAbsolutePath(), APPIUM_JS_NOT_EXIST_ERROR.apply(this.appiumJS)); + return; } - if (!StringUtils.isBlank(appiumJS)) { - File node = new File(appiumJS); - validateNodeStructure(node); - this.appiumJS = node; + + File mainScript = loadPathFromEnv(APPIUM_PATH); + if (mainScript != null) { + validatePath(mainScript.getAbsolutePath(), APPIUM_JS_NOT_EXIST_ERROR.apply(mainScript)); + this.appiumJS = mainScript; return; } - this.appiumJS = findNodeInCurrentFileSystem(); + this.appiumJS = findMainScript(); } private String parseCapabilitiesIfWindows() { @@ -363,13 +312,13 @@ private String parseCapabilitiesIfWindows() { if (PATH_CAPABILITIES.contains(entry.getKey())) { value = "\\\"" + String.valueOf(value).replace("\\", "/") + "\\\""; } else { - value = "\\\"" + String.valueOf(value) + "\\\""; + value = "\\\"" + value + "\\\""; } } else { value = String.valueOf(value); } - String key = "\\\"" + String.valueOf(entry.getKey()) + "\\\""; + String key = "\\\"" + entry.getKey() + "\\\""; if (StringUtils.isBlank(result)) { result = key + ": " + value; } else { @@ -396,12 +345,12 @@ private String parseCapabilitiesIfUNIX() { } if (String.class.isAssignableFrom(value.getClass())) { - value = "\"" + String.valueOf(value) + "\""; + value = "\"" + value + "\""; } else { value = String.valueOf(value); } - String key = "\"" + String.valueOf(entry.getKey()) + "\""; + String key = "\"" + entry.getKey() + "\""; if (StringUtils.isBlank(result)) { result = key + ": " + value; } else { @@ -412,7 +361,7 @@ private String parseCapabilitiesIfUNIX() { return "{" + result + "}"; } - + private String parseCapabilities() { if (Platform.getCurrent().is(Platform.WINDOWS)) { return parseCapabilitiesIfWindows(); @@ -420,9 +369,10 @@ private String parseCapabilities() { return parseCapabilitiesIfUNIX(); } - @Override protected ImmutableList createArgs() { + @Override + protected ImmutableList createArgs() { List argList = new ArrayList<>(); - checkAppiumJS(); + loadPathToMainScript(); argList.add(appiumJS.getAbsolutePath()); argList.add("--port"); argList.add(String.valueOf(getPort())); @@ -432,7 +382,7 @@ private String parseCapabilities() { } else { InetAddressValidator validator = InetAddressValidator.getInstance(); if (!validator.isValid(ipAddress) && !validator.isValidInet4Address(ipAddress) - && !validator.isValidInet6Address(ipAddress)) { + && !validator.isValidInet6Address(ipAddress)) { throw new IllegalArgumentException( "The invalid IP address " + ipAddress + " is defined"); } @@ -508,7 +458,8 @@ public AppiumServiceBuilder usingAnyFreePort() { * appium server with. * @return A self reference. */ - @Override public AppiumServiceBuilder withEnvironment(Map environment) { + @Override + public AppiumServiceBuilder withEnvironment(Map environment) { return super.withEnvironment(environment); } @@ -525,21 +476,12 @@ public AppiumServiceBuilder withLogFile(File logFile) { @Override protected AppiumDriverLocalService createDriverService(File nodeJSExecutable, int nodeJSPort, - ImmutableList nodeArguments, ImmutableMap nodeEnvironment) { + ImmutableList nodeArguments, ImmutableMap nodeEnvironment) { try { return new AppiumDriverLocalService(ipAddress, nodeJSExecutable, nodeJSPort, - nodeArguments, nodeEnvironment, startupTimeout, timeUnit); + nodeArguments, nodeEnvironment, startupTimeout, timeUnit); } catch (IOException e) { throw new RuntimeException(e); } } - - @Override protected void finalize() throws Throwable { - try { - disposeCachedFile(npmScript); - disposeCachedFile(getNodeJSExecutable); - } finally { - super.finalize(); - } - } } diff --git a/src/main/java/io/appium/java_client/service/local/InvalidServerInstanceException.java b/src/main/java/io/appium/java_client/service/local/InvalidServerInstanceException.java index 9b7498407..6addfbd33 100644 --- a/src/main/java/io/appium/java_client/service/local/InvalidServerInstanceException.java +++ b/src/main/java/io/appium/java_client/service/local/InvalidServerInstanceException.java @@ -21,9 +21,11 @@ public class InvalidServerInstanceException extends RuntimeException { private static final long serialVersionUID = 1L; - private static String MESSAGE_PREFIX = "Invalid server instance exception has occured: "; + public InvalidServerInstanceException(String message, Throwable t) { + super(message, t); + } - public InvalidServerInstanceException(String messege, Throwable t) { - super(MESSAGE_PREFIX + messege, t); + public InvalidServerInstanceException(String message) { + super(message); } } diff --git a/src/main/java/io/appium/java_client/service/local/Scripts.java b/src/main/java/io/appium/java_client/service/local/Scripts.java deleted file mode 100644 index 042654e03..000000000 --- a/src/main/java/io/appium/java_client/service/local/Scripts.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * 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 io.appium.java_client.service.local; - -import org.apache.commons.io.IOUtils; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - - -enum Scripts { - GET_PATH_TO_DEFAULT_NODE_UNIX("get_path_to_default_node.sh"), - GET_NODE_JS_EXECUTABLE("getExe.js"); - private static final String RESOURCE_FOLDER = "/scripts/"; - private final String script; - - Scripts(String script) { - this.script = script; - } - - public File getScriptFile() { - InputStream inputStream = getClass().getResourceAsStream(RESOURCE_FOLDER + this.script); - byte[] bytes; - try { - bytes = IOUtils.toByteArray(inputStream); - } catch (IOException e) { - throw new RuntimeException(e); - } - - String[] splittedName = this.script.split("\\."); - File scriptFile; - try { - scriptFile = File.createTempFile(splittedName[0], "." + splittedName[1]); - } catch (IOException e) { - throw new RuntimeException(e); - } - - if (!scriptFile.exists()) { - try { - scriptFile.createNewFile(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - FileOutputStream output; - try { - output = new FileOutputStream(scriptFile, true); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - - try { - output.write(bytes); - output.flush(); - output.close(); - return scriptFile; - } catch (IOException e) { - throw new RuntimeException(e); - } - - } -} diff --git a/src/main/resources/scripts/getExe.js b/src/main/resources/scripts/getExe.js deleted file mode 100644 index 15cfdb975..000000000 --- a/src/main/resources/scripts/getExe.js +++ /dev/null @@ -1 +0,0 @@ -console.log(process.execPath); \ No newline at end of file diff --git a/src/main/resources/scripts/get_path_to_default_node.sh b/src/main/resources/scripts/get_path_to_default_node.sh deleted file mode 100644 index fce4693ea..000000000 --- a/src/main/resources/scripts/get_path_to_default_node.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!bin/sh -OUTPUT="$(npm root -g)" -echo "${OUTPUT}" -exit \ No newline at end of file From 5efc9b021e199221e7b6e56ddbf6274247190569 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 17 Oct 2019 22:00:02 +0200 Subject: [PATCH 2/6] Make linter happy --- .../appium/java_client/service/local/AppiumServiceBuilder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java index c7633f2b6..de727d0b4 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java @@ -476,7 +476,8 @@ public AppiumServiceBuilder withLogFile(File logFile) { @Override protected AppiumDriverLocalService createDriverService(File nodeJSExecutable, int nodeJSPort, - ImmutableList nodeArguments, ImmutableMap nodeEnvironment) { + ImmutableList nodeArguments, + ImmutableMap nodeEnvironment) { try { return new AppiumDriverLocalService(ipAddress, nodeJSExecutable, nodeJSPort, nodeArguments, nodeEnvironment, startupTimeout, timeUnit); From a07aa886b4e3ac848219ec600e9b6fc08e10167d Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 17 Oct 2019 22:09:03 +0200 Subject: [PATCH 3/6] Fix Windows command line --- .../java_client/service/local/AppiumServiceBuilder.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java index de727d0b4..9bf6cfc9d 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java @@ -29,6 +29,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.SystemUtils; import org.apache.commons.validator.routines.InetAddressValidator; import org.openqa.selenium.Capabilities; import org.openqa.selenium.Platform; @@ -45,6 +46,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -142,7 +144,11 @@ private static File findNpm() { private static File findMainScript() { File npm = findNpm(); - ProcessBuilder pb = new ProcessBuilder(npm.getAbsolutePath(), "root", "-g"); + List cmdLine = SystemUtils.IS_OS_WINDOWS + // npm is a batch script, so on windows we need to use cmd.exe in order to execute it + ? Arrays.asList("cmd.exe", "/c", String.format("\"%s\" root -g", npm.getAbsolutePath())) + : Arrays.asList(npm.getAbsolutePath(), "root", "-g"); + ProcessBuilder pb = new ProcessBuilder(cmdLine); String nodeModulesRoot; try { nodeModulesRoot = IOUtils.toString(pb.start().getInputStream(), StandardCharsets.UTF_8).trim(); From 5dadc23284252c01968d8fed30fb59172adde0c8 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 18 Oct 2019 09:07:50 +0200 Subject: [PATCH 4/6] Update tests --- .../local/AppiumDriverLocalService.java | 59 +++++----- .../service/local/AppiumServiceBuilder.java | 6 +- .../service/local/ServerBuilderTest.java | 106 ++++++++++-------- 3 files changed, 91 insertions(+), 80 deletions(-) diff --git a/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java b/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java index a7fd502b2..69de4ddbe 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java @@ -17,6 +17,7 @@ package io.appium.java_client.service.local; import static com.google.common.base.Preconditions.checkNotNull; +import static io.appium.java_client.service.local.AppiumServiceBuilder.BROADCAST_IP_ADDRESS; import static org.slf4j.event.Level.DEBUG; import static org.slf4j.event.Level.INFO; @@ -67,8 +68,8 @@ public final class AppiumDriverLocalService extends DriverService { private CommandLine process = null; AppiumDriverLocalService(String ipAddress, File nodeJSExec, int nodeJSPort, - ImmutableList nodeJSArgs, ImmutableMap nodeJSEnvironment, - long startupTimeout, TimeUnit timeUnit) throws IOException { + ImmutableList nodeJSArgs, ImmutableMap nodeJSEnvironment, + long startupTimeout, TimeUnit timeUnit) throws IOException { super(nodeJSExec, nodeJSPort, nodeJSArgs, nodeJSEnvironment); this.nodeJSExec = nodeJSExec; this.nodeJSArgs = nodeJSArgs; @@ -91,11 +92,13 @@ public static AppiumDriverLocalService buildService(AppiumServiceBuilder builder * * @return The base URL for the managed appium server. */ - @Override public URL getUrl() { + @Override + public URL getUrl() { return url; } - @Override public boolean isRunning() { + @Override + public boolean isRunning() { lock.lock(); try { if (process == null) { @@ -121,15 +124,15 @@ public static AppiumDriverLocalService buildService(AppiumServiceBuilder builder } private void ping(long time, TimeUnit timeUnit) throws UrlChecker.TimeoutException, MalformedURLException { - URL status = new URL(url.toString() + "/status"); + // 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"); new UrlChecker().waitUntilAvailable(time, timeUnit, status); } /** * Starts the defined appium server. * - * @throws AppiumServerHasNotBeenStartedLocallyException - * If an error occurs while spawning the child process. + * @throws AppiumServerHasNotBeenStartedLocallyException If an error occurs while spawning the child process. * @see #stop() */ public void start() throws AppiumServerHasNotBeenStartedLocallyException { @@ -141,7 +144,7 @@ public void start() throws AppiumServerHasNotBeenStartedLocallyException { try { process = new CommandLine(this.nodeJSExec.getCanonicalPath(), - nodeJSArgs.toArray(new String[] {})); + nodeJSArgs.toArray(new String[]{})); process.setEnvironmentVariables(nodeJSEnvironment); process.copyOutputTo(stream); process.executeAsync(); @@ -149,8 +152,8 @@ public void start() throws AppiumServerHasNotBeenStartedLocallyException { } catch (Throwable e) { destroyProcess(); String msgTxt = "The local appium server has not been started. " - + "The given Node.js executable: " + this.nodeJSExec.getAbsolutePath() - + " Arguments: " + nodeJSArgs.toString() + " " + "\n"; + + "The given Node.js executable: " + this.nodeJSExec.getAbsolutePath() + + " Arguments: " + nodeJSArgs.toString() + " " + "\n"; if (process != null) { String processStream = process.getStdOut(); if (!StringUtils.isBlank(processStream)) { @@ -171,7 +174,8 @@ public void start() throws AppiumServerHasNotBeenStartedLocallyException { * * @see #start() */ - @Override public void stop() { + @Override + public void stop() { lock.lock(); try { if (process != null) { @@ -193,7 +197,7 @@ private void destroyProcess() { * Logs as string. * * @return String logs if the server has been run. - * null is returned otherwise. + * null is returned otherwise. */ @Nullable public String getStdOut() { @@ -206,6 +210,7 @@ public String getStdOut() { /** * Adds other output stream which should accept server output data. + * * @param outputStream is an instance of {@link OutputStream} * that is ready to accept server output */ @@ -216,6 +221,7 @@ public void addOutPutStream(OutputStream outputStream) { /** * Adds other output streams which should accept server output data. + * * @param outputStreams is a list of additional {@link OutputStream} * that are ready to accept server output */ @@ -240,12 +246,12 @@ public boolean clearOutPutStreams() { * SLF4J loggers. This allow server output * data to be configured with your preferred logging frameworks (e.g. * java.util.logging, logback, log4j). - * + * *

NOTE1: You might want to call method {@link #clearOutPutStreams()} before * calling this method.
* NOTE2: it is required that {@code --log-timestamp} server flag is * {@code false}. - * + * *

By default log messages are: *

    *
  • logged at {@code INFO} level, unless log message is pre-fixed by @@ -262,7 +268,7 @@ public boolean clearOutPutStreams() { * is logged by logger {@code appium.service.xcuitest} at level * {@code DEBUG}. *
    - * + * * @see #addSlf4jLogMessageConsumer(BiConsumer) */ public void enableDefaultSlf4jLoggingOfOutputData() { @@ -280,14 +286,14 @@ public void enableDefaultSlf4jLoggingOfOutputData() { * message is parsed for its slf4j context (logger name, logger level etc.) * and the specified {@code BiConsumer} is invoked with the log message and * slf4j context. - * + * *

    Use this method only if you want a behavior that differentiates from the * default behavior as enabled by method * {@link #enableDefaultSlf4jLoggingOfOutputData()}. - * + * *

    NOTE: You might want to call method {@link #clearOutPutStreams()} before * calling this method. - * + * *

    implementation detail: *

      *
    • if log message begins with {@code [debug]} then log level is set to @@ -302,10 +308,9 @@ public void enableDefaultSlf4jLoggingOfOutputData() { * Example log-message: "[debug] [XCUITest] Xcode version set to 'x.y.z' " * is logged by {@code appium.service.xcuitest} at level {@code DEBUG} *
      - * - * @param slf4jLogMessageConsumer - * BiConsumer block to be executed when a log message is - * available. + * + * @param slf4jLogMessageConsumer BiConsumer block to be executed when a log message is + * available. */ public void addSlf4jLogMessageConsumer(BiConsumer slf4jLogMessageConsumer) { checkNotNull(slf4jLogMessageConsumer, "slf4jLogMessageConsumer parameter is NULL!"); @@ -331,17 +336,15 @@ static Slf4jLogMessageContext parseSlf4jContextFromLogMessage(String logMessage) /** * When a complete log message is available (from server output data), the * specified {@code Consumer} is invoked with that log message. - * + * *

      NOTE: You might want to call method {@link #clearOutPutStreams()} before * calling this method. - * + * *

      If the Consumer fails and throws an exception the exception is logged (at * WARN level) and execution continues. *
      - * - * @param consumer - * Consumer block to be executed when a log message is available. - * + * + * @param consumer Consumer block to be executed when a log message is available. */ public void addLogMessageConsumer(Consumer consumer) { checkNotNull(consumer, "consumer parameter is NULL!"); diff --git a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java index 9bf6cfc9d..10fdefe56 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java @@ -72,7 +72,7 @@ public final class AppiumServiceBuilder */ private static final String NODE_PATH = "NODE_BINARY_PATH"; - private static final String DEFAULT_LOCAL_IP_ADDRESS = "0.0.0.0"; + public static final String BROADCAST_IP_ADDRESS = "0.0.0.0"; private static final List PATH_CAPABILITIES = ImmutableList.of(AndroidMobileCapabilityType.KEYSTORE_PATH, AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, MobileCapabilityType.APP); private static final Path APPIUM_PATH_SUFFIX = Paths.get("appium", "build", "lib", "main.js"); @@ -80,7 +80,7 @@ public final class AppiumServiceBuilder private final Map serverArguments = new HashMap<>(); private File appiumJS; private File node; - private String ipAddress = DEFAULT_LOCAL_IP_ADDRESS; + private String ipAddress = BROADCAST_IP_ADDRESS; private DesiredCapabilities capabilities; private static final Function APPIUM_JS_NOT_EXIST_ERROR = (fullPath) -> String.format( "The main Appium script does not exist at '%s'", fullPath.getAbsolutePath()); @@ -384,7 +384,7 @@ protected ImmutableList createArgs() { argList.add(String.valueOf(getPort())); if (StringUtils.isBlank(ipAddress)) { - ipAddress = DEFAULT_LOCAL_IP_ADDRESS; + ipAddress = BROADCAST_IP_ADDRESS; } else { InetAddressValidator validator = InetAddressValidator.getInstance(); if (!validator.isValid(ipAddress) && !validator.isValidInet4Address(ipAddress) diff --git a/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java b/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java index 357f3c2de..89ed50be2 100644 --- a/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java +++ b/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java @@ -27,7 +27,6 @@ import static org.junit.Assert.assertTrue; import io.github.bonigarcia.wdm.WebDriverManager; -import org.apache.commons.validator.routines.InetAddressValidator; import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; @@ -36,11 +35,12 @@ import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; +import java.net.DatagramSocket; import java.net.InetAddress; -import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; public class ServerBuilderTest { @@ -67,32 +67,20 @@ public class ServerBuilderTest { private OutputStream stream; private static WebDriverManager chromeManager; - private static String getLocalIP(NetworkInterface intf) { - for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr - .hasMoreElements(); ) { - InetAddress inetAddress = enumIpAddr.nextElement(); - if (!inetAddress.isLoopbackAddress()) { - InetAddressValidator validator = InetAddressValidator.getInstance(); - String calculated = inetAddress.getHostAddress(); - if (validator.isValid(calculated)) { - return calculated; - } - } + private static String getLocalIp4Address() throws SocketException, UnknownHostException { + // https://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java + try (final DatagramSocket socket = new DatagramSocket()) { + socket.connect(InetAddress.getByName("8.8.8.8"), 10002); + return socket.getLocalAddress().getHostAddress(); } - return null; } /** * initialization. */ - @BeforeClass public static void beforeClass() throws Exception { - for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en - .hasMoreElements(); ) { - NetworkInterface intf = en.nextElement(); - if ((testIP = getLocalIP(intf)) != null) { - break; - } - } + @BeforeClass + public static void beforeClass() throws Exception { + testIP = getLocalIp4Address(); chromeManager = chromedriver(); chromeManager.setup(); } @@ -115,7 +103,8 @@ public void tearDown() throws Exception { ofNullable(PATH_TO_APPIUM_NODE_IN_PROPERTIES).ifPresent(s -> setProperty(APPIUM_PATH, s)); } - @Test public void checkAbilityToAddLogMessageConsumer() { + @Test + public void checkAbilityToAddLogMessageConsumer() { List log = new ArrayList<>(); service = buildDefaultService(); service.clearOutPutStreams(); @@ -124,19 +113,22 @@ public void tearDown() throws Exception { assertTrue(log.size() > 0); } - @Test public void checkAbilityToStartDefaultService() { + @Test + public void checkAbilityToStartDefaultService() { service = buildDefaultService(); service.start(); assertTrue(service.isRunning()); } - @Test public void checkAbilityToFindNodeDefinedInProperties() { + @Test + public void checkAbilityToFindNodeDefinedInProperties() { File definedNode = PATH_T0_TEST_MAIN_JS.toFile(); setProperty(APPIUM_PATH, definedNode.getAbsolutePath()); assertThat(new AppiumServiceBuilder().createArgs().get(0), is(definedNode.getAbsolutePath())); } - @Test public void checkAbilityToUseNodeDefinedExplicitly() { + @Test + public void checkAbilityToUseNodeDefinedExplicitly() { File mainJS = PATH_T0_TEST_MAIN_JS.toFile(); AppiumServiceBuilder builder = new AppiumServiceBuilder() .withAppiumJS(mainJS); @@ -144,29 +136,33 @@ public void tearDown() throws Exception { is(mainJS.getAbsolutePath())); } - @Test public void checkAbilityToStartServiceOnAFreePort() { + @Test + public void checkAbilityToStartServiceOnAFreePort() { service = new AppiumServiceBuilder().usingAnyFreePort().build(); service.start(); assertTrue(service.isRunning()); } - @Test public void checkAbilityToStartServiceUsingNonLocalhostIP() { + @Test + public void checkAbilityToStartServiceUsingNonLocalhostIP() { service = new AppiumServiceBuilder().withIPAddress(testIP).build(); service.start(); assertTrue(service.isRunning()); } - @Test public void checkAbilityToStartServiceUsingFlags() { + @Test + public void checkAbilityToStartServiceUsingFlags() { service = new AppiumServiceBuilder() - .withArgument(CALLBACK_ADDRESS, testIP) - .withArgument(SESSION_OVERRIDE) - .withArgument(PRE_LAUNCH) - .build(); + .withArgument(CALLBACK_ADDRESS, testIP) + .withArgument(SESSION_OVERRIDE) + .withArgument(PRE_LAUNCH) + .build(); service.start(); assertTrue(service.isRunning()); } - @Test public void checkAbilityToStartServiceUsingCapabilities() { + @Test + public void checkAbilityToStartServiceUsingCapabilities() { File app = ROOT_TEST_PATH.resolve("ApiDemos-debug.apk").toFile(); DesiredCapabilities caps = new DesiredCapabilities(); @@ -183,7 +179,8 @@ public void tearDown() throws Exception { assertTrue(service.isRunning()); } - @Test public void checkAbilityToStartServiceUsingCapabilitiesAndFlags() { + @Test + public void checkAbilityToStartServiceUsingCapabilitiesAndFlags() { File app = ROOT_TEST_PATH.resolve("ApiDemos-debug.apk").toFile(); DesiredCapabilities caps = new DesiredCapabilities(); @@ -204,7 +201,8 @@ public void tearDown() throws Exception { assertTrue(service.isRunning()); } - @Test public void checkAbilityToChangeOutputStream() throws Exception { + @Test + public void checkAbilityToChangeOutputStream() throws Exception { testLogFile = new File("test"); testLogFile.createNewFile(); stream = new FileOutputStream(testLogFile); @@ -214,7 +212,8 @@ public void tearDown() throws Exception { assertThat(testLogFile.length(), greaterThan(0L)); } - @Test public void checkAbilityToChangeOutputStreamAfterTheServiceIsStarted() throws Exception { + @Test + public void checkAbilityToChangeOutputStreamAfterTheServiceIsStarted() throws Exception { testLogFile = new File("test"); testLogFile.createNewFile(); stream = new FileOutputStream(testLogFile); @@ -225,14 +224,16 @@ public void tearDown() throws Exception { assertThat(testLogFile.length(), greaterThan(0L)); } - @Test public void checkAbilityToShutDownService() { + @Test + public void checkAbilityToShutDownService() { service = buildDefaultService(); service.start(); service.stop(); assertFalse(service.isRunning()); } - @Test public void checkAbilityToStartAndShutDownFewServices() throws Exception { + @Test + public void checkAbilityToStartAndShutDownFewServices() throws Exception { List services = asList( new AppiumServiceBuilder().usingAnyFreePort().build(), new AppiumServiceBuilder().usingAnyFreePort().build(), @@ -245,7 +246,8 @@ public void tearDown() throws Exception { assertTrue(services.stream().noneMatch(AppiumDriverLocalService::isRunning)); } - @Test public void checkAbilityToStartServiceWithLogFile() throws Exception { + @Test + public void checkAbilityToStartServiceWithLogFile() throws Exception { testLogFile = new File("Log.txt"); testLogFile.createNewFile(); service = new AppiumServiceBuilder().withLogFile(testLogFile).build(); @@ -254,7 +256,8 @@ public void tearDown() throws Exception { assertThat(testLogFile.length(), greaterThan(0L)); } - @Test public void checkAbilityToStartServiceWithPortUsingFlag() { + @Test + public void checkAbilityToStartServiceWithPortUsingFlag() { String port = "8996"; String expectedUrl = String.format("http://0.0.0.0:%s/wd/hub", port); @@ -265,8 +268,9 @@ public void tearDown() throws Exception { assertEquals(expectedUrl, actualUrl); service.start(); } - - @Test public void checkAbilityToStartServiceWithPortUsingShortFlag() { + + @Test + public void checkAbilityToStartServiceWithPortUsingShortFlag() { String port = "8996"; String expectedUrl = String.format("http://0.0.0.0:%s/wd/hub", port); @@ -278,7 +282,8 @@ public void tearDown() throws Exception { service.start(); } - @Test public void checkAbilityToStartServiceWithIpUsingFlag() { + @Test + public void checkAbilityToStartServiceWithIpUsingFlag() { String expectedUrl = String.format("http://%s:4723/wd/hub", testIP); service = new AppiumServiceBuilder() @@ -289,7 +294,8 @@ public void tearDown() throws Exception { service.start(); } - @Test public void checkAbilityToStartServiceWithIpUsingShortFlag() { + @Test + public void checkAbilityToStartServiceWithIpUsingShortFlag() { String expectedUrl = String.format("http://%s:4723/wd/hub", testIP); service = new AppiumServiceBuilder() @@ -300,7 +306,8 @@ public void tearDown() throws Exception { service.start(); } - @Test public void checkAbilityToStartServiceWithLogFileUsingFlag() { + @Test + public void checkAbilityToStartServiceWithLogFileUsingFlag() { testLogFile = new File("Log2.txt"); service = new AppiumServiceBuilder() @@ -310,9 +317,10 @@ public void tearDown() throws Exception { assertTrue(testLogFile.exists()); } - @Test public void checkAbilityToStartServiceWithLogFileUsingShortFlag() { + @Test + public void checkAbilityToStartServiceWithLogFileUsingShortFlag() { testLogFile = new File("Log3.txt"); - + service = new AppiumServiceBuilder() .withArgument(() -> "-g", testLogFile.getAbsolutePath()) .build(); From ad44944f017fab7831b19fb3cad1cfbba7c21d32 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 18 Oct 2019 09:11:00 +0200 Subject: [PATCH 5/6] Fix style --- .../java_client/service/local/AppiumDriverLocalService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java b/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java index 69de4ddbe..c3f9e0389 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java @@ -196,8 +196,7 @@ private void destroyProcess() { /** * Logs as string. * - * @return String logs if the server has been run. - * null is returned otherwise. + * @return String logs if the server has been run. Null is returned otherwise. */ @Nullable public String getStdOut() { From 0cf63e74ac4e5906506fcacbb999b3fa4d478564 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 18 Oct 2019 21:11:39 +0200 Subject: [PATCH 6/6] Update tests --- .../java/io/appium/java_client/TestUtils.java | 16 ++++++++++++++++ .../io/appium/java_client/ios/AppIOSTest.java | 4 +--- .../io/appium/java_client/ios/BaseIOSTest.java | 12 ++++++------ .../java_client/ios/BaseIOSWebViewTest.java | 5 ++--- .../appium/java_client/ios/BaseSafariTest.java | 5 ++--- .../appium/java_client/ios/UICatalogIOSTest.java | 5 ++--- .../service/local/ServerBuilderTest.java | 13 +------------ 7 files changed, 30 insertions(+), 30 deletions(-) create mode 100644 src/test/java/io/appium/java_client/TestUtils.java diff --git a/src/test/java/io/appium/java_client/TestUtils.java b/src/test/java/io/appium/java_client/TestUtils.java new file mode 100644 index 000000000..cd6e3dd44 --- /dev/null +++ b/src/test/java/io/appium/java_client/TestUtils.java @@ -0,0 +1,16 @@ +package io.appium.java_client; + +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +public class TestUtils { + public static String getLocalIp4Address() throws SocketException, UnknownHostException { + // https://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java + try (final DatagramSocket socket = new DatagramSocket()) { + socket.connect(InetAddress.getByName("8.8.8.8"), 10002); + return socket.getLocalAddress().getHostAddress(); + } + } +} diff --git a/src/test/java/io/appium/java_client/ios/AppIOSTest.java b/src/test/java/io/appium/java_client/ios/AppIOSTest.java index 891d3711f..b4b47247c 100644 --- a/src/test/java/io/appium/java_client/ios/AppIOSTest.java +++ b/src/test/java/io/appium/java_client/ios/AppIOSTest.java @@ -8,16 +8,14 @@ import org.openqa.selenium.remote.DesiredCapabilities; import java.io.File; -import java.net.MalformedURLException; import java.net.URL; -import java.net.UnknownHostException; public class AppIOSTest extends BaseIOSTest { public static final String BUNDLE_ID = "io.appium.TestApp"; @BeforeClass - public static void beforeClass() throws UnknownHostException, MalformedURLException { + public static void beforeClass() throws Exception { final String ip = startAppiumServer(); if (service == null || !service.isRunning()) { diff --git a/src/test/java/io/appium/java_client/ios/BaseIOSTest.java b/src/test/java/io/appium/java_client/ios/BaseIOSTest.java index 695a9cb5d..45e7a8e2e 100644 --- a/src/test/java/io/appium/java_client/ios/BaseIOSTest.java +++ b/src/test/java/io/appium/java_client/ios/BaseIOSTest.java @@ -20,9 +20,11 @@ import io.appium.java_client.service.local.AppiumServiceBuilder; import org.junit.AfterClass; -import java.net.InetAddress; +import java.net.SocketException; import java.net.UnknownHostException; +import static io.appium.java_client.TestUtils.getLocalIp4Address; + public class BaseIOSTest { protected static AppiumDriverLocalService service; @@ -40,12 +42,10 @@ public class BaseIOSTest { * @return ip of a local host * @throws UnknownHostException when it is impossible to get ip address of a local host */ - public static String startAppiumServer() throws UnknownHostException { - service = new AppiumServiceBuilder() - .usingPort(PORT).build(); + public static String startAppiumServer() throws UnknownHostException, SocketException { + service = new AppiumServiceBuilder().usingPort(PORT).build(); service.start(); - InetAddress inetAddress = InetAddress.getLocalHost(); - return inetAddress.getHostAddress(); + return getLocalIp4Address(); } /** diff --git a/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java b/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java index d4a35adab..a608177ba 100644 --- a/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java +++ b/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java @@ -23,13 +23,12 @@ import org.openqa.selenium.remote.DesiredCapabilities; import java.io.File; -import java.net.MalformedURLException; +import java.io.IOException; import java.net.URL; -import java.net.UnknownHostException; public class BaseIOSWebViewTest extends BaseIOSTest { - @BeforeClass public static void beforeClass() throws UnknownHostException, MalformedURLException { + @BeforeClass public static void beforeClass() throws IOException { final String ip = startAppiumServer(); if (service == null || !service.isRunning()) { diff --git a/src/test/java/io/appium/java_client/ios/BaseSafariTest.java b/src/test/java/io/appium/java_client/ios/BaseSafariTest.java index a47adb19d..e58af254b 100644 --- a/src/test/java/io/appium/java_client/ios/BaseSafariTest.java +++ b/src/test/java/io/appium/java_client/ios/BaseSafariTest.java @@ -24,13 +24,12 @@ import org.junit.BeforeClass; import org.openqa.selenium.remote.DesiredCapabilities; -import java.net.MalformedURLException; +import java.io.IOException; import java.net.URL; -import java.net.UnknownHostException; public class BaseSafariTest extends BaseIOSTest { - @BeforeClass public static void beforeClass() throws UnknownHostException, MalformedURLException { + @BeforeClass public static void beforeClass() throws IOException { final String ip = startAppiumServer(); if (service == null || !service.isRunning()) { diff --git a/src/test/java/io/appium/java_client/ios/UICatalogIOSTest.java b/src/test/java/io/appium/java_client/ios/UICatalogIOSTest.java index 1e0c11d4f..ff6e4b5a5 100644 --- a/src/test/java/io/appium/java_client/ios/UICatalogIOSTest.java +++ b/src/test/java/io/appium/java_client/ios/UICatalogIOSTest.java @@ -7,14 +7,13 @@ import org.openqa.selenium.remote.DesiredCapabilities; import java.io.File; -import java.net.MalformedURLException; +import java.io.IOException; import java.net.URL; -import java.net.UnknownHostException; public class UICatalogIOSTest extends BaseIOSTest { @BeforeClass - public static void beforeClass() throws UnknownHostException, MalformedURLException { + public static void beforeClass() throws IOException { final String ip = startAppiumServer(); if (service == null || !service.isRunning()) { diff --git a/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java b/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java index 89ed50be2..8df6ac856 100644 --- a/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java +++ b/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java @@ -1,5 +1,6 @@ package io.appium.java_client.service.local; +import static io.appium.java_client.TestUtils.getLocalIp4Address; import static io.appium.java_client.remote.AndroidMobileCapabilityType.APP_ACTIVITY; import static io.appium.java_client.remote.AndroidMobileCapabilityType.APP_PACKAGE; import static io.appium.java_client.remote.AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE; @@ -35,10 +36,6 @@ import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.SocketException; -import java.net.UnknownHostException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -67,14 +64,6 @@ public class ServerBuilderTest { private OutputStream stream; private static WebDriverManager chromeManager; - private static String getLocalIp4Address() throws SocketException, UnknownHostException { - // https://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java - try (final DatagramSocket socket = new DatagramSocket()) { - socket.connect(InetAddress.getByName("8.8.8.8"), 10002); - return socket.getLocalAddress().getHostAddress(); - } - } - /** * initialization. */