Generic mobile tests with appium - android

I'm new to mobile testing , and currently I research for an automation framework for mobile testing.
I've started to look into Appium, and created some tests for the demo app I've made (one for IOS and the other for Android).
I've managed to write a test for each of the platforms , but I was wondering , how difficult it might be to write a one generic test which will be executed on the both platforms with minimum adjustments ?
Thanks

It is possible but you have to keep same labels for each component for all platforms, for example to click on a button, instead of locating through Xpath locate by its name.
WebElement button = driver.findElement(By.name("my button")); button.click();
More info finding elements in Appium docs:
http://appium.wikia.com/wiki/Finding_Elements

I built an automation framework from scratch which does exactly the same thing, i.e. have one code base and the tests run both on Android and iOS based on what device and app you give the test. This is how I went about doing it. (I used Java+Appium+Cucumber framework).
Following the Page Object pattern is a good practice for writing automation code.
That being said, you will have all the resource ids of Android and Accessibility ids of iOS in 2 separate files under a folder named say "ObjectRepository". These files usually have the extension of *.properties (It is called the properties file).
Say you have a Login button that you want to interact with on Android and iOS, you have will 2 files:
File 1) "androidObject.properties" which has:
Login.LoginButton=loginAndroidBtn
File 2) "iOSObject.properties" which has:
Login.LoginButton=loginiOSBtn
NOTE: In the key/value pair above, the key is the same "Login.LoginButton", the value is the resource id and the accessibility id of the Login Button in your Android and iOS application
In your code you would do the following:
if(IS_ANDROID) {
DRIVER.findElementById("Login.LoginButton").click();
} else {
DRIVER.findElementByAccessibilityId("Login.LoginButton").click();
}
In another file you would set what IS_ANDROID and IS_IOS means. You may do something like this:
public static DeviceConfig DEVICE_CONFIG;
private void setPlatform() {
if (DEVICE_CONFIG.platformName.equals("Android")) {
IS_ANDROID = true;
} else if (DEVICE_CONFIG.platformName.equals("iOS")) {
IS_IOS = true;
}
This way you can have one code base and run Android and iOS seamlessly.

Related

Create and change to new view with React Native

We're currently working on an app for one of our customers, and we've decided to use React Native as the technology to use for creating the app.
I'm pretty new to this technology, and I'm used to developing apps with either C# or Java, where I have full-fledged IDEs that provide all the functionality I need.
I'm currently creating a login screen, and would like to change to different views, depending on the type of login (e.g.: Facebook, Google, Twitter, Email, etc.).
How do I go about doing this. As I mention, with an IDE, it'd be a shortcut like SHIFT+ALT+A or something to create a new item, select type, name it and the IDE does the rest.
Do I have to create a new xx.android/ios.js file, and somehow call that, or do I need to go in to the native backend of the different projects?
What I tried was something along the lines of:
class Class extends Component {
render() {
<UI code here>
<Button onPress={this.eventHandler}
}
eventHandler(event) {
var xxLogin = new xxLogin();
xxLogin.render();
}
}
class xxLogin extends Component {
render() {
<UI code here>
}
}
But that failed, which I expected.
Thanks in advance for any help!
P.S.: I'm using Mac OS X El Capitan, if that helps.

Show image in TImage dynamically (at run time) without opendialog in c++ builder xe8

I want to show image (png,jpg etc) in dynamically created (as per requirement and fully through coding) TImage component, at runtime in C++ builder xe8 (not delphi). But I dont want to use opendialogbox (suggested in many web sites). I want to run this app on my android device. I tried to use LoadFromFile(), it crashes the app on android, but when I run this on windows, its running smoothly. I am just a beginner to c++ builder. So guys pls help. Thanx in advance for any kind of help.Here is what I did.
void __fastcall TForm1::TForm1(TComponent* Owner)
{
TImage* img = new TImage(this);
img->Parent = this;
img->Bitmap->LoadFromFile("D:\\res\\profile.png");
}
Did you see what is the error?
If you run the program with the provided by you code I assume the error would be that the file is not found, because there is no such directory "D:\" in android.
One way to set the path is to write a static path which points to your image. For example : "/storage/sdcard0/DCIM/Camera/MyImage.jpg";
The second way is to include the <System.IOUtils.hpp> header and to use some built-in functions like:
System::Ioutils::TPath::GetPicturesPath();
System::Ioutils::TPath::GetAlarmsPath();
You can check them out, they might be useful.

Using Cordova, is there a way to reference native icons?

I'm using Cordova 3.5 to build an app which contains a menu with pretty standard items in the list (home, contacts, etc.), and I want to use the native menu icons whenever possible. I believe those icons are already on the device as part of the OS, but I don't know if Cordova gives me a way to reference them.
I suppose I'd need to write a Javascript function to choose the right file name based on the platform, e.g.:
// this is pseudocode
var icon = '';
if (platform === 'android') {
icon = 'some/path/home.png';
} else {
icon = 'other/path/icon.home.png';
// or maybe a function such as the following exists:
// icon = cordova.getNativeIcon('icon.home.png');
}
$('.selector').css('background-image', icon);
Alternatively, I may be able to make do by referencing the files in CSS, e.g.:
.android .home-icon {
background-image: url('some/path/home.png');
}
.ios .home-icon {
background-image: url('other/path/icon.home.png');
}
So, how do folks handle this sort of thing in Cordova? Is there a function I can use to access native icons? Are folks just copying them into their projects? What's the best practice?
If you're working with Cordova, then you'll be working inside a web view provided by the host OS and you won't have direct access to any artwork. I've found that using icon fonts and CSS "themes" to work well enough, but that approach will replicate artwork already provided. There's extra work involved with theming for iOS 6 vs iOS 7 or 8, for example, but it's not as bad as it sounds.
IBM does have an article on partitioning your view between native and web controls, but it sounds a bit cumbersome. More details here: https://www.ibm.com/developerworks/community/blogs/worklight/entry/ios_combining_native_and_web_controls_in_cordova_based_applications

Same Titanium code base for Android & Iphone

I have been trying to create a single codebase for both Iphone & Android for a intermediate level app. ( 4 tabs, multiple windows, maps etc.) using itanium 2.1 API.
However, I have found that things on Android platform dont work as smoothly or willingly as on Iphone epsecially tableviews & UI elemnts. The UI responsiveness on Android is also sluggish.
The kitchen sink examples are pretty straightforward. I am looking at an enterprise ready app which has to be maintained for atleast next couple of years.
Has anybody worked on similar lines with platform quirks and been successful in creating fully functional iOS & Android apps from SAME codebase?
I'm having a lot of success using the compile-time CommonJS mechanism for having a root view that then has os-specific capabilities.
For instance, my os-independent view might be ui/MyView.js :
var createAddButton = require("ui/MyView.AddButton");
var MyView = function() {
var self = Ti.UI.createWindow();
createAddButton(self, function() { alert('ADD!'); });
return self;
};
module.exports = MyView;
Then, I create os-specific functions to handle it:
iphone/ui/MyView.AddButton.js
module.exports = function(view, addHandler) {
var addButton = Titanium.UI.createButton({
systemButton: Titanium.UI.iPhone.SystemButton.ADD
});
addButton.addEventListener("click", addHandler);
view.rightNavButton = addButton;
};
android/ui/MyView.AddButton.js
module.exports = function(view, addHandler) {
view.activity.onCreateOptionsMenu = function(e){
var menuItem = e.menu.add({ title: "Add" });
menuItem.addEventListener("click", addHandler);
};
};
The CommonJS system they have implemented will pick the appropriate version of MyView.AddButton.js so that the button is added to the right place. It allows for the majority of the view to be the same, but the os-specific things to be separated properly.
Titanium is not meant for 1 codebase for all. You do need to rewrite stuff for every OS. However, some app developers claim to have reused 95% of its code. So only 5% of the code is OS specific. But I am sure their code is full with if-elses.
What I recommend doing, to be able to maintain it properly, without thousands of if-else constructions, is build a single backend core, and write code specifically for UI related matters per OS. This way, you have some UI related code for Android, UI related code for iOS and 1 core working for both.
Since Android and iOS differ a lot, writing a single codebase will make sure you can never use OS specific features (like android hardware menu button, or iOS NavigationGroup), and will let the UI look non-intuitive.

Android Compile Time directive

I have an android application with different flavours.What I mean by flavours is that they differ only in their application name,icon and a url that webview in the application uses.
What I have now:
Application 1 with app_name1 and icon1:
{
Code...
myWebview.loadUrl(url1);
code..
}
Application 2 with app_name2 and icon2:
{
SameCode...
myWebview.loadUrl(url2)
Samecode..
}
What I would like to have :
Application(pick the application name and icon from build parameter):
{
Code ..
myWebview.loadUrl(pick the url from build parameter)
Code..
}
Is this possible?
This would be so good to have as I am manually copying any change that i do in either of the projects to the other and I am scared about how I would handle more than 2 "flavours".
You probably want to take a look at Library Projects. See for instance this blog post:
Library Projects allow you to share some whole parts of your applications, resources included.
The main and immediate use is to create several versions of the same application.
You should in any case be using resources to refer to these things. So e.g
<application android:label="#string:app_name" android:icon="#drawable:icon">
in your AndroidManifest.xml, and
String rl = getString(R.string.url);
in your code.
Then you simply have to swap in the right res/values/strings.xml and res/drawable/icon.png, and change the name of your final apk.

Categories

Resources