GUI scripting

Hi all,

I’ve created a script that starts an application and then quits it at a given time. It works properly except for when the script asks the application to quit, the application gives a dialog box saying something like “Are you sure you want to quit?”. How can I get my script to simply click “OK” at that point?

I know this should be a simple GUI script asking System Events to tell process “Application name” keystroke return. For example, if I had TextEdit showing me a message “Do you want to save changes made to document…” and I ran:

 tell application "TextEdit"
	activate
end tell
tell application "System Events"
	tell process "Textedit"
		keystroke return
	end tell
end tell 

I would have expected that script to click the OK button, but it doesn’t do anything. As a matter of fact, I can’t even get the following script to work in an open TextEdit document:

 tell application "TextEdit"
	activate
end tell
tell application "System Events" to keystroke "testing" 

I would have expected that script to enter some text in the open document. Am I missing something here? I’m running Yosemite and I know the process for allowing UI scripting has changed from where it used to be but I’m not getting any error messages either…

Best regards,
David

Hey David,

It’s not good form to activate an app and then GUI-Script it; you inevitably end up with timing issues.

Is the app really activated fully when you insert your keystrokes?

It’s problematic, and you have to test for it.

A more organic method is to do this:


delay 0.1
tell application "System Events"
	tell application process "TextEdit"
		set frontmost to true
		keystroke "testing"
	end tell
end tell

I’ve had to put a delay in to give me time to get my fingers off the keyboard when running from Script Debugger, otherwise the first ‘t’ is interpreted as Cmd-T and brings up the Fonts Dialog in TextEdit.

Generally it’s wise to use a set frontmost to true line in any given UI-Script, because all sorts of things can cause an app to not be properly frontmost.

Thanks Chris, you’re a genius!

What did the trick was “set frontmost to true”. I thought that I was doing that simply by telling TextEdit to activate (it was already running) but apparently this didn’t work. The timing issue also makes a lot of sense so I will factor this in future.

I tested this with keystroke “testing” in TextEdit - it inserted the word in the document. I also prepared TextEdit to pop up a dialog box asking me to save the document and tested the script with “keystroke return”. This successfully pressed the default button on the dialog box.

Much appreciated.
David

Hey David,

By the way.

TextEdit is not a very scriptable application.

For plain-text I advise TextWrangler (freeware) or its commercial big brother BBEdit ” these are amongst the most scriptable apps available for OSX.

There are not any good freeware options for styled-text, but Tex-Edit Plus is inexpensive (and the demo is unlimited in time or function). It’s a Carbon app, so it has certain limitations ” but it is highly scriptable.

The next step up is probably Jedit X, but at $28.00 U.S. it’s not inexpensive.

In an other location, applescript-users@lists.apple.com , Bill Cheeseman posted this neat code

tell application "System Events"
	set frontmost of process "TextEdit" to true
	keystroke "Hello Cruel World!"
end tell

There is no need for the delay whose goal was to let time to the process to become the frontmost one after calling activate.

Yvan KOENIG (VALLAURIS, France) lundi 6 juillet 2015 19:21:48

Hey Yvan,

The delay was to let me get my fingers off the keyboard after hitting Cmd-R in Script Debugger. It was not otherwise necessary.

OK Chris but most of the time it is inserted because when the instruction tell application “System Events” to tell process “TextEdit” is executed after the instruction activate application “TextEdit”, under Yosemite, the process is not at front.
The delay was introduced to allow the process to be at front. It seems neater to no longer rely upon a delay whose required value is unknown and just explicitly push the process at front.

I wrote hundreds of scripts using GUI scripting. Most of the time, in the first draft I insert delay instructions. Then, when everything works as wanted, I remove these instructions one by one to determine which ones are really useful.
Most of the time I am able to drop all of them and doing that, I’m not annoyed when engineers introduce an odd behavior in the function named delay :wink:

Yvan KOENIG (VALLAURIS, France) lundi 6 juillet 2015 21:20:35