Set a Platform Specific Label Font Size in Xamarin Forms

Here’s a quick post for anyone interested.  I had a hard time figuring out just how to set different font sizes for one or more labels depending on the platform.  Here’s how:

Create a resource dictionary for your page.  It could be at the app level too.

Assign the style to your label

Cheers!

Automated UI Testing with Azure DevOps and Selenium

If you’ve never done automated UI testing of your web apps, you’re in for a real treat!  You can visit your pages, click buttons, verify results, take  image snapshots, all automatically through code.  Your code actually controls a web browser that interacts with your site.  I’ve recently rediscovered its benefits and am vowing to up my UI testing game.  Why?  Better code through testing.  I’m not necessarily all in on Test Driven Development, but I’m after a certain set of results.  I want my tests to eventually do my thinking for me.   I can’t possibly remember all the little things I want to validate in every web app I write (many of them).  All the business logic, widgets, rules,  and customized niche stuff.  Best of all, its super easy in your ASP.NET MVC apps using MS Test and Selenium Webdriver.   This post will walk you through setting up your test code in your web solution, then executing that test as part of a build definition in Azure DevOps (formerly Visual Studio Online/ Visual Studio Team Services).  This last part, executing the tests in the cloud, is the best part.   Its hands free, automatic, all web based.  The results are easy to track for someone who can be a little disorganized at times.  I have a complete history of each test execution stored online all in the same place I live anyway, in Azure DevOps.

Get Started Writing Your UI Tests

UI testing is a vast universe of many wonders of which I’m not going to cover for this post.  You will see the most basic of unit tests here.   First, in Visual Studio, add a new project to your web app solution.  In the left menu, select .Net Core if you’re building a .Net Core web app, select Test if you’re building for .Net Framework.  In the middle pane, select the Unit Test Project option.  You’re unit test project will be added.

In your unit test project, add the Selenium Web Driver, and Selenium Web Driver Chrome Driver (or Firefox) Nuget packages.  The Selenium main package is responsible for core UI testing while the browser driver packages interface with the browser of your choice.

Your first test class is added automatically to the project.   The test class itself is decorated with the TestClass attribute.  You also get an automatically created test method decorated with the TestMethod attribute.  Both are required to trigger the MSTest framework.  Some other handy attributes you can use will help you set up and tear down your tests.  These are the TestInitialize and TestCleanup attributes respectively.  Methods decorated with the TestInitialize attribute run before any tests are executed, whereas methods decorated with the TestCleanup attribute run after all tests are executed.

Initialize Selenium Webdriver with your app URL in your TestInitialize method, and dispose of it in your TestCleanup method, as shown below. You’ll need a class level variable of type IWebDriver named driver.  Super important: when running these UI tests in Azure DevOps you have to init the driver with Environment.GetEnvironmentVariable(“ChromeWebDriver”) so the hosted agent can load it.

The Login method instructs the web driver how to log into my web app. I simply reference the html elements by id and tell it what values to enter.

After your init method, all the test methods labeled with the TestMethod attribute will be run and tracked individually in Azure DevOps.  My test method simply shows how to navigate to a URL and take a snapshot.   This one of the coolest features.  I can look back in my test history to see when a page broke.   The snapshots are saved to the cloud under each test result.

I recommend running the tests locally first (remove the environment variable parameter passed to the Chrome Driver constructor). Which brings us to our next part.

Run Your Tests in the Cloud

To get started, you’ll need a build pipeline or a build and deployment pipeline, depending on how you want to configure things.  Most times I just have a build pipeline that also releases to at least staging.  Creating one is beyond the scope of this article.  Add a test assemblies step to your pipeline after whatever step deploys your site.  Its under the tests tab in the add step pane.

When added, the step looks like this.

The great thing about it is that the step is configured correctly with the defaults.  Make sure the upload test attachments option is checked, and that the select tests using step has test assemblies selected.

View Your Results

Run your pipeline.  Your tests will run.  The hosted Crome webdrdiver will go out and test your URL (if its publicly accessible).  There are two places to view your test results.  The first place is the test summary result, under the main left hand side menu :  Pipelines > Builds > click a build result > click the tests tab.  You’ll get a summary view like below.

The next is under the left hand side menu > Test Plans >  the sub menu Test Runs > click a test run.  You’ll get a run summary and a test results tab.  Under the test results tab is where you can view your screenshots.  Under the test results tab, you’ll have to double click a test result to view the details.

Hopefully now you’re off and running building your own UI tests.  Enjoy!

Calling the Visual Studio App Center API from Postman

Visual Studio App Center has a great API exposing most if not all of its functionality.  This is useful for a ton of reasons, whether you want to integrate its app management functionality into your workflow in a custom way, or as in my case, use it to access analytics and display custom dashboards.  You can of course export App Center Analytics data to blob storage or App Insights.  For my purposes, I only needed access to a few aspects of data and also a more fine grained control, so chose to just call the API.  The API is documented using Open API here.   This post will take you through getting all of the API endpoints imported into Postman and even generate code to start calling them. The tooling has certainly come a long way since building API clients by hand!

Get the API Swagger

In order to get the App Center raw Swagger, head on over to https://openapi.appcenter.ms.  Here you can view the interactive, nicely formatted UI where you can easily navigate and even issue test calls.  To get the actual raw swagger from this page, I had to view the page source, upon which I discovered a JavaScript function called on page load to go fetch it.  The URL looks to be https://api.appcenter.ms/preview/swagger.json.

Import the Swagger into Postman

You can import Swagger into Postman by clicking the Import button at the top of the app. From here you choose the source of the Swagger via file, folder, link or raw text. This is how I discovered that simply pasting the App Center Swagger URL did not work, so I posted the raw json from the link above and it created a new collection containing all of the endpoints. Most of the endpoints do not have a general description so they end up having no title in Postman, making it difficult to tell one from another. The good thing is you can add your own title to your favorite endpoints and save them in the collection.

