getDeviceName and getVersion runtime using Appium - appium

Consider I am running my tests using Appium in multiple Real device.
is it possible to get getDeviceName and getVersion runtime using Appium.
Because i need to take screenshots and save it in a folder with that Devicename

I can show you how to get a list of running devices and emulators but I have no code to get the versions they are running.
/**
* Determine already connected physical devices or already running emulators
* #author Bill Hileman
* #return String List of running/connected devices
*/
public List<String> getRunningDevicesList() {
List<String> dev = new ArrayList<String>();
//Location of the Android SDK
String sdkPath = System.getenv("ANDROID_HOME");
if (sdkPath == null) {
System.err.println("ANDROID_HOME is not set in the environment");
Assert.fail();
} else {
//Location of Android Debug Bridge
String adbPath = sdkPath + "/platform-tools/adb.exe";
if (!new File(adbPath).exists()) {
System.err.println(adbPath + " is not found");
Assert.fail();
} else {
try {
String[] commandListAVDs = new String[]{adbPath, "devices"};
System.out.println("Executing command: " + adbPath + " devices");
Process process = new ProcessBuilder(commandListAVDs).start();
BufferedReader inputStream = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = inputStream.readLine()) != null)
//ignore lines that do not contain device information
if (!(line.trim().equals("") || line.equals("List of devices attached") || line.startsWith("* daemon ")))
dev.add(line.trim());
} catch (Exception e) {
System.err.println("Unable to read device list: " + e);
e.printStackTrace();
}
System.out.println("Running Devices: " + dev.toString());
}
}
return dev;
}

Related

Model value not being set in Xamarin in iOS Only

I am working on a Xamarin App where I am facing an issue.
Case 1:
Mode: Debug
Error: System.NullReferenceException: 'Object reference not set to an instance of an object'
Explanation:
No value is being set and passed to ViewModel, Controller.
Even I tried setting static values to variables and parameters.
LoginModel logtest = new LoginModel();
logtest.Username = "Test#user.com"; //uName;
logtest.Password = "2342534"; //pWord;
Tried solution:
In the beginning, I tried many different solutions nothing worked.
Then I create a new project and moved all the code to the new project, then it started working.
Case 2:
Mode: release
Now the same issue I am getting in release mode.
No value is being set and passed to ViewModels and Controller.
I have already tried moving code to a new project.
How can I resolve this? I am not sure is this a Visual studio issue or Xamarin issue or Apple.
I have tried updating Visual Studio enterprise 2019 and Xcode on Mac.
Deleted and recreated Provisioning Profiles and Signing Identities.
Code From LoginPage.xaml.cs
private async void LoginButtonClicked(object sender, EventArgs e)
{
await ((LoginViewModel)BindingContext).Login();
}
protected async override void OnAppearing()
{
//App.Current.MainPage = new Navigation(new DashboardPage());
//load the login page
Device.BeginInvokeOnMainThread(() =>
{
try
{
((LoginViewModel)BindingContext).IsLoading = false;
((LoginViewModel)BindingContext).RememberMe = DeviceStorage.RememberMe;
if (DeviceStorage.RememberMe == true)
{
((LoginViewModel)BindingContext).UserName = "Test#user.ca"; //Trying set static values here
((LoginViewModel)BindingContext).Password = "password"; //Trying set static values here
}
//RememberMeToggle.Toggled += switcher_Toggled;
((LoginViewModel)BindingContext).Load();
}
catch (Exception ex)
{
//logger.Error(App.LogPrefix() + "Error opening Navigation Page: " + ex.Message);
Console.WriteLine(App.LogPrefix() + "Error opening Load(): " + ex.Message);
}
});
}
Code from LoginViewModel.cs
public async Task Login()
{
IsLoading = true;
await TokenController.GetAuthorizationToken(UserName, Password);
}
Code from TokenController.cs
public static async Task GetAuthorizationToken(string uName, string pWord)
{
bool tokenReturned = false;
string tokenGetResponse = string.Empty;
// Have tried setting them static values as well
LoginModel logtest = new LoginModel();
logtest.Username = uName;
logtest.Password = pWord;
logtest.AppType = Constants.AppDetails.APP_CODE;
logtest.SystemCode = Constants.AppDetails.SYSTEM_CODE;
logtest.Push.PushSystem = PushAddressModel.PushSystemCode.FireBase;
logtest.Push.Address = ((App)App.Current).PushNotificationToken;
logtest.Push.AppCode = Constants.AppDetails.APP_CODE;
string uri = URI.message_Chat_Endpoint;
(tokenReturned, tokenGetResponse) = await ApiFunctions.Post(logtest, URI.token_Endpoint, false);
if (tokenReturned)
{
try
{
//deserialize the return object
TokenModel token = JsonConvert.DeserializeObject<TokenModel>(tokenGetResponse);
((App)App.Current).token = token;
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
//logger.Error(App.LogPrefix() + "Error: " + ex.Message);
}
Console.WriteLine("Profile Token loaded: " + ((App)App.Current).token.access_token);
}
else
{
Console.WriteLine("Error: Error loading profile token ");
//logger.Error(App.LogPrefix() + "Error loading profile token");
}
}

