diff --git a/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Command.java b/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Command.java index 05603e01..b5bf91aa 100644 --- a/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Command.java +++ b/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Command.java @@ -28,7 +28,7 @@ */ public class Command { - List command; + private List command; public Command() { command = new ArrayList(); @@ -155,7 +155,7 @@ public Command addAsString(String tokens) { } /** - * Deletes all multiple space and preserve original sense of the text input. + * Deletes all multiple spaces and preserve original sense of the text input. * * @param text * @return {@code text} without multiple spaces @@ -214,6 +214,10 @@ public List getAsList() { return command; } + public String[] getAsArray() { + return getAsList().toArray(new String[0]); + } + public String getAsString() { StringBuilder sb = new StringBuilder(); for (String s : command) { @@ -237,6 +241,28 @@ public String get(int i) { } } + /** + * + * @return last token from the command + */ + public String getLast() { + if (command.isEmpty()) { + return null; + } + return command.get(command.size() - 1); + } + + /** + * + * @return first token from the command + */ + public String getFirst() { + if (command.isEmpty()) { + return null; + } + return command.get(0); + } + @Override public String toString() { return getAsString(); diff --git a/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Validate.java b/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Validate.java index 079693d5..678b9895 100644 --- a/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Validate.java +++ b/droidium-container/arquillian-droidium-container-impl/src/main/java/org/arquillian/droidium/container/configuration/Validate.java @@ -360,4 +360,5 @@ public static void isWriteable(final File file, String message) throws IllegalAr throw new IllegalArgumentException(message); } } + } diff --git a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationHelper.java b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationHelper.java index 7241159a..fb220f84 100644 --- a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationHelper.java +++ b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationHelper.java @@ -26,9 +26,9 @@ import java.util.regex.Pattern; import org.arquillian.droidium.container.configuration.AndroidSDK; +import org.arquillian.droidium.container.configuration.Command; import org.arquillian.droidium.container.configuration.Validate; import org.arquillian.droidium.container.impl.ProcessExecutor; -import org.arquillian.droidium.native_.utils.Command; /** * Provides various helper methods for Android packages. diff --git a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationManager.java b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationManager.java index f87aac70..b4f990eb 100644 --- a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationManager.java +++ b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/android/AndroidApplicationManager.java @@ -23,10 +23,10 @@ import org.arquillian.droidium.container.api.AndroidDevice; import org.arquillian.droidium.container.api.AndroidExecutionException; import org.arquillian.droidium.container.configuration.AndroidSDK; +import org.arquillian.droidium.container.configuration.Command; import org.arquillian.droidium.container.configuration.Validate; import org.arquillian.droidium.container.impl.ProcessExecutor; import org.arquillian.droidium.native_.spi.AndroidDeployment; -import org.arquillian.droidium.native_.utils.Command; import org.arquillian.droidium.native_.utils.DroidiumNativeFileUtils; import org.arquillian.droidium.native_.utils.Monkey; diff --git a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidRebuilder.java b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidRebuilder.java index 2a62d9bf..31686998 100644 --- a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidRebuilder.java +++ b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidRebuilder.java @@ -31,9 +31,9 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.arquillian.droidium.container.configuration.AndroidSDK; +import org.arquillian.droidium.container.configuration.Command; import org.arquillian.droidium.container.configuration.Validate; import org.arquillian.droidium.container.impl.ProcessExecutor; -import org.arquillian.droidium.native_.utils.Command; import org.arquillian.droidium.native_.utils.DroidiumNativeFileUtils; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; diff --git a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidServerManager.java b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidServerManager.java index 070f9425..a9c58f52 100644 --- a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidServerManager.java +++ b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/selendroid/SelendroidServerManager.java @@ -32,10 +32,10 @@ import org.arquillian.droidium.container.api.AndroidDevice; import org.arquillian.droidium.container.api.AndroidExecutionException; import org.arquillian.droidium.container.configuration.AndroidSDK; +import org.arquillian.droidium.container.configuration.Command; import org.arquillian.droidium.container.configuration.Validate; import org.arquillian.droidium.container.impl.ProcessExecutor; import org.arquillian.droidium.native_.spi.SelendroidDeployment; -import org.arquillian.droidium.native_.utils.Command; import org.arquillian.droidium.native_.utils.DroidiumNativeFileUtils; import org.arquillian.droidium.native_.utils.Monkey; diff --git a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/APKSigner.java b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/APKSigner.java index c382e58d..a2c1e1e0 100644 --- a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/APKSigner.java +++ b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/APKSigner.java @@ -22,10 +22,10 @@ import java.util.logging.Logger; import org.arquillian.droidium.container.configuration.AndroidSDK; +import org.arquillian.droidium.container.configuration.Command; import org.arquillian.droidium.container.configuration.Validate; import org.arquillian.droidium.container.impl.ProcessExecutor; import org.arquillian.droidium.native_.configuration.DroidiumNativeConfiguration; -import org.arquillian.droidium.native_.utils.Command; import org.arquillian.droidium.native_.utils.DroidiumNativeFileUtils; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; diff --git a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/KeyStoreCreator.java b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/KeyStoreCreator.java index b8a3921c..d6dd4cf7 100644 --- a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/KeyStoreCreator.java +++ b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/sign/KeyStoreCreator.java @@ -24,9 +24,9 @@ import java.util.logging.Logger; import org.arquillian.droidium.container.configuration.AndroidSDK; +import org.arquillian.droidium.container.configuration.Command; import org.arquillian.droidium.container.configuration.Validate; import org.arquillian.droidium.native_.configuration.DroidiumNativeConfiguration; -import org.arquillian.droidium.native_.utils.Command; /** * Creates keystore and checks if some keystore already exists in the system. diff --git a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/utils/Command.java b/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/utils/Command.java deleted file mode 100644 index d54e9a81..00000000 --- a/droidium-native/arquillian-droidium-native-impl/src/main/java/org/arquillian/droidium/native_/utils/Command.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2012, Red Hat Middleware LLC, and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * Licensed 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 org.arquillian.droidium.native_.utils; - -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - -/** - * Represents emulator command we are creating in order to execute some command on the command line. - * - * @author Stefan Miklosovic - * - */ -public class Command { - - private List command; - - public Command() { - command = new ArrayList(); - } - - /** - * - * @param command - * @throws IllegalArgumentException if {@code command} is null - */ - public Command(List command) throws IllegalArgumentException { - if (command == null) { - throw new IllegalArgumentException("command can't be a null list!"); - } - this.command = command; - } - - /** - * Adds a token to the command list. - * - * @param token token to add to the command list - * @return instance of this {@code Command} - */ - public Command add(String token) { - if (token != null && !token.trim().equals("")) { - command.add(token.trim()); - } - return this; - } - - /** - * Add list of tokens to already existing list we are constructing, ignoring null and empty ones. - * - * @param tokens tokens we are adding to the already existing list - * @return instance of this {@code Command} - */ - public Command add(List tokens) { - for (String token : tokens) { - add(token); - } - return this; - } - - /** - * Adds tokens written in the simple string, parsing tokens when delimiter is a space. - * - * @param tokens tokens to add, saved in the string and delimited by space(s) - * - * @return instance of this {@code Command} - */ - public Command addAsString(String tokens) { - if (tokens == null || tokens.trim().equals("")) { - return this; - } - - tokens = deleteTrailingSpaces(tokens); - - // we tokenize string so every word delimited by spaces will be one token - List tokenized = new ArrayList(); - StringTokenizer tokenizer = new StringTokenizer(deleteTrailingSpaces(tokens), " "); - while (tokenizer.hasMoreTokens()) { - tokenized.add(tokenizer.nextToken().trim()); - } - - int quotesOnEnds = 0; - int quotesTotal = 0; - - // we count number of quotes on the beginning and end of the every word - for (int i = 0; i < tokenized.size(); i++) { - if (tokenized.get(i).startsWith("\"")) { - quotesOnEnds++; - } - if (tokenized.get(i).endsWith("\"")) { - quotesOnEnds++; - } - // and we count number of quotes in the word as such - for (int j = 0; j < tokenized.get(i).length(); j++) { - if (tokenized.get(i).charAt(j) == '\"') { - quotesTotal++; - } - } - } - - // if these two do not equal, it means there is quote somewhere in the - // middle of a word which is not acceptable input - if (quotesOnEnds != quotesTotal) { - return this; - } - - // if it is not divisible by two, it means there are unbalanced quotes - // which is not acceptable input - if (quotesOnEnds % 2 != 0) { - return this; - } - - // if some token starts and ends with quotes, add it to the list - // otherwise take the next one until we have a word which ends with quotes - for (int i = 0; i < tokenized.size(); i++) { - if (tokenized.get(i).startsWith("\"")) { - if (tokenized.get(i).endsWith("\"")) { - command.add(tokenized.get(i)); - } else { - StringBuilder sb = new StringBuilder(); - sb.append(tokenized.get(i)); - int j = i; - while (true) { - if (tokenized.get(++j).endsWith("\"")) { - sb.append(" ").append(tokenized.get(j)); - break; - } - else { - sb.append(" ").append(tokenized.get(j)).append(" "); - } - } - command.add(sb.toString()); - i++; - } - } else { - command.add(tokenized.get(i)); - } - } - - return this; - } - - /** - * Deletes all multiple spaces and preserve original sense of the text input. - * - * @param text - * @return {@code text} without multiple spaces - */ - private String deleteTrailingSpaces(String text) { - if (text == null) { - return null; - } - - return text.replaceAll("^ +| +$|( )+", "$1") - .replaceAll("\" ([^\"])", "\"$1") - .replaceAll("\"([^ \"]) \"", "\"$1\""); - } - - /** - * Remove all occurences of {@code token} from the command list. - * - * @param token token to remove - * @return instance of this {@code EmulatorCommand} - */ - public Command remove(String token) { - if (token == null || token.trim().equals("")) { - return this; - } - - while (command.remove(token)) { - } - - return this; - } - - /** - * Clears the emulator command list. - * - * @return instance of this {@code EmulatorCommand} - */ - public Command clear() { - command.clear(); - return this; - } - - /** - * Return size of the command. - * - * @return number of tokens stored in the command - */ - public int size() { - return command.size(); - } - - /** - * - * @return command we constructed - */ - public List getAsList() { - return command; - } - - public String[] getAsArray() { - return getAsList().toArray(new String[0]); - } - - public String getAsString() { - StringBuilder sb = new StringBuilder(); - for (String s : command) { - sb.append(s); - sb.append(" "); - } - return sb.toString().trim(); - } - - /** - * Returns token on i-th position - * - * @param i position of token we want to get - * @return token on i-th position, null if we are out of bounds - */ - public String get(int i) { - try { - return command.get(i); - } catch (IndexOutOfBoundsException ex) { - return null; - } - } - - /** - * - * @return last token from the command - */ - public String getLast() { - if (command.isEmpty()) { - return null; - } - return command.get(command.size() - 1); - } - - /** - * - * @return first token from the command - */ - public String getFirst() { - if (command.isEmpty()) { - return null; - } - return command.get(0); - } - - @Override - public String toString() { - return getAsString(); - } -} diff --git a/droidium-web/README.adoc b/droidium-web/README.adoc index aa3e6a63..165664d7 100644 --- a/droidium-web/README.adoc +++ b/droidium-web/README.adoc @@ -57,3 +57,22 @@ Sets path to log file where communication with Android device during testing is ---- /path/to/file/you/have/access/to ---- + +==== options +===== default: empty string + +String to add as an option to `org.openqa.selenium.android.app/.MainActivity` from Selenium project when WebDriver hub is +about to be created. + +---- +-e debug true +---- + +==== debug +===== default: false + +Turns debug output to console from WebDriver hub on / off. Value has to be boolean-like. + +---- +true +---- \ No newline at end of file diff --git a/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/configuration/DroidiumWebConfiguration.java b/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/configuration/DroidiumWebConfiguration.java index f2eaeb64..9e5adcea 100644 --- a/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/configuration/DroidiumWebConfiguration.java +++ b/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/configuration/DroidiumWebConfiguration.java @@ -35,6 +35,10 @@ public class DroidiumWebConfiguration { private String logFile = "target" + System.getProperty("file.separator") + "android.log"; + private String options = ""; + + private String debug = "false"; + private Map properties = new HashMap(); public File getServerApk() { @@ -45,6 +49,14 @@ public File getLogFile() { return new File(getProperty("logFile", logFile)); } + public String getOptions() { + return new String(getProperty("options", options)); + } + + public boolean getDebug() { + return Boolean.parseBoolean(getProperty("debug", this.debug)); + } + /** * Sets properties as configuration. * @@ -67,7 +79,7 @@ public void setProperties(Map properties) { */ public String getProperty(String name, String defaultValue) { Validate.notNullOrEmpty(name, "unable to get configuration value of null configuration key"); - Validate.notNullOrEmpty(defaultValue, "unable to set configuration value of " + name + " to null"); + Validate.notNull(defaultValue, "unable to set configuration value of " + name + " to null"); String found = properties.get(name); if (found == null || found.length() == 0) { @@ -86,7 +98,7 @@ public String getProperty(String name, String defaultValue) { */ public void setProperty(String property, String value) { Validate.notNullOrEmpty(property, "unable to set configuration value which key is null"); - Validate.notNullOrEmpty(value, "unable to set configuration value which is null"); + Validate.notNull(value, "unable to set configuration value which is null"); properties.put(property, value); } diff --git a/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/impl/AndroidServerInstaller.java b/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/impl/AndroidServerInstaller.java index 78e4b9f2..fc4f12e9 100644 --- a/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/impl/AndroidServerInstaller.java +++ b/droidium-web/arquillian-droidium-web-impl/src/main/java/org/arquillian/droidium/web/impl/AndroidServerInstaller.java @@ -26,6 +26,7 @@ import org.arquillian.droidium.container.api.AndroidDevice; import org.arquillian.droidium.container.api.AndroidDeviceOutputReciever; import org.arquillian.droidium.container.api.AndroidExecutionException; +import org.arquillian.droidium.container.configuration.Command; import org.arquillian.droidium.container.spi.event.AndroidDeviceReady; import org.arquillian.droidium.web.configuration.DroidiumWebConfiguration; import org.arquillian.droidium.web.spi.event.AndroidServerInstalled; @@ -56,28 +57,24 @@ public class AndroidServerInstaller { private static final Logger log = Logger.getLogger(AndroidServerInstaller.class.getName()); - private static final String START_WEBDRIVER_HUB_CMD = - "am start -a android.intent.action.MAIN -n org.openqa.selenium.android.app/.MainActivity"; - - private static final String TOP_CMD = "top -n 1"; private static final String APK_APP_NAME = "org.openqa.selenium.android.app"; @Inject private Event androidServerInstalled; @Inject - private Instance droneConfiguration; + private Instance configuration; public void install(@Observes AndroidDeviceReady event) throws AndroidExecutionException, IOException { AndroidDevice device = event.getDevice(); - installServerAPK(device, droneConfiguration.get().getServerApk()); + installServerAPK(device, configuration.get().getServerApk()); log.info("Installation of Android Server APK for Arquillan Droidium web support was performed."); log.info("Starting Android Server for Arquillian Droidium web testing."); - WebDriverMonkey monkey = new WebDriverMonkey(droneConfiguration.get().getLogFile()); - device.executeShellCommand(START_WEBDRIVER_HUB_CMD, monkey); + WebDriverMonkey monkey = new WebDriverMonkey(configuration.get().getLogFile()); + device.executeShellCommand(getWebDriverHubCommand().toString(), monkey); log.info("Waiting until Android server for Arquillian Droidium web support is started."); waitUntilStarted(device, monkey); @@ -97,12 +94,32 @@ private void installServerAPK(AndroidDevice device, File apk) throws AndroidExec device.installPackage(apk, true); } + private Command getTopCommand() { + Command command = new Command(); + command.add("top -n 1"); + return command; + } + + private Command getWebDriverHubCommand() { + Command command = new Command(); + command.add("am start -a android.intent.action.MAIN -n org.openqa.selenium.android.app/.MainActivity"); + + command.add(configuration.get().getOptions()); + + // if debug is not already set via "options" and we specified we want to use debugging via debug option + if (!command.getAsString().contains("-e debug") && configuration.get().getDebug()) { + command.add("-e debug true"); + } + + return command; + } + private void waitUntilStarted(AndroidDevice device, WebDriverMonkey monkey) throws IOException, AndroidExecutionException { log.info("Starting Web Driver Hub on Android device."); for (int i = 0; i < 5; i++) { - device.executeShellCommand(TOP_CMD, monkey); + device.executeShellCommand(getTopCommand().toString(), monkey); if (monkey.isWebDriverHubStarted()) { return; } diff --git a/tests/droidium-web-01/src/test/resources/arquillian.xml b/tests/droidium-web-01/src/test/resources/arquillian.xml index 3ac555ba..acb02008 100644 --- a/tests/droidium-web-01/src/test/resources/arquillian.xml +++ b/tests/droidium-web-01/src/test/resources/arquillian.xml @@ -45,6 +45,9 @@ android-server-2.32.0.apk + + +