Skip to content

Commit

Permalink
[mobile]
Browse files Browse the repository at this point in the history
- [`copyToLocal(file,folder)`]: *NEW* command to copy file from host to connected device
- [`selectLocalFile(device,folder,filename)`]: *NEW* command to select file from device's local storage
- [`bin/mobile/copy-to-android.cmd|sh`]: *NEW* utility script to copy file from host to connected Android device
- [`bin/mobile/copy-to-ios.sh`]: *NEW* utility script to copy file from host to connected iOS device

Nexial v4.2 release candidate

Signed-off-by: automike <[email protected]>
  • Loading branch information
mikeliucc committed Sep 13, 2021
1 parent 612bd4c commit e052206
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 55 deletions.
23 changes: 23 additions & 0 deletions bin/mobile/copy-to-android.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@echo off
setlocal enableextensions

REM -----------------------------------------------------------------------------------------------
REM Copy local file to connected Android device
REM -----------------------------------------------------------------------------------------------

if "%2"=="" (
echo ERROR: No source file or target folder specified!
echo USAGE: %0 [source file] [target folder]
echo.
exit /b -1
)

set ANDROID_SDK_ROOT=%USERPROFILE%\.nexial\android\sdk
cd /d %ANDROID_SDK_ROOT%\platform-tools
adb push "%1" "/storage/self/primary/%2"
if %ERRORLEVEL% EQU 0 (
exit /b 0
) else (
echo ERROR: File copy from %1 to %2 failed: %errorlevel%
exit /b %errorlevel%
)
18 changes: 18 additions & 0 deletions bin/mobile/copy-to-android.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash

# -----------------------------------------------------------------------------------------------
# Copy local file to connected Android device
# -----------------------------------------------------------------------------------------------

if [[ "$2" = "" ]]; then
echo
echo "ERROR: No source file or target folder specified!"
echo "USAGE: $0 [source file] [target folder]"
echo
exit 254
fi

ANDROID_SDK_ROOT=~/.nexial/android/sdk
cd $ANDROID_SDK_ROOT/platform-tools || exit
./adb push "$1" "/storage/self/primary/$2"
exit $?
22 changes: 22 additions & 0 deletions bin/mobile/copy-to-ios.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash

# -----------------------------------------------------------------------------------------------
# Copy local file to connected iOS device
# -----------------------------------------------------------------------------------------------

if [[ "$1" = "" ]]; then
echo
echo "ERROR: No source file specified!"
echo "USAGE: $0 [source file]"
echo
exit 254
fi

echo
if whereis xcrun > /dev/null 2>&1 ; then
xcrun simctl addmedia booted "$1"
exit $?
else
echo "ERROR: Required utility 'xcrun' not found; Unable to proceed"
exit 253
fi
13 changes: 4 additions & 9 deletions src/main/java/org/nexial/core/Nexial.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,20 @@
import org.nexial.core.spi.NexialExecutionEvent;
import org.nexial.core.spi.NexialListenerFactory;
import org.nexial.core.tools.TempCleanUpHelper;
import org.nexial.core.utils.CheckUtils;
import org.nexial.core.utils.ConsoleUtils;
import org.nexial.core.utils.ExecUtils;
import org.nexial.core.utils.InputFileUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.security.Security;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;

