Question: Is It Possible to Save a UI Element Path to a Variable

So at work I have to work with a program that is very restricted and so I have to use the mouse to click everything which drives me crazy. To address it, I’ve been developing a series of scripts that help me navigate the program using keyboard shortcuts. But because of this, I have a ton of UI element paths that look something like this

text field 2 of group 2 of group 2 of group 11 of group 1 of UI element 1 of scroll area 1 of splitter group 1 of window 1

As you can see, these long paths can be very difficult to work with, and I have many handlers that all do something like this (select the field)

tell application "System Events"
	tell process "app name"
		set focused of text field 2 of group 2 of group 2 of group 11 of group 1 of UI element 1 of scroll area 1 of splitter group 1 of window 1 to true
	end tell
end tell

And what I really want to do is to be able to pass the path of the UI element to the handler rather than have to re-write the path every time, so like this

set uiPath to "text field 2 of group 2 of group 2 of group 11 of group 1 of UI element 1 of scroll area 1 of splitter group 1 of window 1"

tell application "System Events"
	tell process "app name"
		set focused of uiPath to true
	end tell
end tell

This doesn’t work, however, because the variable is just a string and not a path to the element

Can't set «class focu» of "text field 1 of UI element 1 of group 2 of toolbar 1 of window 1" to true.

I’ve literally tried coercing the string to every type of class and no luck, is this possible at some level?

Model: MacBook Pro
AppleScript: 2.9
Browser: Safari 603.1.30
Operating System: Mac OS X (10.10)

Hi. Welcome to MacScripter.

Basically, the answer’s no. Strings and references aren’t interchangeable. But there are one or two things you can do.

You can store the reference itself as a value .

tell application "System Events" to set uiPath to a reference to text field 2 of group 2 of group 2 of group 11 of group 1 of UI element 1 of scroll area 1 of splitter group 1 of window 1 of process "app name"

Here, the relevant part is ‘a reference to’. The value is then understood to be the reference ‘text field 2 of group 2 of group 2 of group 11 of group 1 of UI element 1 of scroll area 1 of splitter group 1 of window 1 of process “app name” of application “System Events”’ rather than the text field itself. In most cases, it can be used in the same situations where you’d use a variable set to the text field.

You can often break up references in the script by nesting their parts. This can save having to write them out in full every time:

tell application "System Events"
	tell process "app name"
		tell UI element 1 of scroll area 1 of splitter group 1 of window 1
			tell group 2 of group 2 of group 11 of group 1
				set value of text field 1 to "rhubarb"
				set focused of text field 2 to true
			end tell
			tell group 7 of group 2
				-- etc.
			end tell
		end tell
	end tell
end tell

Contrary to what I said above, it’s possible use text representations of references, but it can be just as fiddly to write the code to accommodate them as to write out or paste in the references you’re trying to avoid. Here, the text is compiled and run “on the fly” (by a command in the StandardAdditions), which isn’t as fast as running the precompiled code and the script in the text has no knowledge of anything in the main script:

set uiPath to "text field 2 of group 2 of group 2 of group 11 of group 1 of UI element 1 of scroll area 1 of splitter group 1 of window 1"

run script "tell application \"System Events\"
	tell process \"app name\"
		set focused of " & uiPath & " to true
	end
end"