How to tell AS to click on a certain button

Hello,

I need a script to auto click on the same button everytime to download a file to my desktop, but couldn’t get it to do for me. Can someone please help. This is what I have so far.

tell application "System Events"
	if exists process "Export Window" then
		tell process "Export Window"
			delay 2
			set frontmost to true
			click button "Download"
		end tell
	end if
end tell

Thanks
tdogolf

a button is usually inside a window

so try this :

tell application "System Events"
	if exists process "Export Window" then
		tell process "Export Window"
			tell window 1
				delay 2
				set frontmost to true
				click button "Download"
				-- i always use this line when UI scripting to find the items i need
				get every UI element
			end tell
		end tell
	end if
end tell

Thanks Kim.

I tried your code but I don’t think it even sees the “Export Window” since I put in the error handler to display a dialog.

I then try to just activate “Safari” then click the button, I got this error:

“System Events got an error: NSReceiverEvaluationScriptError: 4”

Do you or any one have any other suggestion?

Thanks again.
tdogolf

make sure ui scripting is turned on

UI is on but I am getting the same error.

I was a bit confused by your original message, tdogolf - but, from your discussion with Kim, it seems you’re trying to access a UI element in a Safari window. Without knowledge about the precise configuration of that window, it would be almost impossible to guess at a workable script. So, if you’d like to supply details of the web page in question, I’m sure someone here could help you more specifically.

