{"id":37598,"date":"2018-07-30T15:07:52","date_gmt":"2018-07-30T19:07:52","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=37598"},"modified":"2019-03-25T14:24:07","modified_gmt":"2019-03-25T22:24:07","slug":"visual-ui-tests-ios-simulator-using-xamarin-appium","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/visual-ui-tests-ios-simulator-using-xamarin-appium\/","title":{"rendered":"Guest Post: Visual UI tests on iOS simulator using Xamarin and Appium"},"content":{"rendered":"<p>\t\t\t\t<em>This is a guest post from Sophie Tagar, a customer support engineer at <a href=\"https:\/\/applitools.com\/\">Applitools<\/a>. Previously, Sophie was a software developer at Matrix Israel where, among other things, she did full stack development using JavaScript and .NET. She is a veteran of the Israeli air force but unfortunately, they only let her touch Oracle ERP and not an F-35 joystick. In her spare time, she enjoys basketball &#8212; both playing (shooting guard) and watching (go Dubs!).<\/em><\/p>\n<h2>Visual UI Tests using Xamarin and Appium<\/h2>\n<p>In this tutorial, you will learn how to integrate automated visual user interface tests into a development toolchain that includes <a href=\"https:\/\/gist.github.com\/shawnbot\/5527355\">Xcode iOS simulator<\/a> using <a href=\"https:\/\/visualstudio.microsoft.com\/xamarin\/\">Xamarin<\/a>, <a href=\"http:\/\/appium.io\/\">Appium<\/a>, Applitools, and MacOS (formerly OSX).<\/p>\n<p>We\u2019ll cover the following:<\/p>\n<ol>\n<li>A brief introduction to Visual UI Testing<\/li>\n<li>Preparing your test automation environment<\/li>\n<li>Writing your test script<\/li>\n<li>Running your first mobile visual UI test<\/li>\n<\/ol>\n<h2>What is Visual User Interface Testing<\/h2>\n<p>If you\u2019re not yet familiar with automated visual UI testing, more broadly called <a href=\"https:\/\/applitools.com\/downloads\/The_Rise_of_AVM_Applitools_June_18_2018.pdf\">Application Visual Management<\/a> (or AVM for short).<\/p>\n<p>Look at this example of a <a href=\"https:\/\/applitools.com\/helloworld?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=mobile-ui-tests-ios-xamarin-appium-macos\">Hello World application<\/a> available on the Applitool\u2019s website:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37634\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image19-17.png\" alt=\"\" width=\"351\" height=\"700\" \/><\/p>\n<p>How would you test this application? You could verify that a button exists and that the button\u2019s text is \u201cCLICK ME!\u201d. What about the \u201cHELLO WORLD!\u201d title? Again, you can verify the text, but what about the colors? What about the positions of the title element? Of the button? What about the rest of the elements?<\/p>\n<p>Without mobile visual testing, you will need to write a lot of validations (also called assertions or checkpoints), one for every property you want to test (content, position, color, etc.). Even then you cannot be sure the final result is displayed properly to the user.<\/p>\n<h3>Using Visual Testing<\/h3>\n<p>Visual testing solves this problem easily. With a single \u201ccheck\u201d command, you verify <strong>all<\/strong> these properties for the <strong>entire<\/strong> content of the application. So your advantage is double:<\/p>\n<ol>\n<li>You don\u2019t need to write a separate assert statement for each element.<\/li>\n<li>You get full coverage, not just coverage for specific elements.<\/li>\n<\/ol>\n<p>The result of visual testing this application using Applitools are shown below; visual differences are highlighted in magenta:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37635\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image24-19.png\" alt=\"\" width=\"1000\" height=\"524\" \/><\/p>\n<p>And here are the raw results:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37636\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image21-21.png\" alt=\"\" width=\"1000\" height=\"526\" \/><\/p>\n<p>What you see in the images above is an actual fix of a bug in the \u201cHELLO WORLD!\u201d title. The coloring method we used for the \u201cHELLO WORLD!\u201d text did not work for Android 6.0. We identified the bug when we ran visual tests on the demo application, fixed it, then ran our visual tests again to make sure the problem is fixed. This is something we could not have identified any other way.<\/p>\n<p>Tthe screens above are just two examples of Applitools\u2019 <a href=\"https:\/\/applitools.com\/docs\/topics\/overview\/walkthough-example.html?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=visual-testing-w-xamarin-appium-ios-macos?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=mobile-ui-tests-ios-xamarin-appium-macos\">visual tests Results view<\/a>. The <a href=\"https:\/\/www.youtube.com\/watch?v=kQE_HLv4Tcw\">Applitools Test Manager<\/a> includes plenty of other options for analysis and maintenance of visual tests.<\/p>\n<p>Even though we only fixed the title, we didn\u2019t have to add new tests or change existing ones. Since visual tests capture the entire screen, not just what\u2019s in the <a href=\"https:\/\/www.techopedia.com\/definition\/32644\/viewport\">viewport<\/a>, but also content that the user needs to scroll in order to view. We have validated the <strong>entire<\/strong> application when we ran the tests, the exact same tests as we had before when setting up our baselines.<\/p>\n<p>Here\u2019s what the command which validates the entire screens looks like:<\/p>\n<p><code>eyes.checkWindow(\"Hello World screen\");<\/code><\/p>\n<h3>Applying Application Visual Management (AVM)<\/h3>\n<p>What happens when the application has a lot of screens? What about different devices? This is where Application Visual Management (AVM) comes into the picture. Applitools automatically creates baselines for each environment in which your tests run. When viewing multiple tests, <a href=\"http:\/\/support.applitools.com\/customer\/en\/portal\/articles\/2369572-grouping-steps-by-similar-mismatches-?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=visual-testing-w-xamarin-appium-ios-macos\">you can group shared differences<\/a>, making it easy to accept\/reject changes all at once. You can also <a href=\"https:\/\/applitools.com\/blog\/applitools-introduces-the-worlds-first-ui-version-control?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=visual-testing-w-xamarin-appium-ios-macos\">review baseline history<\/a>, perform <a href=\"http:\/\/support.applitools.com\/customer\/en\/portal\/articles\/2466911-cross-environment-testing?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=visual-testing-w-xamarin-appium-ios-macos\">cross-environment tests<\/a> and more. With Applitools, you can continuously and easily manage your visual baselines. You can read more Visual UI Testing and how do it right on the <a href=\"https:\/\/applitools.com\/?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=visual-testing-w-xamarin-appium-ios-macos\">Applitools website<\/a>.<\/p>\n<h2>Prepare Your Test Environment<\/h2>\n<p>Here are the tools you\u2019ll need to run your automated mobile UI tests.<\/p>\n<p><strong>Time:<\/strong> about 45 minutes<\/p>\n<p>Software tools to install on your Mac:<\/p>\n<ul>\n<li><a href=\"https:\/\/brew.sh\/\">Homebrew<\/a><\/li>\n<li><a href=\"http:\/\/appium.io\/\">Appium<\/a> <em>(This article assumes you\u2019re installing via brew and npm.)<\/em><\/li>\n<li><a href=\"https:\/\/visualstudio.microsoft.com\/vs\/mac\/\">Visual Studio for Mac<\/a><\/li>\n<li><a href=\"https:\/\/itunes.apple.com\/us\/app\/xcode\/id497799835?mt=12\">Xcode<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/appium\/appium-xcuitest-driver\">XCUITest<\/a><\/li>\n<\/ul>\n<h3>Create an Applitools Account<\/h3>\n<p>To perform visual UI tests, sign up for an Applitools account on the Applitools website. After you registered with Applitools, you get an API KEY for running visual tests. You can find it on the menu in the top right corner of the <a href=\"https:\/\/eyes.applitools.com\/?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=mobile-ui-tests-ios-xamarin-appium-macos\">Applitools Test Manager<\/a>:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37637\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image12-23.png\" alt=\"\" width=\"1000\" height=\"472\" \/><\/p>\n<h2>Write Your Test Script<\/h2>\n<p>In <strong>Visual Studio for Mac<\/strong>:<\/p>\n<ol>\n<li>Create a new solution: File \u2192 new Solution \u2192 iOS \u2192 Tests \u2192 Xamarin Test Cloud \u2192 UI Test App:<\/li>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37638\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image11-25.png\" alt=\"\" width=\"1000\" height=\"725\" \/><\/p>\n<li>Open the <code>Tests.cs<\/code> file:<\/li>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37639 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image20-27.png\" alt=\"\" width=\"374\" height=\"200\" \/><\/p>\n<li>Add the Eyes package in the following way on the <strong>Solution Explorer<\/strong> &#8211; Right click on <strong>Packages<\/strong> \u2192 click <strong>add packages<\/strong> \u2192 search for <strong>Eyes<\/strong> \u2192 select <strong>Eyes.Selenium<\/strong> \u2192 click <strong>Add Package<\/strong>.<\/li>\n<li>Create a file TestXamarinAppium.cs in the project we just created using the code below. You can also find this C# code sample on <a href=\"https:\/\/github.com\/applitools\/Xamarin_Appium\/blob\/master\/TestXamarinAppium\/Tests.cs\">GitHub<\/a>. This code uses <a href=\"https:\/\/www.seleniumhq.org\/projects\/webdriver\/\">Selenium WebDriver<\/a>, <a href=\"https:\/\/nunit.org\/\">NUnit<\/a> test framework, and the <a href=\"https:\/\/applitools.com\/resources\/tutorial\/appium\/dotnet#step-2?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=mobile-ui-tests-ios-xamarin-appium-macos\">Applitools Eyes .NET SDK<\/a> to drive our automated visual UI tests.<\/li>\n<\/ol>\n<pre><code>\r\n\/\/ dependency required for URI and Exception objects\r\nusing System;\r\n\/\/ dependency required for Eyes object\r\nusing Applitools.Selenium;\r\n\/\/ dependency required for FixedCutProvider object\r\nusing Applitools.Cropping;\r\n\/\/ dependency required for NUnit\r\nusing NUnit.Framework;\r\n\/\/ dependency required for By object\r\nusing OpenQA.Selenium;\r\n\/\/ dependency required for RemoteWebDriver object\r\nusing OpenQA.Selenium.Remote;\r\n\/\/ dependency required for BatchInfo object\r\nusing Applitools;\r\n\r\nnamespace TestXamarinAppium\r\n{\r\n    [TestFixture]\r\n    public class Tests\r\n    {\r\n\t\/\/Declaring the Eyes object\r\n        Eyes eyes;\r\n\t\/\/Declaring the RemoteWebDriver object\r\n        RemoteWebDriver driver;\r\n\t\/\/Creating a BatchInfo object to group all the tests together under the same batch\r\n        BatchInfo mybatch = new BatchInfo(\"Xamarin\");\r\n\/\/Using the same test name to create a bug in the TestWithDiff method (normally                              \/\/different tests will be given different test name)\r\n        string TestName = \"Test_Appium\";\r\n\/\/Declaring the DesiredCapabilities object\r\nDesiredCapabilities dc;\r\n\r\n[TestFixtureSetUp]\r\npublic void BeforeAllTests()\r\n{\r\n\r\n   \/\/ Initialize the eyes SDK and set your private API key.\r\n   eyes = new Eyes();\r\n   eyes.ApiKey = Environment.GetEnvironmentVariable(\"APPLITOOLS_API_KEY\");\r\n\r\n   \/\/Hides the scroll bar\r\n   eyes.HideScrollbars = true;\r\n   \/\/Take fullpage screenshot\r\n   eyes.ForceFullPageScreenshot = true;\r\n   \/\/when taking a full page screenshot use css stitching to handle fixed positoin\r\n  \/\/elements like headers\/floating bars\r\n\r\n  eyes.StitchMode = StitchModes.CSS;\r\n\r\n \/\/Create a batch to group all the tests together\r\n eyes.Batch = mybatch;\r\n\r\n\/\/using OpenQA.Selenium.Remote\r\n\/\/Setup appium - Ensure the capabilities meets your environment.\r\ndc = new DesiredCapabilities();\r\ndc.SetCapability(\"platformName\", \"iOS\");\r\ndc.SetCapability(\"platformVersion\", \"11.2\");\r\ndc.SetCapability(\"browserName\", \"safari\");\r\ndc.SetCapability(\"deviceName\", \"iPhone 7\");\r\n\r\n     }\r\n\r\n     [SetUp]\r\n     public void BeforeEachTest()\r\n     {\r\n            try\r\n            {\r\n                \/\/creating the driver with the appium server url\r\n                driver = new RemoteWebDriver(new Uri(\"http:\/\/127.0.0.1:4723\/wd\/hub\"), dc);\r\n\r\n            }\r\n            catch(Exception e)\r\n            {\r\n                Console.WriteLine(e.Message);\r\n            }\r\n\r\n        }\r\n\r\n        [TearDown]\r\n        public void Cleanup()\r\n        {\r\n            \/\/ End the test.\r\n            driver.Quit();\r\n            eyes.Close();\r\n           \r\n        }\r\n\r\n\r\n        [Test]\r\n        public void RunTest()\r\n        {\r\n                \/\/ Start the test\r\n                eyes.Open(driver, \"Xamarin\", TestName);\r\n\r\n                \/\/ Navigate the browser to the \"hello world!\" website.\r\n                driver.Url = \"https:\/\/applitools.com\/helloworld\";\r\n\r\n                \/\/ Visual checkpoint #1\r\n                eyes.Check(\"Hello!\", Applitools.Selenium.Target.Window());\r\n\r\n                \/\/ Click the \"Click me!\" button.\r\n                driver.FindElement(By.TagName(\"button\")).Click();\r\n\r\n                \/\/ Visual checkpoint #2\r\n                eyes.Check(\"Click!\", Applitools.Selenium.Target.Window());\r\n            \r\n            }\r\n        }\r\n\r\n        [Test]\r\n        public void TestWithDiff()\r\n        {\r\n\r\n                \/\/ Start the test\r\n                eyes.Open(driver, \"Xamarin\", TestName);\r\n\r\n                \/\/ Navigate the browser to the \"hello world!\" web-site.\r\n                driver.Url = \"https:\/\/applitools.com\/helloworld\";\r\n\r\n                \/\/Generate diffs\r\n                driver.FindElement(By.CssSelector(\"body &gt; div &gt; div:nth-child(2) &gt; p:nth-child(3) &gt; a\")).Click();\r\n\r\n                \/\/ Visual checkpoint #1\r\n                eyes.Check(\"Hello!\", Applitools.Selenium.Target.Window());\r\n\r\n                \/\/ Click the \"Click me!\" button.\r\n                driver.FindElement(By.TagName(\"button\")).Click();\r\n\r\n                \/\/ Visual checkpoint #2\r\n                eyes.Check(\"Click!\", Applitools.Selenium.Target.Window());\r\n           \r\n       }\r\n\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h2>Run Your First Visual UI Test<\/h2>\n<p>In <strong>MacOS Terminal<\/strong>:<\/p>\n<ol>\n<li>After you have installed Appium using brew and npm, start Appium by typing &#8220;<strong>appium<\/strong>&#8221; into the Terminal.<\/li>\n<li>Run the project by clicking on the play button:<\/li>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37640\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image9-29.png\" alt=\"\" width=\"600\" height=\"91\" \/><\/p>\n<li>The Xcode iOS simulator should run and navigate to the URL in the script.<\/li>\n<li>To terminate appium, hit <strong>ctrl-c<\/strong>.<\/li>\n<\/ol>\n<p><em>Troubleshooting tip:<\/em>\nIf you get an error in your MacOS Terminal:<\/p>\n<pre><code>\u201c-bash: appium: command not found\u201d:<\/code><\/pre>\n<p>By default, appium is installed in the path (\/usr\/local\/bin) when using Homebrew. Ensure that \/usr\/local\/bin is in your $PATH. <a href=\"https:\/\/coolestguidesontheplanet.com\/add-shell-path-osx\/\">Here\u2019s more on how to do that<\/a>.<\/p>\n<h3>Review Your Test Results<\/h3>\n<p>In <strong>the browser<\/strong>:<\/p>\n<p>Go to <a href=\"https:\/\/eyes.applitools.com\">https:\/\/eyes.applitools.com<\/a> to see the results. At this point, you should be all set for visual testing using an iOS app simulator using Xamarin and Appium on MacOS.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37641\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image22-31.png\" alt=\"\" width=\"1000\" height=\"551\" \/><\/p>\n<p><em>Troubleshooting tips:<\/em><\/p>\n<p><strong>Potential Issue #1:<\/strong><\/p>\n<p>If you get the following error in Visual Studio when running your script:<\/p>\n<pre><code>\u201cCould not resolve type with token...\u201d.<\/code><\/pre>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37642\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image13-33.png\" alt=\"\" width=\"600\" height=\"170\" \/><\/p>\n<ol>\n<li>Right-click on <strong>Packages<\/strong><\/li>\n<li><strong>Update<\/strong><\/li>\n<li>Wait for the update to finish<\/li>\n<li>Then a screen with license terms will appear<\/li>\n<li>Click <strong>Accept<\/strong><\/li>\n<li>Wait for the update to finish<\/li>\n<li>Try running the project again.<\/li>\n<\/ol>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37643\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image8-35.png\" alt=\"\" width=\"600\" height=\"266\" \/><\/p>\n<p><strong>Potential Issue #2:<\/strong>\nIf you get the following error in Visual Studio when running your script:<\/p>\n<pre><code>ERROR: NUnit.Core.UnsupportedFrameworkException: Skipped loading assembly because it references an unsupported version of the nunit.framework, 3.10.1.0<\/code><\/pre>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37644\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image23-37.png\" alt=\"\" width=\"1000\" height=\"419\" \/><\/p>\n<ol>\n<li>Right-click on <strong>Packages<\/strong> in the Xamarin project<\/li>\n<li>Search for <strong>NUnit<\/strong><\/li>\n<li>Downgrade to NUnit version <strong>3.10.0<\/strong><\/li>\n<li>Run again.<\/li>\n<\/ol>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-37645\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/image18-39.png\" alt=\"\" width=\"1000\" height=\"871\" \/><\/p>\n<h2>Wrapping up<\/h2>\n<p>At this point, you should have everything you need to support visual UI testing on <a href=\"https:\/\/gist.github.com\/shawnbot\/5527355\"> using <\/a><a href=\"https:\/\/visualstudio.microsoft.com\/xamarin\/\">Xamarin<\/a><a href=\"https:\/\/gist.github.com\/shawnbot\/5527355\">, <\/a><a href=\"http:\/\/appium.io\/\">Appium<\/a><a href=\"https:\/\/gist.github.com\/shawnbot\/5527355\">, <\/a><a href=\"https:\/\/applitools.com\/?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=mobile-ui-tests-ios-xamarin-appium-macos\">Applitools<\/a><a href=\"https:\/\/gist.github.com\/shawnbot\/5527355\">, and MacOS in your automated testing lab, test cloud, or device farm. To learn more:<\/a><\/p>\n<ul>\n<li><a href=\"https:\/\/applitools.com\/request-demo\/?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=mobile-ui-tests-ios-xamarin-appium-macos\">Contact Applitools<\/a> for a demonstration of Visual Testing for your own apps.<\/li>\n<li>Dive into <a href=\"https:\/\/applitools.com\/docs\/?utm_source=microsoft&amp;utm_medium=blog&amp;utm_content=mobile-ui-tests-ios-xamarin-appium-macos\">Applitools documentation<\/a>.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you will learn how to integrate automated visual user interface tests into a development toolchain that includes Xcode iOS simulator using Xamarin, Appium, Applitools, and macOS.<\/p>\n","protected":false},"author":578,"featured_media":40982,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2,556],"tags":[414,4],"class_list":["post-37598","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","category-integrations","tag-testing","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>In this tutorial, you will learn how to integrate automated visual user interface tests into a development toolchain that includes Xcode iOS simulator using Xamarin, Appium, Applitools, and macOS.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/37598","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/578"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=37598"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/37598\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/40982"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=37598"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=37598"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=37598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}