Appium Automating hybrid apps - appium

Hi I try to write my first test for an Ionic App and I cant figure out howto do, as the documentation seems to miss some information.
ionic:
I have created a pipeline that builds an APK and and IPA file
I can run those files in the emulators (Android & iOS)
Appium
The server runs, and can connect to the local running Android Emulator
I've create the node.js project as documented in the getting started guide
The following works too:
async function main () {
const client = await wdio.remote(opts);
await client.deleteSession();
}
Result:
[Instrumentation] OK (1 test)
[Instrumentation] The process has exited with code
But now the documentation seems to miss a step, as it starts with (Automating hybrid apps):
driver
.contexts().then(function (contexts) { // get list of available views. Returns array: ["NATIVE_APP","WEBVIEW_1"]
return driver.context(contexts[1]); // choose the webview context
})
How do I get a driver instance in JavaScript, based on the client instance?
Also I have an "async function main ()" now. Is there no pattern to write it like async function test_01, test_02, or more meaningful?

Related

I want to use DispatchQueue in Objective-C. This is a workaround for the warning I get in Flutter

I am developing an app in Flutter.
I am using the geolocator package and when I build my iOS app I get a warning.
The app launches successfully, but I am unable to get GPS information.
I did some research and it looks like the warning is displayed when using xcode14 and iOS16.
It seems that the best way to handle this is to run the app in parallel instead of running it in the main thread.
What I found is Swift code, so I would like to be able to run it in Objective-C as well.
WARNING message
This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the `-locationManagerDidChangeAuthorization:` callback and checking `authorizationStatus` first.
development environment
iOS16.2
Xcode14
geolocator7.7.1
iPhone SE2(Actual Device)
This warning did not appear when the emulator was used. The emulator is also able to acquire GPS information. All emulators are running in Android Studio.
It seems that Xcode14 is the problem.
Can you make the following code Objective-C?
It would be better to enclose it in DispatchQueue.global().async { }.
DispatchQueue.global().async {
//Process with warnings
}
reference
Main thread warning with CLLocationManager.locationServicesEnabled()
Thank you.

Appium iOS | Can't clear user cache

So I have recently stumbled across a "fun" thing for automation and test case runs in general - and that is that iOS is very persistent with the users cache and won't let you delete the apps cache.
The actual issue:
first test case runs fine and logs in the user
the second test case expects the user to be logged out | expects to run on a fresh app - without any left over cache from the previous user <- so because of that it FAILS
I have tried several solutions:
adding capabilities like noReset or/and fullReset
stopping the driver (deleting the app and reinstating it again)
basically everything I could find - I tried
I have managed to fix the issue for SIMULATOR but not for the REAL DEVICE.
If you are doing any appium webdriver automation for your mobile applications - you should have encountered this issue and had to deal with it somehow - would really appreciate your opinion on this topic! (Also I am using SauceLabs for the real devices)
P.s. I don't want to make silly workarounds like loging out the user after each test case - so the next one could start from a fresh app and so on. IMHO this would be a really bad practise | shot-lived workaround.
Edit - code examples.
Capabilities:
config.capabilities = [
{
platformName: 'iOS',
'appium:platformVersion': getRandomOsVersion(osVersions),
'appium:deviceName': 'iPhone .*',
'appium:automationName': 'XCUITest',
'appium:app': 'storage:filename=app.ipa',
'appium:autoAcceptAlerts': true,
'appium:connectHardwareKeyboard': true,
'appium:shouldTerminateApp': true,
'appium:newCommandTimeout': 240,
'sauce:options': {
build: buildName,
name: buildName,
allowTouchIdEnroll: false,
sauceLabsImageInjectionEnabled: false,
},
},
];
Test cases:
describe('Login functionality', () => {
beforeEach(async () => {
await driver.reset();
(await WelcomeScreen.getStartedButton).waitForDisplayed();
});
it('Login with user (finished profile)', async () => {
await WelcomeScreen.getStartedButton.click();
await LoginScreen.submitLogin(USER_CREDENTIALS.USER_WITH_FINISHED_PROFILE);
await expect(await FeaturesTourScreen.letsGetYouStarted).toBeDisplayed();
});
it('Login with user incorrect credentials', async () => {
await WelcomeScreen.getStartedButton.click();
await LoginScreen.submitLogin(USER_CREDENTIALS.INCORRECT_CREDENTIALS);
await expect(await LoginScreen.alertMesage).toBeDisplayed();
});
});
Real Device background
Real devices behave differently in comparison to Simulators. When you install an iOS app on a real device it needs to be resigned so it is allowed to install the app. Removing an app "might" remove all data that has been stored on the device / keystore, but data could still be attached to your iCloud account.
There are no Appium commands to remove the data stored in the keystore or in the app itself
WebdriverIO background
This is not even 100% specific for WebdriverIO, but when you run 2 tests (it) from a single file the end state of the first test will be the starting state of the second test. You can control that with a beforeEach/afterEach, but this will have no/less effect on real devices.
WebdriverIO spins up a single driver for every test file. In theory this should lead to a clean simulator / device when the second test-file is starting
Sauce Labs background
When you are using Sauce Labs you don't have the option to remove the app between the first and second it, because when you remove the app it needs to be resigned and this is not supported. Options like noReset|fullReset won't have an effect on iOS real devices.
If you need to have all data cleared then you need to:
or have a backdoor in your app to do this through Appium
run the second test case in a new spec file. WebdriverIO spins up a new instance for every test file and in between the app is removed and the device is cleaned
I would suggest you ask the developers of the application to add data cleanup logic in the code itself that runs when a specific launch argument is provided when starting the application. Then you can use the Appium capability processArguments to provide that argument to the app when starting the test and the app itself will cleanup the data. Example for providing arguments from Appium issues, Appium XCUITest driver official docs describing the capability