Make your first call

To authenticate your call to the API from Postman, you need to obtain a token and (I had to dig around online for this one) add a key named X-API-Token to the header of the call with a value of the token you obtained from App Center.  Postman has a neat feature where you can store preset headers and add them to your calls, so I stored the token header as a preset so I can easily add them to new calls.

Generate client code

Now that you’re authenticated you can have Postman generate sample code for each endpoint. In my case I used the RestSharp code gen feature. To do that, click the code link (shown in the image above) while you’re in edit mode of a call and select your language. That’s it, you’re off and running!

Log Events and Crashes in Xamarin Forms with App Center

While there are a number of third party mobile telemetry and logging solutions on the market, Its no secret that I’m partial to the Microsoft platform.  As such, in this post I’ll show you an easy way to enable and send log messages in your Xamarin Forms apps using App Center

Get Set Up

To get started, you’ll need to install the App Center SDK.  This is the shortened version of the documentation in that link.

There are three main NuGet packages offered.  The main App Center package, an Analytics package and a crashes package.  Install them from the Visual Studio NuGet package manger.  If you prefer the package manager console, you’ll want to use the commands

Install-Package Microsoft.AppCenter.Analytics
Install-Package Microsoft.AppCenter.Crashes

The crashes and analytics packages depend on the main App Center package so it will install automatically with them.   You’ll need to install the packages in each project.  To start logging, you need to opt in to any of the modules you want to use.  In Xamarin Forms, call the AppCenter.Start method in your App.Xaml.cs file.  The call looks as shown below, and takes a string argument of app secrets as well as parameters for each module you want to enable.  App secrets are obtained by creating a separate App Center app for each platform you’re using.  So if you have an Android App and an iOS app, you’ll need to create an App Center Android app as well as an iOS app, and get a secret for each.  The method allows you to pass one to three secrets and enable one or both modules, like so

Replace the curly braces and ‘Your App Secret’ with your actual app secret.

Start Logging

Now that you’re all configured you can start calling the crashes module in your catch blocks, or anywhere you want to report a non optimal situation, and call the events module for any event you want to report.   Calls to the crash and event modules are shown below.  Pass an exception object to the crashes call, and a string argument to the event call.  They each also take a Dictionary<string, string> argument where you can pass up to 20 custom properties and values.   There are other limitations, such as 200 distinct event names, a maximum limit of 256 characters per event name and 125 characters per event property name and event property value.


View your Logs in App Center

Call these and the SDK will send the data up to App Center where you will see it in the portal.  In the portal you get session count and device properties like model and OS version for free, meaning no extra code required.  The portal displays your data in aggregate and also gives you some nice charts.  Here’s a couple of images of the events main page and a detail view of one of the events.

You can see from the images above I’m logging some things that I care about in this sample field technician app. Namely: A user logs in, a user creates a ticket, and so forth. In the second image, you can see the drilled in view and details which include the number of users, and if you scrolled down, values of the custom properties I sent.

With App Center, you can even export this data to Azure Blob Storage or Application Insights to gain further insights. Another cool feature is the ability to see log data in real time as it is sent to App Center. Simply navigate to the Analytics > Log Flow menu item in your App Center app, use your app in a way that invokes anywhere in your code where you have wired up an SDK call and BAM, you’ll see the raw data come in. How cool is that? I can’t wait to see what else they might come out with.

Using Azure Maps with a Xamarin Forms app Part 3 – Route Directions

This is the third in a three part series where I build a Xamarin Forms app that uses the Azure Maps service. You can check out the other parts here:

Part 1 – Basic text search
Part 2 – Search by Category
Part 3 – This post.  Routing

In this post I’ll show you how I was able to query the Azure Maps Route Directions Endpoint and render the route on a map.  The route directions API endpoint takes a number of parameters, of which I only use a few.  Mainly, the source location lat and long, and the destination location lat and long.  The URI I construct ends up looking like this

For this demo, I let the user choose from a few hard coded source and destination locations.  For each preconfigured source and destination, I looked up the latitude and longitude, and stored them with the option.  When the user selects from one of the source and destination pairs, I pass the associated latitude/longitude coordinates to the API.  This is just a demo, so a real solution could be more dynamic by allowing the user to query for directions based on points of interest also returned by the API.  For this post, I’m returning the route for Stanford University to Pizzeria Delfina in Palo Alto, California.  (Palo Alto is the default simulated location for the Android Emulator).  Here’s a screenshot of the view where a user selects from one of the locations.  Its just a few buttons.

Here’s the resulting route drawn as an overlay on the phone’s native map. I was able to draw the polyline overlay using this technique for Xamarin Forms Maps.

Here’s what the code looks like for when the user clicks a button and the view loads to query the API based on the hard coded choice selection and render the map. (pay no attention to the async void lol)

To start I’m using a switch statement based on the user’s selection and passing the hard coded lat long to the API. Notice I’m instantiating the map AFTER I get the results back from the query. This was because of the way the overlay is drawn on to the map for Xamarin Forms. It involves creating a custom renderer which listens to when the map is instantiated. At first, the overlay wasn’t drawing on the map because I was instantiating the map before making the API call, and the listener on the custom renderer was running and rendering the map before the results of the route query were returned. This is one of the rare cases where I personally declare UI in code, to control the declaration timing at run time. After I instantiate the map I place a pin on the starting point no matter which route is chosen. Then I place a pin on the selected destination.

So there you have it. I’ve always been a sucker for POI, mapping etc so I’m excited to be able to explore the mapping API more.