Navigation Menu

Skip to content

Commit

Permalink
support to run test on genymotion (#515)
Browse files Browse the repository at this point in the history
* support to run test on genymotion

* fix azure yaml

* add GM caps

* add server path to azure

* improved logging

* make codacy happy
  • Loading branch information
saikrishna321 committed Jul 11, 2019
1 parent cc1e6b4 commit bb8d57c
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 21 deletions.
31 changes: 30 additions & 1 deletion azure-pipelines.yml
Expand Up @@ -158,4 +158,33 @@ jobs:
displayName: 'Run Test on Sauce on iOS and Android'
- job: Genymotion
pool:
vmImage: 'macOS 10.13'


steps:
- task: NodeTool@0
inputs:
versionSpec: '8.12.0'

- script: |
node -v
npm install -g appium@beta
appium -v
displayName: 'Install Appium'
- bash: |
pip3 install gmsaas
displayName: 'Download Genymotion Installer'
- bash: |
gmsaas config set android-sdk-path $ANDROID_HOME
displayName: 'Set Android Sdk Path'
- script: |
mvn clean install -Dmaven.test.skip=true
Platform='android' CLOUD_USER=$(user_gm) CLOUD_KEY=$(pass_gm) CONFIG_FILE='gm_config.properties' mvn clean -Dtest=Runner test
displayName: 'Run Test on Genymotion Android'
30 changes: 30 additions & 0 deletions caps/genymotion.json
@@ -0,0 +1,30 @@
{
"android": {
"automationName": "UIAutomator2",
"project": "ATD",
"app": {
"local": "https://github.com/shridharkalagi/AppiumSample/raw/master/VodQA.apk"
},
"noSign": true
},
"genycloud": {
"android": [
{
"udid": "107d757e-463a-4a18-8667-b8dec6e4c87e",
"deviceName": "Google Pixel",
"osVersion": "9.0"
},
{
"udid": "a59951f2-ed13-40f9-80b9-3ddceb3c89f5",
"deviceName": "Google Nexus 6",
"osVersion": "8.0"
}
]
},
"hostMachines": [
{
"machineIP": "127.0.0.1",
"appiumServerPath": "/usr/local/lib/node_modules/appium/build/lib/main.js"
}
]
}
4 changes: 4 additions & 0 deletions gm_config.properties
@@ -0,0 +1,4 @@
RUNNER=distribute
FRAMEWORK=testng
CAPS=./caps/genymotion.json
RUNNER_LEVEL=methods
6 changes: 5 additions & 1 deletion src/main/java/com/appium/capabilities/CapabilityManager.java
Expand Up @@ -202,7 +202,11 @@ public boolean isRealDeviceAppPresentInCapsJson() {
}

public String getAppiumServerPath(String host) throws Exception {
return appiumServerProp(host, "appiumServerPath");
try {
return appiumServerProp(host, "appiumServerPath");
} catch (Exception e) {
return null;
}
}

public boolean isCloud(String host) {
Expand Down
88 changes: 88 additions & 0 deletions src/main/java/com/appium/device/GenyMotionManager.java
@@ -0,0 +1,88 @@
package com.appium.device;

import com.appium.utils.Api;
import com.appium.utils.CommandPrompt;
import okhttp3.Response;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;

public class GenyMotionManager {

private static final Logger LOGGER = Logger
.getLogger(GenyMotionManager.class.getSimpleName());
private static String cloud_user = System.getenv("CLOUD_USER");
private static String cloud_key = System.getenv("CLOUD_KEY");

protected static void connectToGenyCloud(String udid, Object devices) throws IOException {

String gmLogin = "gmsaas auth login "
+ cloud_user + " " + cloud_key;
try {
new CommandPrompt()
.runCommandThruProcess(gmLogin);
LOGGER.info("Connected to Genymotion Cloud..");
} catch (IOException e) {
throw new IOException("Failed to Connect to geny cloud..");
}

((ArrayList)devices).parallelStream().forEach(o -> {

String instanceUdid = (String) ((HashMap) o).get("udid");
String instanceName = (String) ((HashMap) o).get("deviceName");
String gnInstance = "gmsaas instances start "
+ instanceUdid + " " + "\"" + instanceName + "\"";
LOGGER.info("Starting Device on genymotion cloud instance with uuid"
+ instanceUdid + "and device name " + instanceName);
String createdInstance;
try {
createdInstance = new CommandPrompt()
.runCommandThruProcess(gnInstance);
String adbTunnel = "gmsaas instances adbconnect "
+ " " + createdInstance;
new CommandPrompt()
.runCommandThruProcess(adbTunnel);
} catch (IOException e) {
e.printStackTrace();
}
});

try {
LOGGER.info("Running Instances");
String gmsaas_instances_list = new CommandPrompt()
.runCommandThruProcess("gmsaas instances list");
LOGGER.info(gmsaas_instances_list);
} catch (IOException e) {
e.printStackTrace();
}

}

public void stopAllGenymotionInstances() throws ParseException, IOException {
JSONObject jsonObject = new JSONObject();
jsonObject.put("email", cloud_user);
jsonObject.put("password", cloud_key);
Api api = new Api();
String post = api.post("https://api.geny.io/cloud/v1/users/login", jsonObject.toString());
JSONParser parser = new JSONParser();
Object parse = parser.parse(post);
Object token = ((JSONObject) parse).get("token");
Response response = api.requestBuilderWithBearerToken("https://api.geny.io/cloud/v1/instances", token.toString());
String string = response.body().string();
JSONParser responseUdid = new JSONParser();
((JSONArray) responseUdid.parse(string)).parallelStream().forEach(o -> {
Object uuid = ((JSONObject) o).get("uuid");
LOGGER.info("Stopping Genymotion instance.." + uuid.toString());
String recipe_uuid = null;
recipe_uuid = api.postWithNoBody("https://api.geny.io/cloud/v1/instances/" + uuid
+ "/stop-disposable", token.toString());
System.out.println(recipe_uuid);
});
}
}
11 changes: 10 additions & 1 deletion src/main/java/com/appium/device/HostMachineDeviceManager.java
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.logging.Logger;
import java.util.stream.Collectors;

public class HostMachineDeviceManager {
Expand Down Expand Up @@ -176,6 +177,15 @@ private Map<String, List<AppiumDevice>> getDevices() throws Exception {
});
devicesByHost.put(ip, getAppiumDevices(ip, device));
} else {
if (capabilityManager.getCapabilityObjectFromKey("genycloud") != null) {
JSONObject cloud = capabilityManager
.getCapabilityObjectFromKey("genycloud");
for (Map.Entry<String, Object> entry : cloud.toMap().entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
GenyMotionManager.connectToGenyCloud(key, value);
}
}
devicesByHost.put(ip, getDevicesByIP(ip, platform, hostMachineJson));
}

Expand Down Expand Up @@ -223,7 +233,6 @@ private List<Device> getSimulatorsToBoot(String machineIP, JSONArray simulators)
}
return devices;
}

}