Is it possible to switch wifi networks in Appium?

While executing my test suite I have to switch between different wifi networks available in Android Device.
In the middle of the execution I have to change my wifi connection from Wifi_Network_1 to Wifi_Network_2 provided ssid name and password of wifi network is known. How can it be done?
I am using:
Appium server -->1.8.1
java-client --> 6.1.0
selenium-java --> 3.13.0
Since NetworkConnectionSetting has been deprciated, I am not able to find alternate for it.
I can toggle wifi on/off using
driver.toggleWifi();
But it is not suitable for my case as i need to toggle between different wifi network available using SSID name and its password.
Thanks in advance.
Hi I'am using this method due Appium deprecated their switch for wifi, and I've created my own override via console via commands from adb. It is working for me so give it a try:
public synchronized boolean wifiSetup(String udid, boolean flg) {
synchronized (this) {
String flgEnabled = (flg) ? "enable" : "disable";
List<String> output = Console.runProcess(false, "adb -s " + udid + " shell am broadcast -a io.appium.settings.wifi --es setstatus " + flgEnabled);
for (String line : output) {
System.err.println(line);
if (line.equalsIgnoreCase("Broadcast completed: result=-1"))
return true;
}
return false;
}
}
usage to switch off:
wifiSetup("xxxUDIDfromAndroid", false);
usage to switch on:
wifiSetup("xxxUDIDfromAndroid", true);
And here is part for calling console:
public class Console {
private static final String[] WIN_RUNTIME = { "cmd.exe", "/C" };
private static final String[] OS_LINUX_RUNTIME = { "/bin/bash", "-l", "-c" };
private Console() {
}
private static <T> T[] concat(T[] first, T[] second) {
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
#SuppressWarnings({ "hiding"})
private static <String> String[] concatStr(String[] first, String[] second) {
String[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
public static List<String> runProcess(boolean isWin, String... command) {
String[] allCommand = null;
try {
if (isWin) {
allCommand = concat(WIN_RUNTIME, command);
} else {
allCommand = concat(OS_LINUX_RUNTIME, command);
}
ProcessBuilder pb = new ProcessBuilder(allCommand);
pb.redirectErrorStream(true);
Process p = pb.start();
p.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String _temp = null;
List<String> line = new ArrayList<String>();
while ((_temp = in.readLine()) != null) {
// system.out.println("temp line: " + _temp);
line.add(_temp);
}
// system.out.println("result after command: " + line);
return line;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Hope this helps,

Selenium grid error : Session [(null externalkey)] not available and is not among the last 1000 terminated sessions

We are executing multiple test cases in selenium grid where hub is connected to 2 machines, but every time I am running the grid, I get an error.
Error creating a webdriver. Exception message:
Session [(null externalkey)] not available and is not among the last 1000 terminated sessions.
Active sessions are[]
Command duration or timeout: 0 milliseconds
Code:
private static List<WebDriver> m_listOfWebDrivers = Collections.synchronizedList(new ArrayList<WebDriver>());
private static ThreadLocal<WebDriver> m_driverForThread = new ThreadLocal<WebDriver>() {
#Override
protected WebDriver initialValue() {
WebDriver driver = null;
try {
driver = loadDesktopDriver();
} catch (Exception e) {
e.printStackTrace();
}
Log.info("Initializing Webdriver");
m_listOfWebDrivers.add(driver);
return driver;
}
};
protected static WebDriver loadDesktopDriver() throws Exception {
WebDriver driver = null;
Log.debug("Get Driver for Browser : " + m_browser);
try {
if (!m_runOnBrowserStack && null == m_browser) {
throw new IllegalArgumentException("Browser value should be provided for test");
}
driver = getNewDriver(m_browser, "", "", m_context);
**driver.manage().timeouts().implicitlyWait(50000, TimeUnit.MILLISECONDS);** /* this was added later, still didnt work*/
} catch (Exception e) {
Log.fatal("Error creating a webdriver. Exception message : " + e.getMessage());
throw e;
}
return driver;
}
public static WebDriver getNewDriver(String browserName, String browserVersion, String platform,
ITestContext context)
throws IOException, ComboBoxElementException, TextBoxElementException, ElementException, PageException {
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.BROWSER, Level.ALL);
/**
* These capabilities will need to be re assigned according to the
* browser we are going to be launched. This is required in case of
* running on Grid only but keeping it same normal execution to avoid
* code redundancy.
*/
DesiredCapabilities desiredCapabilities = null;
if (m_runOnBrowserStack) {
desiredCapabilities = new DesiredCapabilities();
JSONObject envs = (JSONObject) m_bsConfig.get("environment");
String bsEnvironment = context.getCurrentXmlTest().getParameter("bsEnvironment");
String testName = context.getCurrentXmlTest().getName();
Log.info("Environmnet details for Test [" + testName + "] is : " + bsEnvironment);
if (null == bsEnvironment)
throw new PageException(
"Environment name does not present in XML or not passed from CLI : " + bsEnvironment);
Map<String, String> envCapabilities = (Map<String, String>) envs.get(bsEnvironment);
if (null == envCapabilities)
throw new PageException("Environment name does not present in Config file : " + bsEnvironment);
Iterator<Entry<String, String>> it = envCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, ?> pair = (Map.Entry<String, ?>) it.next();
desiredCapabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
}
Map<String, String> commonCapabilities = (Map<String, String>) m_bsConfig.get("capabilities");
it = commonCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, ?> pair = (Map.Entry<String, ?>) it.next();
if (desiredCapabilities.getCapability(pair.getKey().toString()) == null) {
desiredCapabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
}
}
browserName = (String) desiredCapabilities.getCapability("browser");
}
DriverSupportedBrowsers driverType = DriverSupportedBrowsers.valueOf(browserName.toUpperCase());
if (null != m_gridUrl && !m_gridUrl.isEmpty()) {
m_gridUrl += "/wd/hub";
}
switch (driverType) {
case CHROME:
String chromeDriverPath = driverHome + File.separator + FrameworkConstants.chromeDriverExeName;
if (m_runOnBrowserStack || CommonHelper.isFileExists(chromeDriverPath)) {
if (!m_runOnBrowserStack)
desiredCapabilities = DesiredCapabilities.chrome();
desiredCapabilities.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-extensions");
// To start browser in private mode
// options.addArguments("incognito");
desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options);
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
if (null != m_gridUrl && !m_gridUrl.isEmpty()) {// for runs on
// grid
return new RemoteWebDriver(new URL(m_gridUrl), desiredCapabilities);
} else
return new RemoteWebDriver(service.getUrl(), desiredCapabilities); /* The code fails here generally with the failure*/
} else {
throw new FileNotFoundException(
"Chrome Driver path : " + chromeDriverPath + "\n\"" + FrameworkConstants.chromeDriverExeName
+ "\" not found in driver home path declared in System Environment Variable \""
+ driverHome + "\"");
}
#Parameters({ "bsEnvironment" })
#BeforeMethod(alwaysRun = true)
public void initialize(ITestContext context, Method method, #Optional String bsEnvironment)
throws IOException {
String customer = context.getCurrentXmlTest().getParameter("customer");
String testName = context.getCurrentXmlTest().getName();
setTestName(testName);
String methodName = "";
m_testMethod = method.getName();
methodName = testName + "_" + method.getName() + "_" + customer;
CommonHelper.renameRetryLog(m_logDir, methodName);
Log.setLog(m_logDir, methodName);
m_context = context;
if (m_runOnBrowserStack) {
if (null == context.getCurrentXmlTest().getParameter("bsEnvironment")
|| context.getCurrentXmlTest().getParameter("bsEnvironment").isEmpty()) {
Log.info("Adding bsEnvironment parameter for run on BrowserStack");
context.getCurrentXmlTest().addParameter("bsEnvironment", bsEnvironment);
}
}
try {
WebDriver driver = getDriverInstanceForThread();
if (null == driver)
throw new PageException("Driver is null. Initialization problem!!");
// Logging browser name and version parameters, driver and thread
// instances
String browserName = null;
String browserVersion = null;
try {
Capabilities webDriverCapablities = ((RemoteWebDriver) driver).getCapabilities();
browserName = webDriverCapablities.getBrowserName();
browserVersion = webDriverCapablities.getVersion();
} catch (ClassCastException e) {
Log.error("Unable to cast driver to RemoteWebdriver");
browserName = m_browser;
browserVersion = "NA";
}
Log.info("\n ****************** START OF TEST CASE " + method.getName() + " " + customer + ":"
+ browserName + ":" + browserVersion + "\t THREAD:" + Thread.currentThread().getId()
+ "\t WEBDRIVER:" + driver + " ****************** \n");
// driver.manage().timeouts().pageLoadTimeout(CommonConstants.PAGE_LOAD_WAIT_SEC,
// TimeUnit.SECONDS);
if (null != m_gridUrl) {
// Log the remote node ip address where the test is running
Log.info("Remote Node IP: " + CommonHelper.getIPOfRemoteNode(driver));
}
} catch (Exception e) {
e.printStackTrace();
Log.warn(e.getMessage());
}
The CMD is triggered for Node giving timeout and browser timeout:
java -Dwebdriver.chrome.driver=D:/imp/iTAF_Driver_Home/chromedriver.exe -jar selenium-server-standalone-3.3.1.jar -port 5554 -role node -hub http://10.18.15.168:5550/grid/register -timeout 86400 -browserTimeout 86000
This issue is a recurring error.

Not able to get scanner device name via bluetooth on iOS device

Currently working on xamarin and trying to connect a scanner device(Zebra scanner) via bluetooth. CoreBluetooth.CBPeripheral is used to get information of device like id, name etc…
To scan device used following code :
protected override async Task StartScanningForDevicesNativeAsync(Guid[] serviceUuids, bool allowDuplicatesKey, CancellationToken scanCancellationToken)
{
// Wait for the PoweredOn state
await WaitForState(CBCentralManagerState.PoweredOn, scanCancellationToken).ConfigureAwait(false);
if (scanCancellationToken.IsCancellationRequested)
throw new TaskCanceledException("StartScanningForDevicesNativeAsync cancelled");
Trace.Message("Adapter: Starting a scan for devices.");
CBUUID[] serviceCbuuids = null;
if (serviceUuids != null && serviceUuids.Any())
{
serviceCbuuids = serviceUuids.Select(u => CBUUID.FromString(u.ToString())).ToArray();
Trace.Message("Adapter: Scanning for " + serviceCbuuids.First());
}
DiscoveredDevices.Clear();
_centralManager.ScanForPeripherals(serviceCbuuids, new PeripheralScanningOptions { AllowDuplicatesKey = allowDuplicatesKey });
}
And getting Response in Event by following code :
_centralManager.DiscoveredPeripheral += (sender, e) =>
{
Trace.Message("DiscoveredPeripheral: {0}, Id: {1}", e.Peripheral.Name, e.Peripheral.Identifier);
System.Diagnostics.Debug.WriteLine("DiscoveredPeripheral: {0}, Id: {1}", e.Peripheral.Name, e.Peripheral.Identifier);;
var name = e.Peripheral.Name;
foreach (var oData in e.AdvertisementData)
{
System.Diagnostics.Debug.WriteLine("AdvertisementData : key : " + oData.Key + " , Value : " + oData.Value);
}
if (e.AdvertisementData.ContainsKey(CBAdvertisement.DataLocalNameKey))
{
// iOS caches the peripheral name, so it can become stale (if changing)
// keep track of the local name key manually
name = ((NSString)e.AdvertisementData.ValueForKey(CBAdvertisement.DataLocalNameKey)).ToString();
}
var device = new Device(this, e.Peripheral, name, e.RSSI.Int32Value,
ParseAdvertismentData(e.AdvertisementData));
HandleDiscoveredDevice(device);
};
Now, in this AdvertisementData doesn’t contains CBAdvertisement.DataLocalNameKey so not able to get device name…?


Want to use "xcrun simctl" in Appium automation

Is there a way I can use xcrun simctl commands in my Appium automation? I have came to situation where I wanted to use uninstall and install app from simulator which is not available with appium methods. So, I am thinking if somehow I could use this utility in automation code.
I am running my automation on iOS in Java.
public class XCRunUtil {
ProcessBuilder processBuilder = new ProcessBuilder();
Process process;
public void execute(String url) {
String link = "xcrun simctl list devices";
System.out.println("link : " + link);
processBuilder.command("sh", "-c", link);
try {
process = processBuilder.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
This above code will works

Resources