How to switch driver context from Android to webview in karate - appium

I'm working on a project to automate a mobile application using Karate and appium. The application that I'm working upon seems to be a hybrid one. When I launch the app it redirects me to a web URL to sign-in(web browser) and my karate tests are not able to locate elements present under the sign-in page.
Feature: android test
Background: App Preset
* configure driver = { type: 'android', webDriverUrl : 'xxxxx', start: false, httpConfig : { readTimeout: 120000 } }
Scenario: android mobile app UI tests
Given driver { webDriverSession: { desiredCapabilities : "#(android.desiredConfig)"} }
And driver.click('//android.widget.Button[#text="Get Started"]')
# Sign details
And click('#signInName')
And input('#signInName', 'someone#gmail.com')
And input('#password', '123456')

karate by default keeps you in the native app context. you can check all the context available by invoking a mobile command,
def contexts = driver.script("mobile: getContexts")
or
json contexts = driver.http.path("contexts").get()
and print contexts
you should be able to switch context to web-view as below (instead of WEBVIEW_1 use your respective web-view which you got from the previous step),
driver.setContext("WEBVIEW_1")
and then switch back to native app by
driver.setContext("NATIVE_APP")
try with different locator strategies if facing any issue

Related

Authenticate with Firebase on IOS using a Phone Number

I am working on a Xamarin Forms application and using an iPhone simulator to test the Firebase authentication using phone number. I have checked all project setup needed on to Console and inside the app but I am getting the
Method name: DidReceiveRemoteNotification
Information: {
"com.google.firebase.auth" = {
warning = "This fake notification should be forwarded to Firebase Auth.";
};
}
all the time. I know that because I am using a simulator I will have to go through recaptcha process for this that has also been done (Added Url Scheme for that). Any help or suggestion that can help me to get this problem sorted will be a great help.

Using Firebase Authentication from iOS 7.1.2 Safari

I see this error:
Error: This operation is not supported in the environment this
application is running on. "location.protocol" must be http, https or
chrome-extension and web storage must be enabled.
When I use:
firebase.auth().signInWithPopup(provider)
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log('popup', error);
//webSettings.setDomStorageEnabled(true);
firebase.auth().signInWithRedirect(provider)
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log('redirect', error);
firebase.auth().signInAnonymously().catch(function(error) {
console.log('anonymous', error);
});
});
});
The first two login attempts via popup and redirect fail. It seems to happen only on iOS Safari.
I see others reporting the issue with Cordova, but I don't see an answer and I'm only using web and firebase. Not Cordova or ionic etc.
The anonymous login works on iOS but that is only a test and not what we want to use to use.
If you want to test it you can use https://meetup-reporter.firebaseapp.com/ from Safari on iOS
An example dump of the error object from the returned Promise is:
{"code": "auth/operation-not-supported-in-this-environment",
"constructor": function (a, b)
{this.code="auth/"+a;this.message=b||Xf[a]||"";}, "F": function ()
{return{code:this.code,message:this.message}}, "line": 44, "message":
"This operation is not supported in the environment this application
is running on. \"location.protocol\" must be http, https or
chrome-extension and web storage must be enabled.", "sourceURL":
"https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js",
"stack":
"https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:44:638\nhttps://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:45:258\nA#https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:44:545\nD#https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:45:242\nsignInWithPopup#https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:241:48\na#https://meetup-reporter.firebaseapp.com/__/firebase/4.1.2/firebase-auth.js:260:432\nhttps://meetup-reporter.firebaseapp.com/scripts/main.js:430:36",
"toJSON": function () {var
a=Array.prototype.slice.call(arguments);a:{var
e=Array.prototype.slice.call(a);var l=0;for(var
n=!1,C=0;Cl||l>=fk.length)throw new N("internal-error","Argument
validator received an unsupported number of arguments.");e=fk[l]+"
argument "+(e.name?'"'+e.name+'" ':"")+"must be "+e.N+".";break
a}e=null}}if(e)throw new N("argument-error",d+" failed: "+e);return
b.apply(this,a);}}
signInWithRedirect actually works in Cordova now: https://firebase.google.com/docs/auth/web/cordova
signInWithPopup and signInWithRedirect should also work for iOS7 and up. I just tested both on an iOS 7 device and they both work. What you are experiencing is likely to the fact that you are using this operation in Safari Private/Incognito mode where web storage is disabled. These operations depend on web storage in order to securely communicate the OAuth result to the parent page. You will need to ask your users to switch to regular mode when this happens, or you can use the Google Sign-in JS SDk to get the OAuth credential and then signInWithCredential. I think it may work in incognito mode.

