| Win32, MFC, common controls | Character Map, classic dialogs, MFC applications | Full | Test (a #32770 dialog of common controls, the window's menu and the common dialogs, with another window in front; System Information, an MFC application of Windows; charmap; win32-apps.md) | State and actions the tree lacks go through the controls' own windows: radio buttons, trackbar, date picker, SysLink, up-down, the window's menu (read, not shown), its shortcuts, context menus, clicks and double clicks posted to a window behind another. List views are read through their messages (10,000 rows in under a second), and a window beside a big one through the helper's own tree. Owner-drawn items without text are named from the screen. A chord no menu lists is posted with its modifiers held; a list view's item is double- or right-clicked on its text, behind another window too; a control the application paints itself (charmap's grid) is read off the screen, behind another window too, and clicked with its window in front. Hover needs the foreground, and so does focus() where the window is not its thread's active window. RichEdit 2.0/3.0 fields (riched20.dll, as MFC's CRichEditCtrl, older Delphi TRichEdit and VB6 make them) pass the shared contract, Unicode and ANSI; an ANSI one holds only its code page's characters. | — |
| Scintilla editors | Notepad++, SciTE, TortoiseGit and TortoiseSVN commit dialogs, Code::Blocks | Full (the editor) | Test (Notepad++ 8.9.8.1 and SciTE 5.6.7, behind another window) | UI Automation reports the editor as a pane named with its whole text and no pattern: it is a text box whose value is that text, read through its window, filled and typed into through its window in the background (line ends as the Enter key, the application's auto-indent undone). Notepad++'s menu, tabs, status bar and Find dialog are Windows' own; its toolbar buttons have no names. Hosts other than Notepad++ unverified | — |
| Windows Forms | line-of-business applications | Full | Test, on the .NET Framework 4.8 and on .NET 10 (the standard controls and a 5,000-row grid with another window in front; dotnet-apps.md) | Grids are read through the helper's MSAA reader: ~1 s for 500 rows, ~5–8 s for 5,000 (~4.5 s on .NET 10, whose rows not shown have no place and whose row names are slow to ask); the rest of a window beside a big grid through the helper's own tree, ~1–2 s a locator. A ToolStrip check button's state is read through MSAA, a NumericUpDown's arrows step it through its edit, a ContextMenuStrip's item is chosen and a menu strip's shortcut pressed in the background. Third-party suites that paint their controls are covered on Krypton: a field painted around Windows' own control is that control, a painted button or check box is read off its pane's picture and clicked with real input, and the ribbon's tabs and buttons by their painted text; a painted navigator's page header is told chosen by the page read inside it (DevExpress, Telerik and Infragistics themselves unverified). Also: MDI documents as windows inside their container; a MenuStrip's window list once opened; a NotifyIcon's menu through desktop.shell(); a window recreated with a new handle; a PropertyGrid, a MonthCalendar, autocomplete, a SplitContainer and a scrolling panel. On .NET 8+ a CheckOnClick ToolStrip button is a check box, a PropertyGrid's properties are tree items, and FolderBrowserDialog is the file dialog's folder mode (dotnet-apps.md). A DateTimePicker's days are read off the screen, a ToolStripSplitButton's menu opens by a click posted on its arrow (its pattern would run its command), and a shell autocomplete list takes a choice only from the real mouse. | — |
| WPF | line-of-business applications | Full | Test (dotnet-apps.md) | Virtualised lists hold only the rows on screen: a row of a grid in order by the column asked for is reached by setting the grid's scroll position to where it should be (row 7,842 of 10,000 by its Id in about 5 s, selectOption of item 150 of 10,000 in about 5 s); rows in no order by it are paged to a view at a time, the grid looked at alone between pages (a row 150 down, found by two of its cells, in about 23 s); WPF may bring its window forward when paged or focused through UI Automation. In-house controls: labels in another panel, template text (read from the Raw view), tables of plain text, and charts, forms and whole windows that paint their content (tables, input boxes and buttons found in the picture) are handled; real input to what is only painted needs the foreground. A WPF ribbon's tabs, group buttons, toggle and application menu are driven; its RibbonComboBox, a menu bar to UI Automation, is reported as the combo box it is and driven by selectOption. Re-templated WPF controls (Material Design In XAML) keep their automation peers, and a Fluent.Ribbon's tabs, group buttons and combo box report their roles. A WPF form hosted in Windows Forms (ElementHost) and a Windows Forms form hosted in WPF (WindowsFormsHost) read as one tree across the seam | — |
| WinUI 3, Windows App SDK, .NET MAUI | Windows 11 Notepad, Terminal, Paint | Full | Test (an unpackaged application built from downloads; the same application packaged, an MSIX loose layout with an identity registered under Developer Mode and started by its app ID, in the Windows Sandbox guest (experimental) and on a machine with Developer Mode on; the packaged build runs the whole contract as a column of its own, "WinUI 3 (packaged)", activated with the session's arguments, and is activated for its own URI scheme), Manual | A control's context flyout opens behind another window through UI Automation, which brings the window forward to show it; a far item of a virtualised ListView is reached by setting its scroll viewer's position to where the item should be (item 150 of 200 in about 3 s); .NET MAUI reads as WinUI: an application built with the MAUI workload in the downloaded SDK passes the form, the far list item and the modal page | — |
| UWP, hosted by ApplicationFrameHost | Calculator, Settings, Photos | Full | Test (Calculator) | The helper tells which process each frame hosts; keys need the foreground (XAML ignores many posted keys); a minimized window shows nothing until restore(); a suspended app is woken in the background; an app is activated with arguments (the Store Notepad with a file) and for a URI (ms-settings:display), and launch({ uri }) activates the scheme's handler and names its process; in the Windows Sandbox (experimental) the helper runs in the guest, where a packaged application registered there starts by its app ID; the image has no Store apps, so none is driven there | — |
| Java Swing, AWT | text editors, enterprise Java clients | Good | Test (java-apps.md) | Java 8 and 32-bit runtimes (Temurin 8 x86 among them) through their own bridge; in the Windows Sandbox (experimental) only an application that brings its own runtime (a jpackage image) runs, read through the bridge in the guest; custom components show nothing to the bridge, and their text is read off the screen (an editor that paints its own text, verified); a long JList lists only the rows it shows: a locator scoped to it is reached by dragging its scroll bar's thumb with the real mouse to where the item should be (file 150 of 200 in about 3 s), and the wheel pages it otherwise; a JTable is a table by column (its header's labels head its columns), one without a header by the column count its AccessibleTable reports, but is not paged | — |
| JavaFX | DBeaver wizards, JavaFX clients | Good | Test (an application run from source on the machine's JDK with the OpenJFX SDK) | JavaFX implements UI Automation itself (no Access Bridge); fields named by Label.labelFor; the form, tree, far list and modal all pass. A modal shown from a button's handler blocks the Invoke call, as elsewhere; one shown after the handler returns does not | — |
| SWT / Eclipse RCP | Eclipse, DBeaver | Good | Test (an application run from the SWT jar from Maven Central) | Native controls through their MSAA proxies, as Win32; names through SWT's Accessible. Passed every shared-contract scenario | — |
| Qt Widgets | engineering tools | Good | Test (a PySide6 application) | Qt takes a drop-down's choice, a tree item's expansion, a list's scrolling and an item's selection only from real input: SPART-Desk ends with it where nothing in the background took, so these need the window in the foreground; a far list item takes about 30 s with the wheel, as the list shows few rows and Qt exposes neither a scroll pattern that takes a position nor its scroll bar, so nothing sets its position from outside; between pages the list is looked at alone. Fields labelled by buddy labels, and by the text beside them without, are found; custom-painted widgets show nothing. A QTableWidget reports its cells flat under it, with the table's AutomationId: they are grouped into rows by place, and found by column | reading the screen covers painted widgets |
| Qt Quick / QML | modern Qt applications | Good | Test (a PySide6 application) | A combo box opens only for the mouse and reports no value, so selectOption clicks and says nothing confirms the choice; it reports itself collapsed while its list shows, and expand() counts it open by its items. A list reports a highlighted item unselected: only a delegate's Accessible.selected reports it. A ListView keeps the rows it created above and below its view and reports them on screen: SPART-Desk tells its view by where the rows are, pages it with the wheel and pages on toward a row it will not scroll into view (item 150 of 200 in about 28 s, the list looked at alone between pages; it exposes no scroll pattern and no scroll bar, so its position cannot be set). A label named by Accessible.name shows its text only on screen. Controls without Accessible.name are named by the text beside them | — |
| Flutter (Windows) | cross-platform Flutter desktop applications | Good | Test (an application built with the Flutter SDK) | SPART-Desk's helper reads the window's widgets. Flutter reports a drop-down as a button named "label\nvalue", which getByLabel finds by its label and selectOption presses (as does expand()), choosing the item's button its menu shows; an ExpansionTile as a text with no expand state (click it); and a ListView as a named group of buttons stacked in a column that overflows it, which SPART-Desk reads as the list it is and pages with the wheel, the only thing that moves it (item 150 of 200 in about 40 s); text fields refuse UI Automation's value, so fill() clicks and types with real input. hover() and scroll({ wheel }) are the real mouse over a control's middle | — |
| Avalonia | cross-platform .NET | Good | Test (an application built from downloads) | A TreeViewItem reports no name and no expand state: it is named by the caption read inside it, and expand()/collapse() toggle the expander button it holds and read the state from it; its window reports its client area as its bounds, and text read off its picture is placed by its frame; a far item of a virtualised ListBox is reached by setting its scroll viewer's position to where the item should be (item 150 of 200 in about 1 s, in front or behind another window) | — |
| Electron | VS Code, Slack, Discord | Good–Full | Test (an Electron application of SPART-Desk's own, with the shared contract, its editors and a native dialog; electron-apps.md) | A rich-text editor that keeps its own model (Slate, Lexical, ProseMirror: the composers of Slack, Discord, Teams, Notion) is typed into in the background, never given a value its model would not hear, and what its Send posts is checked. A Monaco editor ignores set-value (an empty one is typed into in the background; one holding text needs real input); a page takes chords only as real input; a working window's tree is large (VS Code: 2 000 controls and more); snapshot({ root }) reads only inside its root, while a chained locator reads the whole window; canvases are pixels. An HTML <select>'s option is chosen with real input only; an ARIA tree expands, a far listbox option is found, and a modal window is answered in the background; an HTML table's row is found by its cells, its header cells (reported as cells) heading its columns. Slack unverified. | — |
| React Native for Windows | the Microsoft Store, the Xbox app, Office's and Teams' newer surfaces | Full | Test (an application built from the React Native template with its Fabric C++ app, the "React Native (Windows)" column of the matrix: 66 of 87 cases pass, 19 are declared n/a for what React Native's core lacks or its platform never reports) | Its views are UI Automation elements only with a role, a label and accessible set, and act on UI Automation's patterns only through accessibility actions; no picker, slider, spin box, menu bar, tabs, tree, grid or drag and drop in React Native's core (an application builds them from views); a press hears the left button and the device, no other button, no modifier key, no pen pressure; its native tooltip is outside the tree; a list that virtualises drops its items out of view from the tree; its scroll pattern takes no position, which SPART-Desk sees through and pages with the wheel | — |
| WebView2 hosts | new Outlook, Teams 2, hybrid applications, Blazor Hybrid | Full (the page) | Test (a Windows Forms host, electron-apps.md; a Blazor Hybrid page, a MAUI application's BlazorWebView in WinUI 3's WebView2, found by its address https://0.0.0.1/ and driven through the page's labels; WinUI 3's WebView2 runtime shows the page in a widget window of its own over the host window, which the application's windows include, so a launch names the host's process) | As Electron, rich-text editors included; characters posted in the background do not always arrive (read back, posted again, then typed with real input); Teams and new Outlook unverified (they need a signed-in account) | — |
| IE WebBrowser hosts | Windows Forms, VB6 and Delphi applications that show a page in the WebBrowser control (TWebBrowser), HTML Help | Good | Test (a Windows Forms host of the control, ie-webbrowser-apps.md) | The engine (MSHTML) reports the page through Windows' MSAA proxy: roles, names, values, states, an element's id as its AutomationId; a page in IE7's default document mode reads too. An ARIA tree item named after every line under it is named by its own text; a tab, menu item or tree item without Invoke is clicked, since the engine takes their selection and expansion patterns without telling the page; a table's cells, each reported in a row of its own, are read by row. The host gives a page no pointer events (legacy input mode) and IE11 no spin box and no fieldset group, which the matrix declares. HTML Help, VB6 and Delphi hosts unverified | — |
| Tk (tkinter) | Python tools | Partial | Test (a tkinter/ttk application; its panes read as widgets) | One window handle per widget, each an unnamed pane with no role: what each paints tells its widget (a button, a check box with its state, a combo box with its value and its popup, an input box, a list, a tree with its indicators), named by the label beside or above it, acted on with real input in the foreground. The form, the tree, the modal and the far list item pass: a painted list is paged with the wheel over its picture, leaping toward a numbered item (item 150 of 200 in about 19 s). A selected row reads as text (its highlight is flattened for the reader); expand() presses a painted combo box open and finds its list by the lines read around it; Tk 9.0 still shows UI Automation nothing | — |
| wxWidgets (wxPython) | Audacity, FileZilla, Python tools | Good | Test (a wxPython application) | Native controls through their MSAA proxies, names through a wx.Accessible of the control's own (wx.Window.SetName names it to nothing outside the application); the form, tree, modal and far list item (150 of 200 in about 9 s, through the list box's window) pass | — |
| One toolkit hosted in the other | ElementHost in Windows Forms, WindowsFormsHost in WPF | Full | Test (dotnet-apps.md) | The hosted controls are plain WPF or Windows Forms controls, read as one tree across the host | — |
| CEF applications | Spotify, Steam, enterprise clients | Partial–Good | Test (a CefSharp host of the Electron application's pages) | With force-renderer-accessibility the page reads as Electron's does; without it the first look sees the pane and nothing in it, then Chromium turns accessibility on for the client that asked and the page follows. A launch can pass the switch in args | reading the screen while the page is opaque |
| Delphi VCL, C++Builder | ERP, medical, point of sale | Good | Test (vcl-apps.md), Manual (WinSCP, HeidiSQL) | Labels, speed buttons and grid cells are read off the screen, so clicks on them need the foreground; AutomationIds are window handles; a 32-bit application's windows are read by the 32-bit build of the helper (vcl-apps.md) | — |
| Delphi FireMonkey | cross-platform Delphi | Pixels | Expected | One window handle, no UI Automation | — |
| VB6, ActiveX, PowerBuilder | legacy line-of-business | Partial | Expected | MSAA only; windowless controls, DataWindows and third-party grids are opaque | reading the screen |
| Office | Word, Excel, Outlook | Good (ribbon, dialogs) / Partial (document) | Expected (automation-interfaces.md) | Excel's cells and Word's body are read whole through the application's own automation interface (app.automation); on screen, Word's body is one text | Office itself verified |
| SCADA/EMS operator consoles | utility operator consoles | Partial (the console) | Test (a console of that kind, SPART-Desk's own) | The navigator, tabulars, alarm summary, menus and control dialogs are plain controls; the one-line, banner, trend and dashboard are drawn, so they are read off the screen, clicked with real input in the foreground, and told apart by colour through a picture. A device outside the view is reached through the display's own search. Trend curves and gauge needles are not read | — |
| Games, DirectX, OpenGL, CAD canvases | — | Pixels / Blocked | Test (an application drawing through Direct3D 11 flip and blit swap chains, DirectComposition and OpenGL, read behind another window) | Windows drawn on the graphics card capture as any window; what captures black is display affinity, protected video and a locked session, which no capture lifts, and a snapshot and a screen locator's error say so; anti-cheat drops injected input; a view that turns or pans by relative raw-input deltas (a game engine's camera) hears our moves as absolute positions only, so it does not move (input-engine.md) | — |
| Remote desktop, RemoteApp, Citrix, VM consoles | — | Pixels | Expected | One picture of a remote screen; compression | recognising such windows and reading them first |
| Console and text-mode applications | cmd, PowerShell, CLI tools | Partial | Expected | The buffer reads as one text | — (a terminal testing tool fits better) |
| Elevated applications | Run as administrator, MMC, regedit | Blocked unless the runner is elevated | Test (the credential prompt, the same rule; an application run as administrator by hand) | Windows (UIPI) keeps a process from reading or driving one of a higher integrity level: an action fails at once with elevation_required, and a snapshot notes why it is empty; run the test runner elevated (elevated.md) | — |
| Installers | MSI, WiX Burn, Inno Setup, NSIS, ClickOnce | Good (their dialogs) | Test (an NSIS installer built from the NSIS zip, installing under the profile and uninstalled again; a per-user MSI built with the WiX toolset, walked through Windows Installer's dialogs and removed silently, and a ClickOnce deployment installed through its security dialog, started from its .appref-ms and removed through its maintenance dialog; installers.md) | Their pages are Win32 dialogs of common controls, walked by their buttons; an installer that needs elevation needs an elevated runner (elevated.md); a ClickOnce dialog belongs to the ClickOnce service, named as the target; WiX Burn and Inno Setup unverified | the Windows Sandbox runtime (experimental) |
| Shell surfaces | tray icons, notifications, taskbar | Good | Test (desktop.shell(), in the Windows Sandbox (experimental) too) | Names are in the display language; the flyouts close through their taskbar button (a posted Escape is ignored); a notification's text may read "Private"; another display's taskbar through shell({ display }); an application that lives in the tray until its window is shown is attached by processName and reached through its icon (launch({ target: { processName }, windowTimeout: 0 })) | — |
| File Explorer | folders, the Details view, the Open and Save dialogs' items | Good | Test (a folder the test makes, behind another window) | An item's invoke opens it, so a click selects it and a double click opens it (a folder in the same window), in the background; the Details view reads as a table (table({ root: getByRole("list", { name: "Items View" }) }), each property's value, a folder's Size empty); an item's context menu is asked for through UI Automation (selected first, as a right click selects it), and Explorer brings its window forward to show it; the rename box is named after what it holds, so it is found by its class (UIRenameTextElement). Names show without extensions by default | — |
| Applications of several processes | out-of-process dialogs, updaters | Good | Test (an application of several processes, locally and in the Windows Sandbox (experimental)) | Windows of the processes an application started count only for a launched one; one attached to spans what its windows own | — |
| Windows' own dialogs | credential prompt, print dialog, Open and Save, folder pickers, task dialogs | Good–Partial | Test (credential prompt; Notepad's print dialog; the common dialogs and task dialogs) | The credential prompt is one of the application's windows, but it runs at a higher integrity level, so Windows (UIPI) keeps its fields out of UI Automation and its input out of reach: its text is read off the screen, and acting in it fails with elevation_required unless the test runner runs elevated; app.credentialPrompt() is the prompt Windows ties to the application, never another's (elevated, where the prompt has no owner, through the helper's wait-chain link) (elevated.md); the print dialog is an application of its own (attach({ processName: "PrintDialog" })), readable in full | — |