I am new to Appium, In my code I have given required desired capabilities and wrote one test case that is working fine. Now I want to launch another App for second test in same code , how can I do that ?
I heard about startActivity(app-package,app Activity) but its not working, it says startActivity() not defined for Web Driver .
public class Calculator {
WebDriver driver;
#BeforeClass
public void setUp() throws MalformedURLException{
//Set up desired capabilities and pass the Android app-activity and app-package to Appium
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "Android");
capabilities.setCapability(CapabilityType.VERSION, "4.4");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName", "14085521650378");
capabilities.setCapability("appPackage", "com.android.calculator2"); // This is package name of your app (you can get it from apk info app)
capabilities.setCapability("appActivity","com.android.calculator2.Calculator");
configurations specified in Desired Capabilities
driver = new RemoteWebDriver(new URL("http://127.0.0.1:9515/wd/hub"), capabilities);
}
#Test
public void testCal(){
driver.findElement(By.name("2")).click();
driver.findElement(By.name("+")).click();
driver.findElement(By.name("4")).click();
driver.findElement(By.name("=")).click();
}
#Test
public void Test2() { driver.startActivity("appPackage", "com.tttk.apc","appActivity","com.tttk.apc.DWDemoActivity");
for(int i=0; i<20;i++)
driver.findElement(By.className("android.widget.ImageButton")).click();
}
#AfterClass
public void teardown(){
//close the app
driver.quit();
}}
Seems like you are trying to use the method with a WebDriver instance.
The startActivity method is provided by an interface StartsActivity implemented by AndroidDriver only. So ideally this shall work :
((AndroidDriver) driver).startActivity(<appPackage>, <appActivity>);
public static void start() {
try {
((AndroidDriver) driver).startActivity("com.example.test", "com.example.LaunchApp");
} catch (Exception e) {
e.printStackTrace();
}
}
You have to enter your app package name and activity name to maximize the app.
Related
I'm looking for a way to work with one driver for both android and IOS real devices, for example now if I start with IOS = IOSDriver<MobileElement> driver; and unlock my device for example than my code is driver = new IOSDriver<>(url, dc); and driver.unlockDevice(); for android its the same, but if my driver will be AppiumDriver driver; the code will not work on driver.unlockDevice(); so what are the options to work with android and ios together in one driver?
This is POC - and this isn't handled very well. Just for quick look.
And... I'm not sure about iOS driver - if it can even handle device unlocking - maybe only on simulators...
public static AppiumDriver<MobileElement> driver;
public static DesiredCapabilities iosCaps;
public static DesiredCapabilities androidCaps;
public void caps() {
iosCaps = new DesiredCapabilities();
iosCaps.setCapability("deviceName", "iPhone 5");
androidCaps = new DesiredCapabilities();
androidCaps.setCapability("deviceName", "Samsung X");
}
protected void startDriver() throws MalformedURLException {
caps();
if (device == android) {
driver = new AndroidDriver<>(new URL("appium url"), androidCaps);
} else if (device == ios) {
driver = new IOSDriver<>(new URL("appium url"), iosCaps);
}
}
public void iosLock() {
((IOSDriver) driver).lockDevice();
((IOSDriver<MobileElement>) driver).lockDevice();
}
public void androidLock() {
((AndroidDriver) driver).lockDevice();
}
Current setup stored inside my DriverFactory:
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
return webDriver.get();
Currently the following method seems to be failing:
public void loadUrl(String url) {
try {
getDriver().get(url);
System.out.println("Successfully navigated to URL: " + url);
} catch (Exception e) {
System.out.println(e.getStackTrace());
Assert.fail("Unable to navigate to URL: " + url + ", Exception: " + e.getMessage());
}
}
Set driver method:
public final void setDriver(String browser) throws Exception {
String remoteHubUrl = "http://xxx.xxxx.xxx.xxx:4444/wd/hub/";
try {
switch (setBrowserType(browser)) {
case "grid":
DesiredCapabilities capabilities =new DesiredCapabilities();
capabilities.setBrowserName("chrome");
ChromeOptions op = new ChromeOptions();
op.merge(capabilities);
webDriver.set(new RemoteWebDriver(new URL(remoteHubUrl), op));
break;
}
}
Exception Message:
Exception: null
There seems to be no issues when using older versions of chromedriver, any ideas?
Base Step which is used to initialise the driver prior to executing the tests:
#Before
public void setupHook() {
setDriver("grid");
}
The main Issue I see with the above code is that you are trying to instantiate a RemoteWebDriver instance using a ChromeOptions object instead of a DesiredCapabilities object.
RemoteWebDriver requires a DesiredCapabilities (See Selenium code here) which ChromeOptions does not extend or implement. They do both extend AbstractCapabilities so you may just have been getting lucky in the past, but now they have diverged to an extent that they are no longer compatible.
*EDIT*
I would suggest you update your code to do this:
switch (setBrowserType(browser)) {
case "grid":
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
webDriver.set(new RemoteWebDriver(new URL(remoteHubUrl),capabilities));
break;
}
I use Appium with Java to automate tests for mobile applications. It is clear that when I want to write tests for Android I use AndroidDriver<MobileElement> driver = [..] and for iOS I need to use IOSDriver<MobileElement> driver = [..] though with this approach I'd need to write same tests twice for iOS and Android. Is there a way that I could choose type of Appium Driver dynamically based on i.e. some kind of variable to choose between AndroidDriver and iOSDriver? I tried:
if(platform == "Android"){
//returns AndroidDriver
AppiumDriver<MobileElement> driver = COMMON.startAndroid(name, id, platform, version);
} else {
//returns IOSDriver
AppiumDriver<MobileElement> driver = COMMON.startIOS(name, id, platform, version);
}
but below in Test Eclipse points out that with this approach driver is not defined
Both of those drivers extend WebDriver interface (via inheritance). You can define driver from this type. It is also OOP encapsulation concept
WebDriver driver;
if(platform.equals("Android")){
driver = COMMON.startAndroid(name, id, platform, version);
} else {
driver = COMMON.startIOS(name, id, platform, version);
}
public class AppiumController {
public static OS executionOS = OS.ANDROID;
public AppiumDriver<MobileElement> driver;
DesiredCapabilities capabilities = new DesiredCapabilities();
public enum OS {
ANDROID,
IOS,
MOBILEBROWER_IOS,
MOBILEBROWER_ANDROID
}
public void start() {
if (driver != null) {
return;
}
switch(executionOS){
case ANDROID:
// set android caps
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
case IOS:
// set ios caps
driver = new IOSDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
case MOBILEBROWER_IOS:
// set ios browser caps
driver = new IOSDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
case MOBILEBROWER_ANDROID:
// set android browser caps
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
}
public void stop() {
if (driver != null) {
driver.quit();
driver = null;
}
}
}
I have problem with testing my app which is intended for online shopping. I noticed that all buttons from application working but I have problem with system buttons(look at the picture). I’m using to recognize the button UiAutomatorViewer.
At the picture I’m trying add product to cart but when I’m click button “Dodaj”(means Add) the window closes but there are any actions in application, the product should be added to cart. I tested this application manually and everything work correct.
I tried to operate the button in many ways but still nothing. Does anyone know how to solve it? It’s very important functions to testing for me.
public class Product extends MainPage {
private AndroidDriver<AndroidElement> driver;
#FindBy(id = "com.mec.leroy:id/product_add_to_cart")
private WebElement addToCart;
#FindBy(xpath = "//android.widget.Button[#index='1']") //problem with button
private WebElement buttonAdd;
#FindBy(id = "com.mec.leroy:id/product_name")
private WebElement productName;
public Product(AndroidDriver driver) {
super(driver);
this.driver = driver;
}
public Product addProduct() throws InterruptedException {
driver.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(text(\"do koszyka\"));");
addToCart.click();
buttonAdd.click();
Thread.sleep(5000);
return new Product(driver);
}
public boolean productName() throws InterruptedException {
Thread.sleep(2000);
try {
productName.getText();
return true;
} catch (ElementNotVisibleException e) {
return false;
}
}
public class Connector {
public AndroidDriver Settings() throws IOException, InterruptedException {
runAppium();
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "33004db396a6c2d1"); // nazwa urządzenia
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
capabilities.setCapability("noRest", "true");
capabilities.setCapability("fullReset", "false");
// capabilities.setCapability("useKeystore", "true");
//uruchomienie aplikacji z poziomu telefonu
capabilities.setCapability("appPackage", "com.mec.leroy");
capabilities.setCapability("appActivity", "com.mec.leroy.main.activity.MainActivity");
//inicjalizacja połączenia z Appium Server
AndroidDriver<AndroidElement> driver = new AndroidDriver<AndroidElement>(new URL("http://0.0.0.0:4723/wd/hub"), capabilities);
return driver;
}
You are using UiAutomatorViewer (that uses old UiAutomator), but in your tests you are providing UiAutomator2: important to know that these frameworks build snapshot xml in a different way, so your locator might be incorrect.
I suggest to try inspect and interact with your button using official appium-desktop:
Install & launch it
Run the server via appium-desktop
Set exact the same capabilities you have in the code, create new session
Now you can inspect your elements and try to click your button from inspector.
After the attempt to run my tests I always get:
org.openqa.selenium.SessionNotCreatedException: Unable to create new remote session. desired capabilities = Capabilities [{platformVersion=6.0, platformName=Android, deviceName=Xiomi}], required capabilities = Capabilities [{}]
java-client 5.0.0 beta 9
Appium 1.6.5
selenium standalone 3.4.0
Using Android Studio
public class MyTest1 {
AppiumDriver driver;
#Before
public void setUp() throws Exception {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
desiredCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Xiomi");
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "6.0");
URL url = new URL("http://127.0.0.1:4723/wd/hub");
driver = new AppiumDriver(url, desiredCapabilities);
}
#After
public void tearDown() throws Exception {
driver.quit();
}
#Test
public void Test(){
}
}
Please help! I can't understand what am I doing wrong
I've added next desired capabilities and exception stopped occurring:
desiredCapabilities.setCapability("appPackage", "com.package.app");
desiredCapabilities.setCapability("appActivity", ".activities.App");
// Add real app package and activity instead of mine.