How to debug Electron main process after packaging?

I have created an Electron App(say MyApp). I have used electron-packager to pack the App. I installed the app in my local machine and I can see MyApp in the start menu. When I click on the Icon It launches the app but I am not able to debug it.
I can see the devtool
Electron version : "^5.0.7"
Electron Packager: "^12.2.0"
OS: Windows
Thanks in advance
I think the best way debug your main process would be to do so during development, i have found the information here on the Electron docs to be very useful https://electronjs.org/docs/tutorial/debugging-main-process
Also my Code Editor of choice is VSCode so i was able to use this link
https://electronjs.org/docs/tutorial/debugging-main-process-vscode
Its also good practice to have a Crash Reporter setup, Electron has the default one https://electronjs.org/docs/api/crash-reporter which also work great, but you can add other third party libraries like Bugsnag, Sentry or Backtrace.io.
Default Electron Crash Reporter
const { crashReporter } = require('electron')
crashReporter.start({
productName: 'YourName',
companyName: 'YourCompany',
submitURL: 'https://your-domain.com/url-to-submit',
uploadToServer: true
})
Using Sentry "You need an account for this option"
//You need to call init in your main and every renderer process you spawn.
import * as Sentry from '#sentry/electron';
Sentry.init({dsn:'https://<your-key-here>#sentry.io/15...5'});

ADAL for Cordova - Assistance Getting Started

