{"id":4159,"date":"2016-10-16T09:56:34","date_gmt":"2016-10-16T09:56:34","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=4159"},"modified":"2016-10-16T10:09:40","modified_gmt":"2016-10-16T10:09:40","slug":"teststack-white-gotchatips","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/teststack-white-gotchatips\/","title":{"rendered":"TestStack.White Gotcha\/Tips"},"content":{"rendered":"<p><strong>RadioButton Click might not actually change anything<\/strong><\/p>\n<p>The click method does not actually click on the radio button itself. It&#8217;s noticeable where a radio button fills some extra space, in some cases the click will not be over the radio button or the text and thus doesn&#8217;t seem to work.<\/p>\n<p>Instead use<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar radioButton = window.Get&lt;RadioButton&gt;(SearchCriteria.ByText(&quot;One&quot;));\r\nradioButton.SetValue(true);\r\n\r\nAssert.IsTrue(radioButton.IsSelected);\r\n<\/pre>\n<p><strong>What type is a UserControl mapped to in TestStack.White?<\/strong><\/p>\n<p>WPF UserControl&#8217;s maps to the TestStack.White frameworks CustomUIItem. Hence<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;UserControl \r\n   x:Class=&quot;MyClass&quot;\r\n   x:Name=&quot;myClass&quot;&gt;\r\n&lt;!-- Other elements --&gt;\r\n&lt;\/UserControl&gt;\r\n<\/pre>\n<p>can be accessed using<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar myClassUserControl =\r\n   window.Get&lt;CustomUIItem&gt;(\r\n      SearchCriteria.ByAutomationId(&quot;myClass&quot;));\r\n<\/pre>\n<p><strong>Defining a custom control mapping<\/strong><\/p>\n<p>When using the generic Get method in TestStack.White, you&#8217;re have the ability to convert the automation control to a TestStack.White Label, Button etc. to give the feel of interacting with such capabilities that are exposed by these types of controls. <\/p>\n<p>In the case of a WPF UserControl we see this maps to a CustomUIItem. It might be useful if we were to define a TestStack.White compatible UserControl for use with the Get method (for example). <\/p>\n<p>Let&#8217;s firstly look at how TestStack.White source code implements a Label (here&#8217;s the source for the Label control)<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class Label : UIItem\r\n{\r\n   protected Label() {}\r\n   public Label(AutomationElement automationElement, \r\n       IActionListener actionListener) : \r\n          base(automationElement, actionListener) {}\r\n\r\n   public virtual string Text\r\n   {\r\n      get { return (string) Property(AutomationElement.NameProperty); }\r\n   }\r\n}\r\n<\/pre>\n<p>Now in our case we need to create a similar class but derived from the CustomUIItem, so here&#8217;s ours<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;ControlTypeMapping(CustomUIItemType.Custom, WindowsFramework.Wpf)]\r\npublic class UserControl : CustomUIItem\r\n{\r\n   public UserControl(\r\n      AutomationElement automationElement, \r\n      ActionListener actionListener)\r\n         : base(automationElement, actionListener)\r\n   {            \r\n   }\r\n\r\n   protected UserControl()\r\n   {            \r\n   }\r\n}\r\n<\/pre>\n<p>According to the <a href=\"http:\/\/teststackwhite.readthedocs.io\/en\/latest\/AdvancedTopics\/CustomUIItems\/\" target=\"_blank\">Custom UI Items<\/a> documentation, an <em>Empty constructor is mandatory with protected or public access modifier<\/em> also required.<\/p>\n<p>The ControlTypeMapping attribute is used to allow TestStack.White to map the return from the Get method to the new UserControl type, for example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar userControl = window.Get&lt;UserControl&gt;(\r\n   SearchCriteria.ByAutomationId(&quot;myClass&quot;));\r\n<\/pre>\n<p><strong>Selecting an item in a ComboBox<\/strong><\/p>\n<p>The code for selecting an item in a ComboBox is fairly simple in TestStack.White, <em>but<\/em> when I used it I kept getting exceptions saying something about virtualization pattern.<\/p>\n<p>Luckily as TestStack.White is built upon the MS Automation framework and others have been here before me, this from <a href=\"http:\/\/stackoverflow.com\/questions\/5814779\/selecting-combobox-item-using-ui-automation\" target=\"_blank\">Stackoverflow<\/a> worked for me, here&#8217;s the code slightly altered to use as an extension method<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static void SelectItem(this ComboBox control, string item)\r\n{\r\n   var listControl = control.AutomationElement;\r\n\r\n   var automationPatternFromElement = \r\n      GetSpecifiedPattern(listControl,\r\n         &quot;ExpandCollapsePatternIdentifiers.Pattern&quot;);\r\n\r\n   var expandCollapsePattern =\r\n      listControl.GetCurrentPattern(automationPatternFromElement) \r\n         as ExpandCollapsePattern;\r\n   \r\n   if(expandCollapsePattern != null)\r\n   {\r\n      expandCollapsePattern.Expand();\r\n      expandCollapsePattern.Collapse();\r\n\r\n      var listItem = listControl.FindFirst(\r\n          TreeScope.Subtree,\r\n          new PropertyCondition(AutomationElement.NameProperty, item));\r\n\r\n      automationPatternFromElement = \r\n         GetSpecifiedPattern(listItem, \r\n            &quot;SelectionItemPatternIdentifiers.Pattern&quot;);\r\n\r\n      var selectionItemPattern =\r\n         listItem.GetCurrentPattern(automationPatternFromElement) \r\n            as SelectionItemPattern;\r\n\r\n      if(selectionItemPattern != null)\r\n      {\r\n         selectionItemPattern.Select();\r\n      }\r\n   }\r\n}\r\n\r\nprivate static AutomationPattern GetSpecifiedPattern(\r\n   AutomationElement element, string patternName)\r\n{\r\n   return element.GetSupportedPatterns()\r\n      .FirstOrDefault(pattern =&gt; \r\n         pattern.ProgrammaticName == patternName);\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>RadioButton Click might not actually change anything The click method does not actually click on the radio button itself. It&#8217;s noticeable where a radio button fills some extra space, in some cases the click will not be over the radio button or the text and thus doesn&#8217;t seem to work. Instead use var radioButton = [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[135,134],"tags":[],"class_list":["post-4159","post","type-post","status-publish","format-standard","hentry","category-teststack-white","category-ui-testing"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4159","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=4159"}],"version-history":[{"count":9,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4159\/revisions"}],"predecessor-version":[{"id":4321,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4159\/revisions\/4321"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=4159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=4159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=4159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}