How to Switching between two native apps using appium - appium

I would like to switch between two apps without loosing the previous state of the application. How can we achieve this using appium.
Scenario:
1. Launch any application which requires OTP to login ( Ex:filpkart)
2. Launch SMS application and read the OTP
3. Close SMS application and Switch back to first app and enter OTP which we read it from SMS application.
Could some one help me on this.
Regards,
Shiva Oleti

Well if you want to send an app in background then simply use driver.CloseApp() function and relaunch it by driver.OpenApp()
You can also use press keycode method Below are the codes
Home Menu Button - 82
Back Button - 4
Recent app - 187
and then perform the getOTP activity from message then switch back to main app

Step1:- Launch app normally passing all the desired capabilities(For e.g Flipkart app)
Step2):- perform action to get OTP
Step3):- Once OTP received try to pass th AppPacakge and AppActivity of the messaging app where you get otp to below method(you get app pacakage and activity by adb shell command)
public String startNewAndroidActivity(String AppPacakge, String AppActivity) throws
Exception{
String actvty = null;
Activity activity = new Activity(AppPacakge, AppActivity);
activity.setAppWaitPackage(AppPacakge);
activity.setAppWaitActivity(AppActivity);
activity.setStopApp(false);
try {
((AndroidDriver<MobileElement>) driver).startActivity(activity);
Thread.sleep(1000);
actvty = ((StartsActivity) driver).currentActivity();
System.out.println(actvty);
}
catch (Exception e) {
System.out.println("Error occured while starting new Activity
"+e.getMessage());
e.printStackTrace();
}
return actvty;
}
Step4). Once message(OTP) is read close the message application by below method.
public boolean closeApplication() throws Exception {
boolean flag = false;
if(driver!=null) {
driver.closeApp();
flag = true;
}
return flag;
}
Step5). Once this is close find the Xpath of the field where you need to copy the otp. Paste it and go ahead.
P.S:- This work well with Android app.

Updated
For that you need to define two AppiumServer with different port, two AppiumDriver (one for sms app and another for another app).
Start appium driver with 2 different port eg: 4723 and 4724. Define 2 drivers:
public static AppiumDriver<MobileElement> driver1;
public static AppiumDriver<MobileElement> smsDriver;
Define DesiredCapabilities for both app and initialize both driver.
First open and do Login.
public void startApp1(){
DesiredCapabilities cap1 = new DesiredCapabilities();
cap1.setCapability(MobileCapabilityType.NO_RESET, true);
cap1.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 600);
cap1.setCapability(MobileCapabilityType.DEVICE_NAME, "android device");
cap1.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
cap1.setCapability("appPackage", "your app1 package name");
cap1.setCapability("appActivity", "your app1 package name");
cap1.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
driver1 = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), caps);
}
After that start sms and perform the action
public void startApp2(){
DesiredCapabilities cap2 = new DesiredCapabilities();
cap2.setCapability(MobileCapabilityType.NO_RESET, true);
cap2.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 600);
cap2.setCapability(MobileCapabilityType.DEVICE_NAME, "android device");
cap2.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
cap2.setCapability("appPackage", "your app1 package name");
cap2.setCapability("appActivity", "your app1 package name");
cap2.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
smsDriver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4724/wd/hub"), caps);
}
Now to switch from app1 to app2 you can use call startApp2 method. Now if you want to switch back again to switch to app1. Use:
driver1.activateApp(appPackage of app1);
now if you again want to switch to app2 use:
driver2.activateApp(appPackage of 2nd app);

Related

How to implement deep linking in flutter, with redirect to app store?