Hello: I'm trying to get started with the ADAL plug-in for Cordova. Having used the native libraries a few times, I thought this would be pretty straightforward but I ran into a bit of an issue.
First of all my environment is VS2017, and the plugin is ADAL for Cordova 0.10.1.
I've created what I believe is the most simplistic example of a connection, using my own client application specifics and the ones provided in their sample online (which is) included below. My authentication looks like:
function authenticate(authCompletedCallback, errorCallback) {
var authority = "https://login.microsoftonline.com/common",
redirectUri = "http://localhost:4400",
resourceUri = "https://graph.windows.net",
clientId = "a5d92493-ae5a-4a9f-bcbf-9f1d354067d3";
var authContext = new Microsoft.ADAL.AuthenticationContext(authority);
authContext.acquireTokenAsync(resourceUri, clientId, redirectUri).then(authCompletedCallback, errorCallback);
This is then called in onDeviceReady();
acquireTokenAsync is called but doesn't appear to return either success or failure and a quick Fiddler trace doesn't appear to show the call which makes me wonder if it is not a configuration issue with Cordova to begin with.
I have commented out the Content-Security-Policy metatag with similar results.
Thank you in advance for any guidance!
Edit
Okay, perhaps this is helpful. I noticed that on the Cordova Plugin Simulation tab (I am trying to run this in the simulator in Chrome). I am seeing a dialog box with error:
There is no handler for the following exec call:
ADALProxy.acquireTokenAsync(...
Also, seems to work on a connected Android Device, just not in the local Simulator
The plug-in for Cordova doesn't support to run on the browser platform. When we developer an Cordova app and want to test on the browser platform, we have to ensure that the app depends on support the browser platform.
For the ADAL plug-in for Cordova support the platform:
Android (OS 4.0.3 and higher)
iOS Windows (Windows 8.0, Windows 8.1,
Windows 10 and Windows Phone 8.1)
And for other kinds of plug-in you can check it via you the Cordova plug-in.

IBM Worklight - How to enable App Authenticity in a native iOS app?

We have a iOS and Android Hybrid App Environment in which we have App Authenticity successfully running (drop down available to control the feature) using:
<mobileSecurityTest name="app">
<testAppAuthenticity/>
<testUser realm="wl_anonymousUserRealm"/>
<testDeviceId provisioningType="none" />
</mobileSecurityTest>
We added a "iOS Native API" project to our Worklight project that we use for our native iOS client development in XCode 5. We are successfully able to connect to the WL server and call all our existing adapter procedures in our different adapters.
For this native API project, we now would like to enable App Authenticity as well. When we use the same MobileSecurityTest as in the hybrid app in the application descriptor of the native API project we can deploy it to our WL server and the App Authenticity feature is enabled (drop down available to control the feature) at the iOS Native API entry in the console.
On the native iOS app/project we set:
bundle ID is exactly the same as in the hybrid project and the same as in the Apple Developer portal
Key Chain is enabled in the project and also set to worklight.group (as in the hybrid XCode project)
we are not able to get a successful authentication running when we want to connect to WL server. We see that the DeviceAuthManager tries to get the UUID from the device, but then the server returns an error response:
2013-09-24 08:58:35.530 App[32535:c07] DeviceAuthManager:getWorklightUniqueDeviceId --> returning UUID from the keychain
2013-09-24 08:58:35.564 App[32535:c07]
isCustomResponse
2013-09-24 08:58:35.564 App[32535:c07] this is it: Status: 403
InvocationResult: (null)
InvocationContext: {
delegate = "<MyConnectionListener: 0x7d73ec0>";
}
Response text: /*-secure-
{"WL-Authentication-Failure":{"wl_authenticityRealm":{"reason":"com.ibm.json.java.JSONObject cannot be cast to java.lang.String"}}}*/
2013-09-24 08:58:35.564 App[32535:c07] [ERROR] Worklight: -[WLRequest requestFailed:]:309::Status code='403' error='(null)'
2013-09-24 08:58:35.565 App[32535:c07] [ERROR] Worklight: -[WLClient onInitRequestFailure:userInfo:]:410::
We did try this with and without a registered ChallengeHandler that just prints the response. The same results, just that we can see the error response printed in the isCustomResponse method if we have the ChallengeHandler.
Also, a Worklight dialog is shown automatically that says "Error: An error was encountered while processing the request from the application (CLOSE)".
We can see that in 6.0 there is the worklight.plist value:
<key>wlUid</key>
<string>wY/mbnwKTDDYQUvuQCdSgg==</string>
is that also necessary in 5.0.6? Our plist file there does not have that.
When we change the environment value in the worklight.plist file from iOSnative to our app name (or something else) we get a response Response text:
{"errorCode":"UNEXPECTED_ERROR","errorMsg":null}
so I assume this value iOSnative is a fixed value that has to be there?
Sept 30th: WL 6.0.0.1 Update
In WL 6.0.0.1 it seems to not show the same bug when we used it with a Studio 6.0.0 generated iOSApi Environment deployed to a Consumer Server on Tomcat.
Now we are getting an:
Invocation Failure: Status: 403
InvocationResult: {
"WL-Authentication-Failure" = {
"wl_authenticityRealm" = {
reason = "forbidden state";
};
};
}
when we have Enabled, blocking and we can connect and call Adapters when we change to Enabled, servicing. (which was not possible with the 5.0.6 bug before)
Now we assume we need to somehow setup our iOS Certificates or Signatures that we use to sign the app for the iOS Simulator and for the iOS Devices (Developer and Distribution Certificates) on the Wl server, so that the WL Server allows a connection?
Could someone help us with the steps that we need to take to setup an iOS native App Authenticity in our XCode 5 project to successfully connect to the server and after that call our adapters with Enabled, blocking.
We did add worklight.group to the turned-on Keychain Sharing capability of the iOS app.
We copied all Wl iOSAPI files including the plist file with the wlUid into the iOS app xCode5 project?
As mentioned above, it works with Enabled-Servicing and with Disabled AppAuthenticity fine.
For App Authenticity to function in a native iOS application using the Worklight Native API for iOS, the steps are the same as in a Hybrid application on the Eclipse side:
Setup the securityTest in authenticationConfig.xml
Add the securityTest to the iPhone environment application-descriptor.xml
Add your bundleId to the iPhone environment in application-descriptor.xml
There is, however, 1 extra step to do - in Xcode.
Once you open the generated Xcode project:
Under Build Settings > Linking > Other Linker Flags
Add the flag -ObjC
Now you can Clean and/or Run the project on the iOS Simulator/device. Should work.

Resources