In the meantime, all I can do is give you a demonstration of clicking a similar “button”. The following script should initially open up Apple’s home page (http://www.apple.com/), and then auto-click on the tab marked “Mac OS X” (towards the top right-hand side of the page). This should then take you to the Mac OS X page (http://www.apple.com/macosx/):

tell application "Safari" to open location "http://www.apple.com/"
tell application "System Events" to tell UI element 7 of group 1 of ¬
	UI element 1 of scroll area 1 of group -1 of window 1 of process "Safari"
	repeat until exists
		delay 0.2
	end repeat
	click
end tell

Thanks Kai. I am trying to do the same on the webpage (unfortunately I can’t paste the picture in) but I think the “group” is messing me up.

Let say, I want to click on the “Job Opportunities” down below the Apple’s website, how do you tell what group and how do you code this:

UI element 1 of scroll area 1 of group -1 of window 1 of process “Safari”

I really appreciate your help.

Thanks again.
tdogolf

Hi, tdogolf. Sorry about the delayed response.

UI scripting could hardly be described as an exact science. Instead, it usually involves a fair amount of prodding and poking around to define the ‘path’ to a particular UI element. The more complex the UI structure, the more difficult it becomes to hit the target (especially if many of the UI elements are unnamed). However, with a little patience and experimentation - not to mention the aid of a tool like Apple’s Accessibility Inspector* or Prefab UI Browser, it can usually be achieved.

(* If you have Developer Tools installed on Tiger - otherwise try downloading the earlier UIElementInspector)

Let’s take the Job Opportunities link on the Apple website as an example…

By opening up Accessibility Inspector, and positioning the mouse pointer over the link, we should see a UI hierarchy that looks something like this:

Since UI scripting is available only through System Events’ Processes Suite, we already know that we need to start off with a System Events tell statement. We also know that the target application process is “Safari” - and that the target window is named “Apple” (which, if it’s the front window, we could also refer to by index: window 1).

In addition, we can see that the next UI element in the above hierarchy is a group - but how many groups does the window contain?

tell application "System Events"
	tell application process "Safari"
		tell window 1
			count groups
		end tell
	end tell
end tell

--> 3

Right. So we have 3 groups to explore. The above list tells us that the group we want contains a scroll area - so which of these groups match that criterion? Something like this should give us a clue:

tell application "System Events"
	tell application process "Safari"
		tell window 1
			UI elements of groups whose class is scroll area
		end tell
	end tell
end tell

--> {missing value, missing value, scroll area 1 of group 3 of window "Apple" of application process "Safari" of application "System Events"}

That’s lucky. Only the last group, group 3 (or group -1) contains a scroll area, and there’s only one of them - which makes things a little easier.

So far, so good. We’ve now managed to successfully drill about halfway down the UI hierarchy:

Now - the next UI element that we’re checking for is . Since, currently, there is no individual class of web area, we have to use the generic UI element class:

tell application "System Events"
	tell application process "Safari"
		tell window 1 (* or: window "Apple" *)
			tell group -1 (* or: group 3 *)
				tell scroll area 1
					UI elements whose class is UI element
				end tell
			end tell
		end tell
	end tell
end tell

--> {UI element 1 of scroll area 1 of group 3 of window "Apple" of application process "Safari" of application "System Events"}

OK. That narrows things down a little further. Now we need a group - so how many have we to check through?

tell application "System Events"
	tell application process "Safari"
		tell window 1 (* or: window "Apple" *)
			tell group -1 (* or: group 3 *)
				tell scroll area 1
					tell UI element 1 (* web area *)
						count groups
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

--> 16

Whoah, there! Does this mean we have to wade through sixteen entire groups, just to find the link we’re looking for?

Well, that would be one way of doing it - although we could probably use a little filtering trickery here, too. Since we already know that the link is identified by name, rather than merely an index number, we might try something like this:

tell application "System Events"
	tell application process "Safari"
		tell window 1 (* or: window "Apple" *)
			tell group -1 (* or: group 3 *)
				tell scroll area 1
					tell UI element 1 (* web area *)
						UI elements of groups whose name is "Job Opportunities"
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

--> {missing value, missing value, missing value, missing value, missing value, missing value, missing value, missing value, missing value, UI element "Job Opportunities" of group 10 of UI element 1 of scroll area 1 of group 3 of window "Apple" of application process "Safari" of application "System Events", missing value, missing value, missing value, missing value, missing value, missing value}

Strip away all those missing values, and we’re left with both the group index (10) and link name (“Job Opportunities”).

Great - almost done! So now all we need to do is identify the final UI element (described above as ).

… Or do we?

Since the value of attribute “AXRoleDescription” of UI element “Job Opportunities” is “link”, can’t we just click the current UI element?

Let’s see:

tell application "System Events"
	tell application process "Safari"
		tell window 1 (* or: window "Apple" *)
			tell group -1 (* or: group 3 *)
				tell scroll area 1
					tell UI element 1 (* web area *)
						tell group 10
							tell UI element "Job Opportunities"
								actions
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

--> {action "AXPress" of UI element "Job Opportunities" of group 10 of UI element 1 of scroll area 1 of group 3 of window "Apple" of application process "Safari" of application "System Events"}

Yup. Since action “AXPress” means the same as click, that should do it.

“But aren’t there easier ways to extract a particular UI element from a complex UI structure?”, I hear you ask…

Well, yes, there are - given that we have identified certain key features of the target element, and that we know where it occurs in the UI hierarchy. In this case, for example, we know that our target has a class of UI element, is named “Job Opportunities” - and occurs in a UI ‘path’ that looks something like this:

With this information, we should be able to construct a filtering routine that extracts the required target. (This obviously assumes that the url of Safari’s front window is http://www.apple.com/):

to getElement from l
	tell application "System Events" to repeat with i in l
		tell i's class to if it is list then
			if (count i) > 0 then return my (getElement from i)
		else if it is not class then
			return i's contents
		end if
	end repeat
end getElement

tell application "System Events" to my (getElement from first UI element of groups of UI elements of scroll areas of groups of window 1 of application process "Safari" whose name is "Job Opportunities")

--> UI element "Job Opportunities" of group 10 of UI element 1 of scroll area 1 of group 2 of window "Apple" of application process "Safari" of application "System Events"

So, a rather lengthy reply (for which I apologise) to a couple of short questions - but it brings us to what would have been the short answer:

tell application "Safari" to open location "http://www.apple.com/"
tell application "System Events" to tell UI element "Job Opportunities" of group 10 of ¬
	UI element 1 of scroll area 1 of group -1 of window 1 of application process "Safari"
	repeat until exists
		delay 0.2
	end repeat
	click
end tell