Expand Down
Expand Up @@ -4,11 +4,13 @@
import com.annotation.values.RetryCount;
import com.annotation.values.SkipIf;
import com.appium.capabilities.CapabilityManager;
import com.appium.device.GenyMotionManager;
import com.appium.utils.FileFilterParser;
import com.appium.utils.Helpers;

import com.context.SessionContext;
import com.context.TestExecutionContext;
import org.json.simple.parser.ParseException;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ISuite;
Expand Down Expand Up @@ -178,7 +180,14 @@ public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResu
*/
@Override
public void onFinish(ISuite iSuite) {
System.out.println();
if (CapabilityManager.getInstance()
.getCapabilityObjectFromKey("genycloud") != null) {
try {
new GenyMotionManager().stopAllGenymotionInstances();
} catch (ParseException | IOException e) {
e.printStackTrace();
}
}
}

/*
Expand Down
57 changes: 44 additions & 13 deletions src/main/java/com/appium/utils/Api.java
Expand Up @@ -14,14 +14,14 @@
public class Api extends Helpers {

public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
= MediaType.parse("application/json; charset=utf-8");

public Response getResponse(String url) throws IOException {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(90, TimeUnit.SECONDS)
.writeTimeout(90, TimeUnit.SECONDS)
.readTimeout(90, TimeUnit.SECONDS)
.build();
.connectTimeout(90, TimeUnit.SECONDS)
.writeTimeout(90, TimeUnit.SECONDS)
.readTimeout(90, TimeUnit.SECONDS)
.build();
try {
Request request = new Request.Builder().url(url).build();
return client.newCall(request).execute();
Expand All @@ -31,16 +31,28 @@ public Response getResponse(String url) throws IOException {

}

public Response requestBuilderWithBearerToken(String url, String userToken) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.addHeader("Content-Type", "application/json;charset=utf-8")
.addHeader("Authorization", "Bearer" + " " + userToken)
.build();
return client.newCall(request).execute();

}

public String uploadMultiPartFile(File filePath, String hostMachine) throws Exception {
OkHttpClient client = new OkHttpClient();
MediaType MEDIA_TYPE_PNG = MediaType.parse("multipart/form-data");
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("uploaded_file", filePath.getName(),
RequestBody.create(MEDIA_TYPE_PNG, filePath))
.build();
.addFormDataPart("uploaded_file", filePath.getName(),
RequestBody.create(MEDIA_TYPE_PNG, filePath))
.build();
Request request = new Request.Builder().url("http://" + hostMachine
+ ":" + getRemoteAppiumManagerPort(hostMachine) + "/artifacts/upload")
.post(requestBody).build();
+ ":" + getRemoteAppiumManagerPort(hostMachine) + "/artifacts/upload")
.post(requestBody).build();
Response response = client.newCall(request).execute();
return response.body().string();
}
Expand All @@ -49,9 +61,9 @@ public String post(String url, String json) {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
.url(url)
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
return response.body().string();
Expand All @@ -60,4 +72,23 @@ public String post(String url, String json) {
}
}

public String postWithNoBody(String url, String token) {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(null, new byte[]{});
Request request = new Request.Builder()
.url(url)
.addHeader("Content-Type", "application/json;charset=utf-8")
.addHeader("Authorization", "Bearer" + " " + token)
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
return null;
}
}



}
6 changes: 3 additions & 3 deletions src/main/java/com/appium/utils/CommandPrompt.java
Expand Up @@ -48,14 +48,14 @@ public BufferedReader getBufferedReader(String command) throws IOException {
return new BufferedReader(isr);
}

public void runCommandThruProcess(String command)
throws InterruptedException, IOException {
public String runCommandThruProcess(String command)
throws IOException {
BufferedReader br = getBufferedReader(command);
String line;
String allLine = "";
while ((line = br.readLine()) != null) {
allLine = allLine + "" + line + "\n";
System.out.println(allLine);
}
return allLine;
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/video/recorder/Flick.java
Expand Up @@ -59,7 +59,7 @@ private void flickRecordingCommand(String command, String className,
+ AppiumDeviceManager.getAppiumDevice().getDevice().getUdid();
runCommandThruProcess(android);

} catch (IOException | InterruptedException e) {
} catch (IOException e) {
e.printStackTrace();
}
} else {
Expand Down

0 comments on commit bb8d57c

Please sign in to comment.