How do I get SetOrientationPortrait() and SetOrientationLandscape() to work?

I have a number of automated tests running on a physical Asus Android tablet. However, attempting to use SetOrientationPortrait() or SetOrientationLandscape() makes no difference to what happens. Is there something I need to do, beyond simply calling those methods, to get them to take effect on a physical device? Do I need to somehow disable the sensors in the device to prevent the o/s overriding those calls?

Many thanks,

John H.

Answers

  • JohnHardmanJohnHardman GBUniversity mod

    Bump.

    Has anybody solved how to use UITest to test both landscape and portrait mode operation on the same physical device without having to physically move the device?

    Thanks,

    John H.

  • DavidLavenderDavidLavender GBXamarin Team Xamurai
    edited August 2015

    The SetOrientationPortrait() or SetOrientationLandscape() should work perfectly for what you are trying to do. A few things to consider when using these methods:

    1) Whether or not the app supports landscape mode. If it does not, UITest will not be able to manipulate the UI into a landscape view.
    2) If the physical device is set to force portrait mode only. If that is the case an app cannot override this setting and by extension UITest can have no effect.

    Cheers,
    David

  • JohnHardmanJohnHardman GBUniversity mod

    @DavidLavender - Thanks David. Unfrotunately, I'm not seeing SetOrientationLandscape or SetOrientationPortrait having any effect during my automated tests - the app operates based on the physical orientation of the device rather than this setting. For Android, my test code starts as follows. Am I missing something? Many thanks.

                var v = Xamarin.UITest.ConfigureApp.Android.ApkFile(_droidPath)
                    .EnableLocalScreenshots()
                    .DeviceSerial(deviceId);
                app = v.ApiKey(XamarinTestCloudKey).StartApp(appDataMode);
    
                if (landscapeMode)
                    app.SetOrientationLandscape();
                else
                    app.SetOrientationPortrait();
    
                app.DismissKeyboard();
    
  • DavidLavenderDavidLavender GBXamarin Team Xamurai
    edited August 2015

    Hi John,

    The methods you are using to set orientation will in effect 'force' that orientation, meaning it does not matter what the state of the physical device is. Bare in mind there are native settings on all Android devices which could be forcing portrait only, this app is not able to override that.

    I would suggest that there might be something wrong with the 'landscapeMode' variable. Generally in UI testing, the state of the application (and device) under test should be known and as such there should be no need for the if else pipe. Attempt to refactor the code simply to SetOrientationLandscape() when required and hopefully, that will have the desired effect.

    I would suggest as good practice when automating on a physical device, to keep your device in a portrait orientation and let the test drive landscape when required.

    Cheers,
    David

  • JohnHardmanJohnHardman GBUniversity mod

    @DavidLavender - I've double-checked the value of the landscapeMode variable and it does hold the expected value. I've also been through all of the settings on my physical test device, including the developer options. I cannot see anything that would affect this (I did try Auto-Rotate Screen both checked and unchecked, but to no avail). Is it possible that there is something in the Xamarin.Forms libraries that prevent SetOrientationLandscape and SetOrientationPortrait from working (my AUT is a XF app)?

  • JohnHardmanJohnHardman GBUniversity mod

    @DavidLavender - I ran tests on a simulator yesterday. On the simulator, the landscape and portrait switched as expected, but I have still been unable to get the desired switching on physical test devices, despite having gone through all of the likely looking settings that I found. If you see switching of orientation when you run on physical devices, without physically moving the devices, could you let me know which options you had to change to get this to work please.

    I'd like to get this working on Android first, but will need to do the same on iOS shortly thereafter.

    Thanks again,

    John H.

  • DavidLavenderDavidLavender GBXamarin Team Xamurai

    Hi John,

    The methods do work on a physical devices. There are setting in the android system tray (normally drag down menu from the top of screen) which can force portrait mode, other than that i can't see why it wouldn't be working for your device. I would perhaps try a different device to see if that makes any difference. If you have an indie license, you could also try pushing the tests that work on the emulator to the Xamarin Test Cloud as you get a free 60 minutes to use.

    Let me know if you have any luck after trying those options.

    Cheers,
    David

  • JohnHardmanJohnHardman GBUniversity mod

    @DavidLavender

    Hi David,

    On simulators/emulators the orientation changes as expected based on the method call. On physical iOS devices it also changes as expected. But on my 3 physical Android devices (one Moto phone, one Asus tablet, one Amazon Fire tablet) the orientation does not switch based on that method call. I have enabled/disabled "Auto-rotate screen" and switched between "Auto Rotate"/"Rotation Locked", but this has had no effect on the physical Android devices. Are you aware of any other settings that might impact SetOrientationPortrait and SetOrientationLandscape on Android?

    (I have a business license and have bought a package of extra Test Cloud time, so I may give it a try on Test Cloud at some point. However, I'm trying to preserve my device minutes for "proper" testing, as even the small number of tests I currently have will use up my month's quota in one run on one device. Test Cloud is too expensive for "micropreneurs" like me to use for anything that can be done elsewhere. Like a number of other people, I feel like I spend a large chunk of my time doing free work for Xamarin, investigating Xamarin bugs, creating samples for reproducing Xamarin bugs, helping other customers in the forums with problems they hit because most of the Xamarin documentation is so poor etc., rather than being productive on my own project (I have 26 outstanding Xamarin bugs in bugzilla at the moment). Using my Test Cloud minutes for something that is not testing my functionality feels much the same as spending another day creating yet another sample).

    Thanks,

    John H.

  • DavidLavenderDavidLavender GBXamarin Team Xamurai
    edited August 2015

    Hi John,

    I am not aware of anything else that would effect the orientation methods.

    I appreciate your point about using Test Cloud for debugging purposes. I have done all i can via the forums. At this point i can only suggest you contact support via e-mail which is part of the business license.

    Cheers,
    David

  • JohnHardmanJohnHardman GBUniversity mod

    @DavidLavender - wish me luck in that case. Even with a business license, the support email is really hit and miss. Sometimes I have had good answers (although probably before they got busier). The last time, I got something along the lines of "we don't provide that sort of support". Maybe I got somebody on a bad day, but really made me lose all faith in getting support through that channel, even with a business license. What sort of support he thinks they do provide I really don't know. I had thought briefly about upgrading to an enterprise license to get the one day SLA guarantee, but after that last response from them, figure all that means is that the support desk would try to fob me off a bit quicker :-(

  • Glenn.WilsonGlenn.Wilson USXamarin Team Xamurai

    The behavior of the SetOrientationLandscape and SetOrientationPortrait methods are different between iOS and Android. On iOS the orientation is set for the device but on Android the orientation is set for the current activity. So, if your test code is setting the orientation before the app starts it will work on iOS but not on Android. The call needs to happen after each activity starts.

    Here is a code snippet that switches orientation and sleeps in between to easily observe the changes:

                        [Test]
                        public void AppLaunches ()
                        {
                            app.Screenshot ("First screen.");
                            app.SetOrientationLandscape ();
                            System.Threading.Thread.Sleep (5000);
                            app.Screenshot ("Second screen.");
                            app.SetOrientationPortrait ();
                            System.Threading.Thread.Sleep (5000);
                            app.Screenshot ("Third screen.");
                            app.SetOrientationLandscape ();
                            System.Threading.Thread.Sleep (5000);
                            app.Screenshot ("Fourth screen.");
                        }
    

    Here is the output from that code on TestCloud running on ten different physical devices.

    And here is the entire project with that code on dropbox. It can also be run locally against a simulator or physical device.

    This behavior difference is not currently clear in the API documentation (but should be):
    http://developer.xamarin.com/api/member/Xamarin.UITest.IApp.SetOrientationLandscape()/
    http://developer.xamarin.com/api/member/Xamarin.UITest.IApp.SetOrientationPortrait()/

  • JohnHardmanJohnHardman GBUniversity mod

    @Glenn.Wilson - Thanks Glenn. Unfortunately my system doesn't like the project from DropBox. I'm using VS2013. When I open that project it doesn't even show Android amongst the build configurations. Makes me wonder if where I do my Android testing from VS2013, perhaps you always use Xamarin.Studio? Seems unlikely that would make a difference to handling of orientation, but stranger things have happened...

  • MarkSmith.8123MarkSmith.8123 USXamarin Team, University, XamUProfessors Xamurai

    Two questions @JohnHardman --

    1. What version of Android is running on your devices? I've noticed that on my Nexus 7 with 5.1.1 it refuses to rotate sometimes. Several other people are complaining about this as well and it appears to have started with 5.02. A reboot will sometimes fix this - at least it did for me. Make sure apps are properly rotating when you tilt the device.

    2. Is it a Forms application you are working with? Forms does some tricky things internally which could impact your ability to influence rotation through the programatic API.

    I'd recommend starting with a basic Android app. I built one here which just changes a TextView when you rotate the device, and then setup a UITest to rotate through the API and verify the label. Here's the sample:

    https://dl.dropboxusercontent.com/u/2174873/Xamarin.Samples/TheOrient-UITest.zip

    Try this out and see if it's working on your devices. It works on my Nexus 7 with a local test. If it does work, then we know it's something unique about your app, or something incorrectly setup with your test and hopefully we'll be able to start diagnosing it a little further.

    Mark Smith
    Xamarin University | Curriculum

  • MarkSmith.8123MarkSmith.8123 USXamarin Team, University, XamUProfessors Xamurai

    Just for fun, I added a Forms version of the same project into the ZIP file above -- Android and iOS both work properly with the latest Forms release and Xamarin.UITest 1.0. Try that out as well and report back the results, then we can figure out what's different in your environment.

    PS: I ran it from XS (just because then I didn't need to configure APKs and IPA files), but I did run it on physical devices and simulators just to see if there was a difference.

    Good luck!
    mark

  • JohnHardmanJohnHardman GBUniversity mod

    @MarkSmith.1116 - Hi Mark. I am using the following physical Android/Fire devices:

    Operating System    Idiom   Manufacturer        Model                       O/S Version Screen Size Internal Storage (GB)   RAM (GB)
    Android         Phone   Motorola    Moto E                              4.4.4           4.3"            4                       1
    Android (Fire)      Tablet  Amazon          Kindle Fire HDX (3rd Generation)    Fire OS 4.5.5   7"          16                      2
    Android         Tablet  Asus                TF103c                      4.4.2           10.1"       16                      1
    

    (hope that retains its formatting)

    The app under test is a Xamarin.Forms app.

    I've got a really hectic week this week, but will check the behaviour with your projects as soon as I can. Hopefully tomorrow.

    Many thanks,

    John H.

  • JohnHardmanJohnHardman GBUniversity mod

    @MarkSmith @Glenn.Wilson @DavidLavender - I found the problem after comparing with Mark's project (Mark's changed orientation, mine didn't).

    My Xamarin.Forms app uses the technique that many do to implement a splash screen on Android. I have MainLauncher set to true on one Activity that displays the splash screen, then have MainLauncher set to false on a second Activity that handles all of the Xamarin.Forms startup stuff. It would seem that when using Xamarin.UITest to change the orientation, that whatever it does under the covers, it is probably addressing the wrong Activity.

    Is there any way of getting Xamarin.UITest to use that second Activity, or is this another reason to not implement splash screens on Android?

    Many thanks,

    John H.

  • MarkSmith.8123MarkSmith.8123 USXamarin Team, University, XamUProfessors Xamurai

    Hi @JohnHardman --

    Interesting. Let me see if I can dig a little into the system and figure out if we can workaround it. Calabash (the underlying technology) is all open-source, so in theory we should be able to see how it finds the specific Activity.

    Mark

  • MarkSmith.8123MarkSmith.8123 USXamarin Team, University, XamUProfessors Xamurai

    Looking at the source code here and here, it appears this should work fine - it's getting the current Activity.

    You might already be doing this but, are you waiting long enough to make sure the second (non-main) activity is present on the screen? Maybe try a quick-and-dirty sleep up front, or use a WaitForElement until something you know is on the second screen is present?

  • MarkSmith.8123MarkSmith.8123 USXamarin Team, University, XamUProfessors Xamurai

    Another option you could try is to implement your Splash screen on Android differently. Use a different MainPage as the startup page and then swap it out (by changing the Application.MainPage property) when your app is up. That way, you would have just one Activity..

Sign In or Register to comment.