Check for available devices in Java
You can use a REST API call to check if devices with the desired specifications are available before actually attempting to initialize the Appium driver. This way, you avoid a driver initialization error in case no such devices available for the test to start. This error would show up in Perfecto's Report Library as a blocked test.
The following example is based on the Get Device List API. It gets the count of all available devices in the specified cloud that are in a Connected state and not in use. The REST API returns an XML response that includes the list of available devices of a specific OS, OS version, and model. The list is based on the specific cloud user running the test, authenticated with the Perfecto security token.
package PerfectoAPI;
import static io.restassured.RestAssured.given;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.json.XML;
import org.openqa.selenium.Platform;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.perfecto.reportium.client.ReportiumClient;
import com.perfecto.reportium.client.ReportiumClientFactory;
import com.perfecto.reportium.model.Job;
import com.perfecto.reportium.model.PerfectoExecutionContext;
import com.perfecto.reportium.model.Project;
import com.perfecto.reportium.test.TestContext;
import com.perfecto.reportium.test.result.TestResultFactory;
import io.appium.java_client.android.AndroidDriver;
import io.restassured.RestAssured;
import io.restassured.response.Response;
public class DeviceRetryLogic {
static AndroidDriver driver;
static String cloudName="demo";
static String token = "";
public static void main(String[] args) throws InterruptedException, ClientProtocolException, IOException {
// TODO Auto-generated method stub
String platformName = "Android";
String platformVersion = "12";
String deviceModel = "Galaxy.*";
System.out.println("Run started");
DesiredCapabilities capabilities = new DesiredCapabilities("", "", Platform.ANY);
String host = cloudName+".perfectomobile.com";
capabilities.setCapability("securityToken", token);
capabilities.setCapability("platformName", platformName);
capabilities.setCapability("platformVersion", platformVersion);
capabilities.setCapability("automationName", "Appium");
capabilities.setCapability("app", "PRIVATE:ExpenseAppVer1.0.apk");
// For Android:
capabilities.setCapability("appPackage", "io.perfecto.expense.tracker");
int retry = 1;
int interval = 20000;
while (retry <= 6 && driver == null) {
int deviceCount=availableDevices(platformName, platformVersion, deviceModel);
if(deviceCount!=0) {
System.out.println("Available devices: " + deviceCount +" Initializing driver..");
driver = new AndroidDriver(new URL("https://" + host + "/nexperience/perfectomobile/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}else {
System.out.println("Attempt:" + retry + ". No available devices. Retrying.....");
Thread.sleep(interval);
++retry;
}
}
// Reporting client. For more details, see http://developers.perfectomobile.com/display/PD/Reporting
PerfectoExecutionContext perfectoExecutionContext = new PerfectoExecutionContext.PerfectoExecutionContextBuilder()
.withProject(new Project("My Project", "1.0"))
.withJob(new Job("VHA Job", 45))
.withContextTags("tag1")
.withWebDriver(driver)
.build();
ReportiumClient reportiumClient = new ReportiumClientFactory().createPerfectoReportiumClient(perfectoExecutionContext);
try {
reportiumClient.testStart("Expense Tracker sanity test", new TestContext("@vhaDemo", "@smoke"));
reportiumClient.testStop(TestResultFactory.createSuccess());
} catch (Exception e) {
reportiumClient.testStop(TestResultFactory.createFailure(e.getMessage(), e));
e.printStackTrace();
} finally {
try {
driver.quit();
// Retrieve the URL to the DigitalZoom Report (= Reportium Application) for an aggregated view over the execution
String reportURL = reportiumClient.getReportUrl();
// Retrieve the URL to the Execution Summary PDF Report
String reportPdfUrl = (String)(driver.getCapabilities().getCapability("reportPdfUrl"));
// For detailed documentation on how to export the Execution Summary PDF Report, the Single Test report and other attachments such as
// video, images, device logs, vitals and network files - see http://developers.perfectomobile.com/display/PD/Exporting+the+Reports
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Run ended");
}
public static int availableDevices(String platformName, String platformVersion, String deviceModel ) throws ClientProtocolException, IOException {
String url="https://"+cloudName+".app.perfectomobile.com/api/v1/device-management/devices";
CloseableHttpClient clossablehttpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("PERFECTO_AUTHORIZATION", token);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
String json="{\n"
+ " \"device\": {\n"
+ " \"os\": "+platformName+",\n"
+ " \"osVersion\": "+platformVersion+",\n"
+ " \"model\": "+deviceModel+",\n"
+ " \"status\":\"connected\"\n"
+ "\n"
+ " }\n"
+ "}";
StringEntity stringEntity = new StringEntity(json);
httpPost.setEntity(stringEntity);
CloseableHttpResponse clossablehttpClientResponse = clossablehttpClient.execute(httpPost);
JSONObject jsonResponse = new JSONObject(EntityUtils.toString(clossablehttpClientResponse.getEntity()));
int availableDevices = (int)jsonResponse.getJSONObject("handsets").get("items");
return availableDevices;
}
}