Tizen: native service not started when launched from a hybrid app

There is a Tizen hybrid wearable application: native service and web UI applicatoin.
There is following code to start service from javascript:
tizen.application.launchAppControl(
new tizen.ApplicationControl("http://tizen.org/appcontrol/operation/service"),
"EFdQkhAQ5b.mydemoappliacation",
function() {
console.log("mydemoappliacation service started");
},
function(e) {
console.error("mydemoappliacation failed to start: " + e);
}
);
Everything works well when launch application on SM Gear device. When launch application on emulator - success callback received in JS code, but service not started (no service "main" function invoked).
In case if deploy service as separate application (not in scope of hybrid app) - service starts normally.
Does anyone have any ideas, why service not started on emulator?

Meteor.isCordova and Server side

I am running a Meteor app on both browsers and mobile phones. What I want to do is to update the Accounts.urls.verifyEmail accordingly, so the web app opens if the user registered from the web app, and the mobile app gets launched if the user registered from the mobile app.
This is how I am trying to :
Accounts.urls.verifyEmail = function(token) {
if (Meteor.isCordova) {
return 'lybe://email_verification/' + token;
}
else {
return Meteor.absoluteUrl('email_verification/' + token);
}
};
However, even when registering from the mobile app, Meteor.isCordova returns false.
How can I differentiate on the server from Web and Mobile app?
Meteor.isCordova seems to return true on the client side only.
Any suggestion is most welcome
Accounts.urls.verifyEmail is called from server then you cannot use Meteor.isCordova. I think you can checking in email_verification page if client is ios or android or browser and redirect to correct user.
Or you can modify Accounts package and sending client type (ios, android, browser..) when user register

Xcode UI testing for external launching

Hope the title isn't too vague. In the app I am testing, certain app-flow launches external apps (like Safari or Facebook for example). How can I verify that the app launched them with a UI test? I can test for like an openURL with a unit test but is there an equivalent for UI?
I'm not trying to actually continue after leaving the app, just to test and ensure the appropriate new app or URL was launched. The simulator/recorder can select UI elements from the launched application, but the test breaks at that point of the code. I also tried getting a handle to something on the menu bar (always present in the app, like a hamburger button) while it was there and then checking for it after launching the other app (to make sure it wasn't there). But that broke the test as well.
Is there a work around? Or is this just something to be tested by a Unit Test?
As you mentioned, the UI framework can only test the given application. So I would do an assert to make sure that the screen you were previously on (before opening safari or facebook, etc) is no longer present. So for example:
XCTAssertFalse(app.tables.elementBoundByIndex(0).exists, "Found element, so app didn't open safari/facebook")
You're just asserting that the element isn't there, change app.tables.elementBoundByIndex(0).exists to be whatever element you're checking.
Xcode 13 and iOS 15 for safari : we could check if safari opens as below.
let safari = XCUIApplication(bundleIdentifier: "com.apple.mobilesafari")
let isSafariBrowserOpen = safari.wait(for: .runningForeground, timeout: 30)
Then do what you want :
if isSafariBrowserOpen {
// Safari browser has opened, then additionally we could check if the url isn't nil
safari.textFields["Address"].tap()
let url = safari.textFields["Address"].value as? String
XCTAssertNotNil(url)
}
else {
// Safari browser hasn't opened
// do something here, if necessary
}
Note: I didn't check with other external apps.

Resources