Is there a way to achieve deep linking in a flutter, so that if a user clicks on a link then they are redirected to a specific part of the app, given that the app is installed, but if it isn't, they are redirected to the respective app store, to install the application and then taken to that specific part?
While searching for a solution I came across this package called uni_links but I am not sure if it can fulfill this requirement.
You can use Firebase dynamic links for this purpose:
https://firebase.google.com/docs/dynamic-links
There it says:
if a user opens a Dynamic Link on iOS or Android and doesn't have
your app installed, the user can be prompted to install it; then,
after installation, your app starts and can access the link.
You can find information on how to implement this with Flutter here:
https://pub.dev/packages/firebase_dynamic_links
I have tried it myself with Android and iOS and it worked fine. If the app is not installed, the Google Play store or Apple AppStore is opened. The user can tap "Install" and then "Open". Afterward your app is started and the dynamic link is sent to your app (on iOS via the clipboard) where you can access it as explained on the website above. I.e. right after the start of your app in the first initState method you can call
final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.retrieveDynamicLink();
final Uri deepLink = data?.link;
to get the deep link. However in my experience on iOS this is too early to retrieve the link. I got "null" when trying it. It seemed to take a moment. I then used a WidgetsBindingObserver and watched in the didChangeAppLifecycleState method for AppLifecycleState.resumed. There I called retrieveDynamicLink. Due to a permission request (if the user allows notifications) the method was called twice. The first time it returned null but when it was called the second time it returned the deep link. So my solution looks like this:
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
_retrieveDynamicLink();
}
}
/**
* Laden des Deep Link nach der Installation.
*/
Future<void> _retrieveDynamicLink() async {
final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.retrieveDynamicLink();
final Uri deepLink = data?.link;
if (deepLink != null) {
// Use the deepLink
// ...
}
}
As of iOS 12 there is no way to have a direct application deep link that redirects to the app store if your application is not installed.
You can have a deep link to the app store or a deep link within your app using the meta tag apple-itunes-app on a website. But this only shows a small banner at the top of the page, and is not a true deep link.
One system that I haven't used before but might be worth checking out as well is branch.io. You might be able to achieve something like that with their system, but I'm not exactly sure how it works. It for sure is not native as part of iOS 12.
I am answering late but it will might help to others.
We can use firebase dynamic links for deep linking in a flutter with firebase_dynamic_links plugin. Refer this link for full implementation steps and create and receive a link, https://medium.com/better-programming/deep-linking-in-flutter-with-firebase-dynamic-links-8a4b1981e1eb. Here is a sample code for receiving a link inside the app and open a specific screen.
class MainWidgetState extends State<MainWidget> {
#override
void initState() {
super.initState();
this.initDynamicLinks();
}
initDynamicLinks(BuildContext context) async {
await Future.delayed(Duration(seconds: 3));
var data = await FirebaseDynamicLinks.instance.getInitialLink();
var deepLink = data?.link;
final queryParams = deepLink.queryParameters;
if (queryParams.length > 0) {
var userName = queryParams['userId'];
openSpecificScreen(userName);
}
FirebaseDynamicLinks.instance.onLink(onSuccess: (dynamicLink)
async {
var deepLink = dynamicLink?.link;
final queryParams = deepLink.queryParameters;
if (queryParams.length > 0) {
var userName = queryParams['userId'];
openSpecificScreen(userName);
}
debugPrint('DynamicLinks onLink $deepLink');
}, onError: (e) async {
debugPrint('DynamicLinks onError $e');
});
}
openSpecificScreen(String userName){
Navigator.of(context).pushNamed("routeFormScreen", arguments: {"name": userName});
}
}

Appium - Close one iOS application and reopen another application

I have the following scenario to be automated. How this could be achieved through Appium.
1. Launch my application register a user with an gmail id.
2. Close the application.
3. Launch Safari browser and navigate to gmail login
4. Click on the registration link.
Here, challenging part is point number 2 and 3.
Can Appium session be disconnected?
Can Appium start a new session for a pre installed application like Safari?
You can just use the same appium server instance. No need to kill the server, but you will want to probably use two different driver instances.
AppiumDriverLocalService service;
IOSDriver iosDriver;
public void setUp() throws IOException {
service = AppiumDriverLocalService.buildDefaultService();
service.start();
}
public void startMyApplication(){
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone");
dc.setCapability(MobileCapabilityType.UDID, "3838n838fn38jf8n838ffabcdefg");
dc.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.IOS);
dc.setCapability(MobileCapabilityType.APP, "com.your_package.name");
iosDriver = new IOSDriver("http://localhost:4723/wd/hub", dc);
}
public void testMyGoogleLoginOnMyApplication(){
//I intend to do something here
//Once i am finished, I close my application
iosDriver.quit();
}
public void startSafari(){
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone");
dc.setCapability(MobileCapabilityType.UDID, "3838n838fn38jf8n838ffabcdefg");
dc.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.IOS);
dc.setCapability(MobileCapabilityType.APP, "com.safari_package.name");
iosDriver = new IOSDriver("http://localhost:4723/wd/hub", dc);
}
public void testSafari(){
//I intend to go to google and do stuff
//Once i am finished, I close my application
iosDriver.quit();
}
public void finished(){
service.stop();
}
Just came across a solution that works for all iOS versions and Xcode versions:
driver.background_app(-1)
From the springboard, find the Icon and click it!

Invoking access prompt and show it to the user

