I'm facing an issue in which I can't tap on some elements because they belong to a view/window that is on another layer of where the Appium driver operates. This would be solved if I could somehow change the focus to this new layer, like we do in Webdriver with the window handles methods.
I think I can workaround over this issue by executing my tests on the simulator (app file) instead of real device (ipa file) which led me to think. Is it a wrong approach to try to test on real device with ipa file?
I don't think so but that's what came to my mind after this situation.
What type of view it is ? In appium we have context concept.
When you are trying to interact with native component of any app in ios and android the it is known is native context and when elements are in any webview then it is webview context. You can get available context anytime using following code:
Set<String> contexts = driver.getContextHandles()
For example if you want to switch to webview then you can use following code:
Set<String> contexts = driver.getContextHandles();
for (String context : contexts) {
if (context.contains("WEBVIEW")) {
driver.context("WEBVIEW");
}
}
Related
I have a cross platform app that runs on Windows and Mac. It is using WCF on .NET 4.5.2. In the BasicHttpBinding configuration in the settings file I am setting the transferMode="Streaming". We are downloading large files using this service.
On Windows everything works fine. The WCF method call returns right away and then when I read from the Stream member of the MessageContract object the file is streamed as excepted.
When I run the same app in Visual Studio for Mac I have 2 problems. The first problem is that the transfer mode in the binding is Buffered instead of Streamed.
I fix that by changing it in code after creating the channel. Here is the code I use to do it. Maybe this is the problem:
private IDataService CreateClient()
{
Channel = new ChannelFactory<IDataService>(BindingId);
var binding = Channel.Endpoint.Binding as BasicHttpBinding;
binding.TransferMode = TransferMode.Streamed;
Channel = new ChannelFactory<IDataService> (binding, Channel.Endpoint.Address);
var client = Channel.CreateChannel();
return client;
}
Notice how I read the binding, change the transfer mode and then create a new channel using the new binding. This seemed to be the best way to get the same settings from the settings file, but switch the transfer mode.
When the download method call is made I am able to see in the debugger where the transfer mode on the binding is Streamed, where before it was Buffered.
The problem I have at this point is that even though the transfer mode is Streamed, the download WCF method call doesn't return until the whole file is downloaded. It is acting like it is still in Buffered mode.
Any ideas how to fix this?
It looks like the streaming setting doesn't work in the Xamarin implementation of .net 4.5.2 that we are using. Not sure if it works in later versions or not.
I ended up adding a REST api just for downloading large files...
I am using Akavache standard approach on iOS (actually, it's .NET Standard project for Android/iOS), but the issue appears with iOS only.
I save some value during the app lifecycle:
await BlobCache.Secure.InsertObject("user", user);
And on the app new session this:
var user = await BlobCache.Secure.GetObject<UserModel>("user");
But the object is not available (with KeyNotFoundException exception).
Recently I also was trying to call BlobCache.Secure.Flush().Wait() right after the object saving, but there is still no effect.
The issue happens with iOS only. Android is fine.
The issue happens with both Secure and UserAccount objects.
The data is not available even after "gentle" BlobCache.Shutdown().Wait() on the application closing. So, have no idea even where to search the solution now.
Any thoughts why might cause this issue and how I can solve it?
There's another issue people have had is that the SqlLite cache is getting linked out. If you check the type on LocalMachine and it's of type MemoryCache that won't be resilient.
Just add the linker static class somewhere in your project (even if it's a PCL or Standard lib).
That worked for me.
Did you set the ApplicationName property on BlobCache? On iOS this seems more of a necessity than on Android it seems.
We are trying to migrate from UIAutomation to XCUITests and did use the captureScreenWithName() API to programmatically generate screen shots.
What is the replacement in the XCUITests ?
(I know that automatically screenshots are taken in case of error, but we have a special test which runs forever in a loop and evaluates QA click,tap commands via network similar to the appium-xcuitest-driver https://github.com/appium/appium-xcuitest-driver)
Do I need to rip out private headers (XCAXClient_iOS.h) like the appium guys did in order to get a screenshot API?
Edit
I used the actual code line for the accepted solution from
https://github.com/fastlane/fastlane/blob/master/snapshot/lib/assets/SnapshotHelper.swift and its just this for IOS
XCUIDevice.sharedDevice().orientation = .Unknown
or in objC
[XCUIDevice sharedDevice].orientation =UIInterfaceOrientationUnknown;
I use a process on the host to lookup in the "Logs/Test/Attachments" directory all Screenshot_*.png files before the call , and find the new shot then after the call as the new file added in this directory.
Gestures (taps, swipes, scrolls...) cause screenshots, and screenshots are also often taken while locating elements or during assessing expectations.
Fastlane's snapshot tool uses a rotation to an unknown orientation to trigger a screenshot event (which has no effect on the app): https://github.com/fastlane/fastlane/tree/master/snapshot - you can use this if you want to be in control of some screenshots.
Currently I'm writing all the Test Case actions in one javascript file, and using Xcode Instruments automation.traceTemplate file for executing the Test Case.
Following are contents from TestCase file.
var target = UIATarget.localTarget();
var app = target.frontMostApp();
var window = app.mainWindow();
//target.logElementTree();
target.delay(2);
UIATarget.localTarget().captureScreenWithName("Application launched");
target.frontMostApp().mainWindow().textFields()[0].setValue("demo");
target.delay(2);
UIATarget.localTarget().captureScreenWithName("Username entered");
var passwordfield = target.frontMostApp().mainWindow().secureTextFields()[0];
passwordfield.setValue("demo");
My Requirement:
I want to perform one action at a time on iOS device using Xcode Instruments instead of passing complete Test Case file as a input similar to implementation of Appium tool.
Thanks in advance..........
XCode instruments natively do not support on the fly Javascript. You have to have all your javascript in one file and execute all of the script at once. You are not able to stop execution, have separate test cases etc.
This is where appium comes into play, it will allow arbitrary JS execution. You create your test cases in the appium/selenium format and they would send commands to instruments in the background.
Run through this tutorial http://appium.io/slate/en/tutorial/ios.html?java#native-ios-automation and you don't even have to use JS, you can use Java/Ruby and you will be in a better shape.
Check out appiumRepl
You can send commands one-by-one and watch them happen on the device/emulator in realtime :)
There's a Ruby REPL as well.
Tried with
handle = self.driver.window_handles[0]
self.driver.switch_to_window(handle)
on emulator, but no luck. I am not able to access / manipulate the elements in the page. I don't even know if i got switched to web view.
Any suggestions on how to use web views on iOS with appium (python) ?
driver.window_handles[0]is probably the current window - try inspecting window_handles to see what other windows are available. On iOS, the app that I test just has window handles like '1', '2', etc, and switching to the last element of window_handles usually does the trick.
Please use the below code to switch to WebView , if you are using appium 1.0
self.driver.switch_to.context('WEBVIEW');