import static java.io.File.separator;
import static java.lang.System.lineSeparator;
Expand Down Expand Up @@ -275,13 +276,7 @@ protected void init(String[] args) throws IOException, ParseException {
ExecUtils.collectCliProps(args);

// first things first -- do we have all the required system properties?
String errPrefix = "System property " + NEXIAL_HOME;
String nexialHome = System.getProperty(NEXIAL_HOME);
if (StringUtils.isBlank(nexialHome)) { throw new RuntimeException(errPrefix + " missing; unable to proceed"); }
if (!FileUtil.isDirectoryReadable(nexialHome)) {
throw new RuntimeException(errPrefix + " does not refer to a valid directory (" + nexialHome + "); " +
"unable to proceed");
}
CheckUtils.requiresNexialHome();

NexialUpdate.checkAndRun();

Expand Down
8 changes: 7 additions & 1 deletion src/main/java/org/nexial/core/NexialConst.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import org.nexial.core.utils.ConsoleUtils;
import org.nexial.core.utils.ExecUtils;

import javax.validation.constraints.NotNull;
import java.awt.*;
import java.io.File;
import java.io.IOException;
Expand All @@ -48,6 +47,7 @@
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
import javax.validation.constraints.NotNull;

import static java.awt.Color.*;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
Expand Down Expand Up @@ -1021,6 +1021,7 @@ public static final class Project {
public static final String NEXIAL_BIN_REL_PATH = "bin" + separator;
public static final String NEXIAL_MACOSX_BIN_REL_PATH = NEXIAL_BIN_REL_PATH + "macosx" + separator;
public static final String NEXIAL_WINDOWS_BIN_REL_PATH = NEXIAL_BIN_REL_PATH + "windows" + separator;
public static final String NEXIAL_MOBILE_BIN_REL_PATH = NEXIAL_BIN_REL_PATH + "mobile" + separator;
public static final String NEXIAL_LINUX_BIN_REL_PATH = NEXIAL_BIN_REL_PATH + "linux" + separator;
public static final String NEXIAL_EXECUTION_TYPE = NAMESPACE + "executionType";
public static final String NEXIAL_EXECUTION_TYPE_SCRIPT = "script";
Expand Down Expand Up @@ -2126,6 +2127,8 @@ public static final class Message {
public static final String INVALID_NODE_PATH = "Node path did not resolve to a valid executable NodeJS " +
"executable:";
public static final String APP_NOT_INSTALLED = "Configured app is currently not installed on device:";
public static final String SCRIPT_NOT_EXECUTABLE = "cannot be found or is not executable. Unable to proceed";
public static final String NOT_SUPPORT_FILE_EXT = "File extension not supported for iOS file transfer:";
}

public static final class Android {
Expand Down Expand Up @@ -2164,10 +2167,13 @@ public static final class Android {
"nexial" + separator + "android" + separator +
"cmdline-tools";
public static final String SDK_MANAGER = CMDLINE_TOOLS_PATH + separator + SDK_MANAGER_REL_PATH;
public static final String SCRIPT_COPY_TO_ANDROID = "copy-to-android.";
}

public static final class iOS {
public static final String MULTI_PICKER_DELIM = "|";
public static final String SCRIPT_COPY_TO_IOS = "copy-to-ios.sh";
public static final List<String> SUPPORTED_COPY_FILE_EXT = Arrays.asList("png", "jpg", "mp4", "gif", "wbem");
}
}

Expand Down
13 changes: 6 additions & 7 deletions src/main/java/org/nexial/core/plugins/web/WebCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@
import ru.yandex.qatools.ashot.coordinates.WebDriverCoordsProvider;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import javax.validation.constraints.NotNull;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
Expand All @@ -81,6 +77,10 @@
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import javax.validation.constraints.NotNull;

import static java.awt.Image.SCALE_DEFAULT;
import static java.io.File.separator;
Expand Down Expand Up @@ -3036,7 +3036,7 @@ protected StepResult clickInternal(WebElement element) {
} catch (WebDriverException e) {
return StepResult.fail(WebDriverExceptionHelper.resolveErrorMessage(e));
} catch (Exception e) {
// try again..
// try again...
if (forceJSClick) {
jsClick(element);
return StepResult.success("second attempt click via JS event");
Expand Down Expand Up @@ -3752,12 +3752,11 @@ protected static boolean useExplicitWait(ExecutionContext context, String profil

private boolean isElementVisible(String locator, long maxWait) {
By by = locatorHelper.findBy(locator);
boolean outcome = waitForCondition(maxWait, object -> {
return waitForCondition(maxWait, object -> {
WebElement elem = driver.findElement(by);
if (elem == null || !elem.isDisplayed()) { return false; }
return isTrue(jsExecutor.executeScript(JsLib.isVisible(), elem));
});
return outcome;
}

protected StepResult saveTextSubstring(String var, String locator, String delimStart, String delimEnd) {
Expand Down
27 changes: 19 additions & 8 deletions src/main/java/org/nexial/core/utils/CheckUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@

package org.nexial.core.utils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
Expand All @@ -33,8 +26,16 @@
import org.nexial.commons.utils.ResourceUtils;
import org.nexial.commons.utils.TextUtils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static java.lang.Integer.MIN_VALUE;
import static org.apache.commons.lang3.BooleanUtils.toBooleanObject;
import static org.nexial.core.NexialConst.Project.NEXIAL_HOME;
import static org.nexial.core.NexialConst.TOKEN_END;
import static org.nexial.core.NexialConst.TOKEN_START;

Expand Down Expand Up @@ -160,7 +161,7 @@ public static boolean isSameType(Class[] types, Class required) {
return true;
}

public static boolean requireOneOf(String option, String... options) {
public static boolean requiresOneOf(String option, String... options) {
if (requiresNotEmpty(option, "Invalid value", option)) {
List<String> optionList = Arrays.asList(options);
if (!optionList.contains(option)) { fail("Invalid value: " + option + ". Must be one of " + optionList); }
Expand All @@ -177,4 +178,14 @@ public static boolean toBoolean(final String str) {
}
return retVal == Boolean.TRUE;
}

public static void requiresNexialHome() {
String errPrefix = "System property " + NEXIAL_HOME;
String nexialHome = System.getProperty(NEXIAL_HOME);
if (StringUtils.isBlank(nexialHome)) { throw new RuntimeException(errPrefix + " missing; unable to proceed"); }
if (!FileUtil.isDirectoryReadable(nexialHome)) {
throw new RuntimeException(errPrefix + " does not refer to a valid directory (" + nexialHome + "); " +
"unable to proceed");
}
}
}
1 change: 1 addition & 0 deletions src/main/kotlin/org/nexial/core/CommandConst.kt
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ object CommandConst {
"mobile.clickUntilNotFound",
"mobile.waitForElementPresent",
"mobile.assertAlertPresent",
"mobile.copyFromLocal",

"tn.5250.saveTableAsCSV",

Expand Down
Loading

0 comments on commit e052206

Please sign in to comment.