A little background:
I developed a game in Libgdx and upload it to iTunes app store. My app got rejected with a following reason: (This is not the question but I would like to give you a little background of what I am trying to achieve)
> 17.1 Details
Additionally, we noticed that your app does not obtain user consent before collecting the user's personal data.
Specifically, users scores are posted to a high score feature. Please see the attached screenshot(s) for additional information.
Next Steps
To collect personal data with your app, you must make it clear to the user that their personal data will be uploaded to your server and you must obtain the user's consent before the data is uploaded.
- Starting with iOS 6, there are keys for specifying the reason the app will access the user's protected data. When the access prompt is displayed, the purpose specified in these keys is displayed in that dialog box. If your application will be transmitting protected user data, the usage string in your access request should clearly inform the user that their data will be uploaded to your server if they consent.
My app only upload high score to my server. But okay if Apple states that the user should know about this I will make it clear.
Actual mission:
I dont know anything about objective-c programming since I made this app in Java. But I know that iOS have some security dialogs which prompts the user if they are Okay to use the following feature or data in the app.
I would like to invoke this kind of dialog (with my own message)
I also know that it should be defined in my info.plist file, but I dont know how to access it at runtime and show it in my game.
Does somebody have a clue how to open this up?
You could try my libgdx extension for dialog windows: https://github.com/TomGrill/gdx-dialogs
or:
You need to interface with platform specifig code: https://github.com/libgdx/libgdx/wiki/Interfacing-with-platform-specific-code
Use UIAlertView class in your iOS interface implementation to open an AlertView:
Code example:
UIAlertViewDelegateAdapter delegate = new UIAlertViewDelegateAdapter() {
#Override
public void didDismiss(UIAlertView alertView, long buttonIndex) {
//handle button click based on buttonIndex
}
#Override
public void clicked(UIAlertView alertView, long buttonIndex) {
}
#Override
public void cancel(UIAlertView alertView) {
}
#Override
public void willPresent(UIAlertView alertView) {
}
#Override
public void didPresent(UIAlertView alertView) {
}
#Override
public void willDismiss(UIAlertView alertView, long buttonIndex) {
}
#Override
public boolean shouldEnableFirstOtherButton(UIAlertView alertView) {
return false;
}
};
String[] otherButtons = new String[1];
otherButtons[0] = "No";
String firstButton = "Yes";
UIAlertView alertView = new UIAlertView("Title", "message", delegate, firstButton, otherButtons);
alertView.show();

Using a WISON OR200 in web application ( MVC )

Few days ago i bought a WISON OR200 sensor for a web system that i am developing.
I used the SDK that sent to me the enterprise and was been testing in a window application and worked fine but i need it into a web application and i don´t know how to do it..
this is the windows form application:
WisSensorN WisObj = new WisSensorN(); // instance of wison object
objects in form:
private System.Windows.Forms.Button Enroll;
private System.Windows.Forms.Button Identify;
private System.Windows.Forms.PictureBox FingerPic;
private System.Windows.Forms.Button Stop;
private System.Windows.Forms.TextBox Status;
Load method() //Open() .DataEvent and SetDisplay are needed for the fingerprint
private void Form1_Load(object sender, EventArgs e)
{
WisObj.Open();
WisObj.DataEvent += new _IWisSensorNEvents_DataEventEventHandler(WisObj_DataEvent);
WisObj.SetDisplay((int)FingerPic.Handle);
// i can´t do WisObj.SetDisplay((int)FingerPic.Handle) on mvc web app
// because i can't get FingerPic object from view.
}
private void WisObj_DataEvent(WisSensorNLibLib.DATA data, string str)
{
switch (data)
{
case DATA.DATA_ENROLL:
// save the base 64 string of finger image
break;
case DATA.DATA_IDENTIFY_CAPTURE:
//validation
break;
case DATA.DATA_VERIFY_CAPTURE:
break;
}
}
private void Enroll_Click(object sender, EventArgs e)
{
WisObj.StartEnroll(); // it used for save the fingerprint
}
private void Identify_Click(object sender, EventArgs e)
{
WisObj.IdentifyCapture();
// it used to activate the sensor. When i did this on controller action,
// nothing happen. This is because the property setDisplay was not set
}
Any suggestions?
What can i do?
I asked to the company where i bought the fingerprint reader if have a SDK for web applications and never answered.
Help please!
Thnxs!
I think you are on a very wrong path. You can't simply use a device from a browser. The HTML/javascript 'application' that runs in the browser cannot connect to any local resource like I/O ports or Windows events. You will need special techniques, like ActiveX or Java applet to communicate with a device on a client machine.
Whether your website is MVC or plain ASP.NET or even PHP is irrelevant. If you don't know what ActiveX (and alumni) is used for and what drawbacks it has, you should look for a professional who can help you explain the situation and possibly develop a suitable solution.

launch Blackberry app from link in mail

I can not be more clear with the title :D
Is it possible? to launch an application on a blackbeery just cliking on a "link" inside a mail? i read about taping a url and going to the application but this is much more specific.
thx in advance
Actually you can listen incoming emails.
You can implement menu item that will be available in mail app.
But you can also implement content handler with specific URI to launch your app.
All examples are available in BB samples.
Look in the RIM sample apps, more specifically HTTPFilterDemo.
You have to register a filter for the type of link you need the app to be triggered by (you'll need to put this code in the main method of you app):
HttpFilterRegistry.registerFilter("www.rim.com","com.rim.samples.device.httpfilterdemo.filter");
where "www.rim.com" is obviously the link that should open the app and the second parameter is the package that contains the "Protocol" class. The Protocol class has a callback method:
public Connection openFilter( String name, int mode, boolean timeouts ) throws IOException {
This method will be called each time the user clicks on a link that has the form specified by you. So, to open the app, in the "openFilter" method, do:
int modHandle = CodeModuleManager.getModuleHandle("YourAppModuleName");
ApplicationDescriptor[] apDes = CodeModuleManager.getApplicationDescriptors(modHandle);
try {
ApplicationManager.getApplicationManager().runApplication(apDes[0]);
} catch (ApplicationManagerException e) {
e.printStackTrace();
}

Resources