{"id":10682,"date":"2015-12-03T10:14:00","date_gmt":"2015-12-03T10:14:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2015\/12\/03\/coded-ui-test-extensibility-v2\/"},"modified":"2022-08-02T08:17:07","modified_gmt":"2022-08-02T16:17:07","slug":"coded-ui-test-extensibility-v2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/coded-ui-test-extensibility-v2\/","title":{"rendered":"Coded UI Test Extensibility V2"},"content":{"rendered":"<p><span style=\"font-family: verdana,geneva\">In VS2013 Update 2 we enhanced the Coded UI Test extensibility model to support plugins built for Windowless controls including controls in Modern Apps. These series of <a href=\"http:\/\/blogs.msdn.com\/b\/gautamg\/archive\/2010\/01\/05\/series-on-coded-ui-test-extensibility.aspx\">blogs<\/a> should give an overview of the extensibility model exposed in Coded UI Test. Also, this <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2012\/05\/24\/coded-ui-test-new-extensibility-qfe.aspx\">blog<\/a> explains a new extensibility QFE that we introduced earlier. In the current blog I will build upon the context from the above two links. These are the major goals that the new extensibility changes target:<\/span><\/p>\n<ol>\n<li><span style=\"font-family: verdana,geneva\">Windowless control support including extensibility for Modern Apps.<\/span><\/li>\n<li><span style=\"font-family: verdana,geneva\">Control Specific Support for only controls that the extension targets.<\/span><\/li>\n<li><span style=\"font-family: verdana,geneva\">Support API\u2019s that are not closely tied to window handles.<\/span><\/li>\n<\/ol>\n<p><span style=\"color: #1c86e2;font-family: arial,helvetica,sans-serif;font-size: large\">Design Changes<\/span><\/p>\n<p><span style=\"font-family: verdana,geneva\">For the above feature set, changes were made in the logic for Coded UI Tests authoring, playback and navigation. These changes involve the engine calling into a new set of API\u2019s detailed below. These changes should be backward compatible and should continue to work for existing plugins since the base extensible points have default implementations for the new API\u2019s to redirect to the existing API set.<\/span><\/p>\n<p><em><span style=\"color: #1c86e2;font-family: arial,helvetica,sans-serif;font-size: small\"><span style=\"line-height: 107%\" lang=\"EN-IN\">Authoring<\/span><\/span><\/em><\/p>\n<p><span style=\"font-family: verdana,geneva\">The Coded UI Test Technology Abstraction Layer (TAL) is now responsible for stitching the query ID of a control based on its corresponding UIA hierarchy. To elaborate on that the TAL would get a controls UIA hierarchy in terms of AutomationElements and then query each of the registered plugins for support for each node in the hierarchy. When a plugin claims support for a node through the GetControlSupportLevel API (surfaced in UITechnologyManagerProxy) it would then be queried again to create a query ID (from the Query Id property surfaced in UITechnologyElementProxy) for the range of nodes it supports. The TAL then would stitch the query ID\u2019s (generated by the plugins) for controls in the hierarchy to obtain a leaf level control\u2019s complete query ID. With this change TAL manages the generation of a complete query ID for an element as opposed to the earlier logic where individual plugins manage the generation of a query ID until it reaches a control in the hierarchy that it does not support. With this change, plugins providing control specific support for an intermediate control in the hierarchy take precedence over plugins providing default support.<\/span><\/p>\n<p><span style=\"font-family: verdana,geneva\">\u00a0The below flowchart summarizes this change. Consider T<sub>x<\/sub> to be technologies and E<sub>xx <\/sub>to be elements in the UIA hierarchy of a control.<\/span><\/p>\n<p><span style=\"font-family: arial,helvetica,sans-serif;font-size: small\"><a href=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/12\/5658.AuthoringFlow.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2015\/12\/5658.AuthoringFlow.png\" alt=\"\" border=\"0\" \/><\/a><\/span><\/p>\n<p><em><span style=\"font-family: arial,helvetica,sans-serif;font-size: small\"><span style=\"color: #1c86e2\">\u00a0Playback\/Navigation<\/span><\/span><\/em><\/p>\n<p><span style=\"font-family: verdana,geneva\">Playback\/Navigation is fairly the same as earlier except where there is a technology switch in the hierarchy in such cases, TAL would communicate across technologies via an AutomationElement which is now the common factor as opposed to a window handle earlier.<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span style=\"color: #1c86e2;font-family: arial,helvetica,sans-serif;font-size: large\"><span style=\"line-height: 107%\">API Set<\/span><\/span><\/p>\n<p><span style=\"font-family: verdana,geneva\"><span style=\"line-height: 107%\"><span style=\"line-height: 107%\" lang=\"EN-IN\">To better support Windowless controls, the following are the set of new API\u2019s that we introduced.<\/span><\/span><\/span><\/p>\n<p><span style=\"font-family: arial,helvetica,sans-serif;font-size: small\"><em><span style=\"color: #1c86e2\"><span style=\"line-height: 107%\"><span style=\"line-height: 107%\" lang=\"EN-IN\">Technology Manager<\/span><\/span><\/span><\/em><\/span><\/p>\n<p><span style=\"font-family: verdana,geneva\">In UITechnologyManagerProxy\/UITechnologyManager we added overrides for methods that were window handle based earlier to now also take AutomationElement:<\/span><\/p>\n<ol>\n<li>\n<p><span style=\"color: #0000ff\">public virtual<\/span> IUITechnologyElement GetElementFromPoint(int pointX, int pointY, AutomationElement ceilingElement)<\/p>\n<p><span style=\"font-family: verdana,geneva\">This method gets called from TAL and expects the plugin to return the element at the given point after creating its query ID. It is a requirement on the plugins to create a Query ID only until the ceiling element is reached. The ceiling element prevents plugins from encroaching into controls in the hierarchy that are better supported by other plugins. This API is called for the leaf nodes in the hierarchy.<\/span><\/p>\n<\/li>\n<li>\n<p><span style=\"color: #0000ff\">public virtual<\/span> IUITechnologyElement GetElementFromAutomationElement(AutomationElement element, AutomationElement ceilingElement)<\/p>\n<p><span style=\"font-family: verdana,geneva\">This method gets called for intermediate elements in the hierarchy Query ID creation here follows the same strategy as earlier, having ceiling element as the limit for creating the query ID.<\/span><\/p>\n<\/li>\n<li>\n<p><span style=\"color: #0000ff\">public virtual<\/span> IUITechnologyElement GetFocusedElement(AutomationElement ceilingElement)<\/p>\n<p><span style=\"font-family: verdana,geneva\">This is needed when recording so that the engine knows which control is being acted upon.<\/p>\n<p><\/span><\/p>\n<\/li>\n<li><span style=\"font-family: verdana,geneva\"><span style=\"color: #0000ff\">public virtual int<\/span> GetControlSupportLevel(AutomationElement element) \n<p>Gets the support level of this technology manager for the control corresponding to the given Automation Element. The framework uses this function to select the right technology manager for the control.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-family: verdana,geneva\"><br \/><span style=\"color: #1c86e2\"><em><span style=\"font-family: arial,helvetica,sans-serif;font-size: small\">Technology Element<\/span><\/em><\/span><\/span><\/p>\n<p><span style=\"font-family: verdana,geneva\">In UITechnologyElementProxy\/UITechnologyElement we added<\/span><\/p>\n<ol>\n<li>\n<p><span style=\"color: #0000ff\">public virtual<\/span> AutomationElement AutomationElement<\/p>\n<p><span style=\"font-family: verdana,geneva\">We use this AutomationElement value when we need to convert between <\/span><span style=\"font-family: verdana,geneva\">technologies during playback.<\/span><\/p>\n<\/li>\n<\/ol>\n<p><span style=\"font-family: verdana,geneva\">In scenarios where a plugin does not implement these list of API\u2019s we have default implementation to redirect to use the existing API functionalities based on window handles. <\/span><\/p>\n<p><span style=\"color: #1c86e2;font-family: arial,helvetica,sans-serif;font-size: large\">Resources<\/span><\/p>\n<ol>\n<li>\n<p><span style=\"font-family: verdana,geneva\">This <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2012\/08\/17\/few-tips-on-implementing-a-coded-ui-test-plugin-extension.aspx\">blog<\/a> helps troubleshoot issues for plugin writers.<\/span><\/p>\n<\/li>\n<li>\n<p><span style=\"font-family: verdana,geneva\">Attached to this blog is a sample extension written for modern apps.<\/span><\/p>\n<\/li>\n<\/ol>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/02\/DatePickerExtension.zip\">DatePickerExtension.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In VS2013 Update 2 we enhanced the Coded UI Test extensibility model to support plugins built for Windowless controls including controls in Modern Apps. These series of blogs should give an overview of the extensibility model exposed in Coded UI Test. Also, this blog explains a new extensibility QFE that we introduced earlier. In the [&hellip;]<\/p>\n","protected":false},"author":79,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-10682","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"acf":[],"blog_post_summary":"<p>In VS2013 Update 2 we enhanced the Coded UI Test extensibility model to support plugins built for Windowless controls including controls in Modern Apps. These series of blogs should give an overview of the extensibility model exposed in Coded UI Test. Also, this blog explains a new extensibility QFE that we introduced earlier. In the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/10682","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/79"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=10682"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/10682\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=10682"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=10682"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=10682"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}