{"id":477,"date":"2026-11-09T03:12:34","date_gmt":"2026-11-09T03:12:34","guid":{"rendered":"https:\/\/www.sigma-rt.com\/blog\/?post_type=sigma_tc&#038;p=477"},"modified":"2026-11-09T03:12:39","modified_gmt":"2026-11-09T03:12:39","slug":"android-compatibility-testing","status":"publish","type":"sigma_tc","link":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/","title":{"rendered":"Nine test devices, one script"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A team of four, shipping a paid app and a free build, with a support inbox that fills up whenever a mid-range phone gets a firmware update.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The device matrix is usually whatever could be bought over time: one flagship, four mid-range, two cheap, one phone a customer complained about, and one with a screen ratio the designer keeps forgetting exists.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Where the time actually goes<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The flow is simple. Sign in, pick a plan, pay with a test account, restore a purchase. Six days, spread across two weeks, was the norm.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Not six days of testing. Six days of fixing taps.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Absolute coordinates broke on two devices with identical resolutions but different status bar heights. Percentages of screen width survived that and died on tall-screen models. dp worked until a phone shipped with a bumped system font size, wrapping every label to two lines and shifting the button down a row.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each round meant a full re-run of the matrix: edit eleven tap points, reinstall on nine devices, watch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The worse failure was the quiet one. A script tapped forty pixels left of &#8220;Continue&#8221;, hit the background, and the app never left the screen it was on. Every assertion after that measured the wrong page. One build shipped with a broken payment sheet because the report said pass. That is what a flaky test looks like from the inside, except the flakiness came from the device matrix rather than the assertions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The toolchain behind it rarely converged on one answer either. Appium with XPath locators, a uiautomator2 script for the screens Appium couldn&#8217;t reach, and two scrcpy windows side by side for the phones that had to be watched by eye. Three ways to name the same button, none of them portable to the next firmware build.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Address the node<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Total Control exposes UI nodes to scripts. Queries take a resource ID, visible text, class name, content description, or a boolean property, and the device works out the coordinates:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">device.sendAai({query: &#8220;R:.pay_button&amp;&amp;BP:clickable&#8221;, action: &#8220;click&#8221;})<br>device.sendAai({query: &#8220;T:Total&amp;&amp;OX:1&#8221;, action: &#8220;getText&#8221;})<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Resource IDs are the stable option \u2014 they don&#8217;t shift with language, font scale, or panel density. Settings screens often lack them, so text plus an offset gets the value next to a label. That relationship holds on every device in the drawer, which is more than can be said for any hardcoded point.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One gotcha: the template decides which nodes exist for the rest of the query. Narrow it to \/^[0-9]$\/ and then ask for the neighbour with OX:1, and it fails with &#8220;Node not found on offset&#8221; \u2014 the neighbour was never in scope. Use a wider template, or none, and it behaves.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Assertions get simpler too:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">device.sendAai({action: &#8220;getText(+T:Order confirmed)&#8221;})<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Null means it wasn&#8217;t there. lastError() explains why.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Nine devices in one call<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">devices.sendAai({query: &#8220;T:Add to cart&#8221;, action: &#8220;click&#8221;})<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Results come back per device, so a failure names the device and the step. That&#8217;s roughly two hours of squinting at mirrored screens removed per pass.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Object mode handles the exploratory case: perform the flow once on the master device, and the group follows the same nodes. No script needed for a sanity pass on a new firmware build.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">The parts it won&#8217;t do<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u00b7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>Portrait only.<\/strong> The tablet layout is landscape and still manual.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00b7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>WebView content is often invisible.<\/strong> Moving checkout into a WebView made the nodes vanish. Same for custom-drawn UI. Mostly-native apps are fine; mostly-web wrappers should be checked in UI Explorer first.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00b7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>Only one entry point at a time.<\/strong> Running a script, browsing nodes, driving the group by hand and calling the REST API can&#8217;t happen together. They queue.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00b7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>Five second default timeout<\/strong>, except for sleep, openApp and scrollIntoView.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s also not a test framework: no case management, no reports, no retries. Results get collected separately through the REST API (Appium-shaped JSON, {&#8220;cmd&#8221;:&#8221;action&#8221;,&#8221;action&#8221;:&#8221;findnode&#8221;,&#8221;params&#8221;:{&#8230;}}, status:0 on success). For four people that&#8217;s acceptable. A QA department expecting a dashboard would find a hole.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">When it isn&#8217;t worth it<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Three devices, two releases a year: coordinates are fine. The cost of this only shows up once the matrix gets wide.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Weekly releases across a dozen configurations, with the same person re-mapping taps at 11pm: it pays back inside one cycle.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start where the free edition stops: two devices, the flagship and the cheapest phone in the drawer, same script, no edits. If both come back clean, the other seven are a formality.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A team of four, shipping a paid app and a free build, with a support inbox that fills up whenever a mid-range phone gets a firmware update. The device matrix is usually whatever could be bought over time: one flagship, four mid-range, two cheap, one phone a customer complained about, and one with a screen [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":478,"template":"","sigma_tc_category":[],"class_list":["post-477","sigma_tc","type-sigma_tc","status-publish","has-post-thumbnail","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Android Compatibility Testing on 9 Devices, One Script<\/title>\n<meta name=\"description\" content=\"Nine devices, six days fixing taps instead of testing. What android compatibility testing looks like when scripts address UI nodes, not coordinates.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Android Compatibility Testing on 9 Devices, One Script\" \/>\n<meta property=\"og:description\" content=\"Nine devices, six days fixing taps instead of testing. What android compatibility testing looks like when scripts address UI nodes, not coordinates.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/\" \/>\n<meta property=\"og:site_name\" content=\"Sigma-rt\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-09T03:12:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.sigma-rt.com\/blog\/wp-content\/uploads\/2026\/11\/overseas-02.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1500\" \/>\n\t<meta property=\"og:image:height\" content=\"844\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/\",\"url\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/\",\"name\":\"Android Compatibility Testing on 9 Devices, One Script\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/overseas-02.jpg\",\"datePublished\":\"2026-11-09T03:12:34+00:00\",\"dateModified\":\"2026-11-09T03:12:39+00:00\",\"description\":\"Nine devices, six days fixing taps instead of testing. What android compatibility testing looks like when scripts address UI nodes, not coordinates.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/overseas-02.jpg\",\"contentUrl\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/overseas-02.jpg\",\"width\":1500,\"height\":844},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/android-compatibility-testing\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"TC \u6587\u7ae0\",\"item\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/en\\\/tc\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Nine test devices, one script\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/\",\"name\":\"Sigma-rt\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/#organization\",\"name\":\"Sigma-rt\",\"url\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/w-logo-gray.png\",\"contentUrl\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/w-logo-gray.png\",\"width\":80,\"height\":80,\"caption\":\"Sigma-rt\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sigma-rt.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Android Compatibility Testing on 9 Devices, One Script","description":"Nine devices, six days fixing taps instead of testing. What android compatibility testing looks like when scripts address UI nodes, not coordinates.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/","og_locale":"en_US","og_type":"article","og_title":"Android Compatibility Testing on 9 Devices, One Script","og_description":"Nine devices, six days fixing taps instead of testing. What android compatibility testing looks like when scripts address UI nodes, not coordinates.","og_url":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/","og_site_name":"Sigma-rt","article_modified_time":"2026-11-09T03:12:39+00:00","og_image":[{"width":1500,"height":844,"url":"https:\/\/www.sigma-rt.com\/blog\/wp-content\/uploads\/2026\/11\/overseas-02.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/","url":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/","name":"Android Compatibility Testing on 9 Devices, One Script","isPartOf":{"@id":"https:\/\/www.sigma-rt.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/#primaryimage"},"image":{"@id":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/#primaryimage"},"thumbnailUrl":"https:\/\/www.sigma-rt.com\/blog\/wp-content\/uploads\/2026\/11\/overseas-02.jpg","datePublished":"2026-11-09T03:12:34+00:00","dateModified":"2026-11-09T03:12:39+00:00","description":"Nine devices, six days fixing taps instead of testing. What android compatibility testing looks like when scripts address UI nodes, not coordinates.","breadcrumb":{"@id":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/#primaryimage","url":"https:\/\/www.sigma-rt.com\/blog\/wp-content\/uploads\/2026\/11\/overseas-02.jpg","contentUrl":"https:\/\/www.sigma-rt.com\/blog\/wp-content\/uploads\/2026\/11\/overseas-02.jpg","width":1500,"height":844},{"@type":"BreadcrumbList","@id":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/android-compatibility-testing\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sigma-rt.com\/blog\/"},{"@type":"ListItem","position":2,"name":"TC \u6587\u7ae0","item":"https:\/\/www.sigma-rt.com\/blog\/en\/tc\/"},{"@type":"ListItem","position":3,"name":"Nine test devices, one script"}]},{"@type":"WebSite","@id":"https:\/\/www.sigma-rt.com\/blog\/#website","url":"https:\/\/www.sigma-rt.com\/blog\/","name":"Sigma-rt","description":"","publisher":{"@id":"https:\/\/www.sigma-rt.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sigma-rt.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.sigma-rt.com\/blog\/#organization","name":"Sigma-rt","url":"https:\/\/www.sigma-rt.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sigma-rt.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.sigma-rt.com\/blog\/wp-content\/uploads\/2026\/10\/w-logo-gray.png","contentUrl":"https:\/\/www.sigma-rt.com\/blog\/wp-content\/uploads\/2026\/10\/w-logo-gray.png","width":80,"height":80,"caption":"Sigma-rt"},"image":{"@id":"https:\/\/www.sigma-rt.com\/blog\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/sigma_tc\/477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/sigma_tc"}],"about":[{"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/types\/sigma_tc"}],"author":[{"embeddable":true,"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"version-history":[{"count":1,"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/sigma_tc\/477\/revisions"}],"predecessor-version":[{"id":479,"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/sigma_tc\/477\/revisions\/479"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/media\/478"}],"wp:attachment":[{"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/media?parent=477"}],"wp:term":[{"taxonomy":"sigma_tc_category","embeddable":true,"href":"https:\/\/www.sigma-rt.com\/blog\/wp-json\/wp\/v2\/sigma_tc_category?post=477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}