I’m currently writing a script to automate running the installation of an application.
Its a simple script, simply clicking the continue or next button.
What i need is a way for applescript to figure out that the continue button or window i’m referring to actually exists before clicking it.
I’m currently using delays but sometimes the window loads longer or faster than expected:
click button “Continue” of sheet 1 of window 1
delay 0.5
click button “Continue” of window 1
delay 0.5
click button “Continue” of window 1
etc…
I’m sure you guys can get the picture.
when using AutoIt for windows, the syntax is WinWaitActive. I hope there’s something for AppleScript.
Hi,
I’m always using this way for an appearing UI element
repeat until exists [unique UI element]
delay 0.2
end repeat
or for disappearing UI element
repeat while exists [unique UI element]
delay 0.2
end repeat
Thanks, now that part worked.
New problem, i tried adding it as a handler so that i can reuse it but it doesnt seem to work. here’s my code:
it returns the error "System Events got an error: Can’t get button “Install” of sheet 1 of window 1 of process “Installer”. (-1728)
on winWaitActive(objectID)
repeat until exists objectID
delay 0.2
end repeat
end winWaitActive
on clicked theObject
tell application "System Events"
tell process "Installer"
my winWaitActive("button \"Continue\" of sheet 1 of window 1")
click button "Continue" of sheet 1 of window 1
end tell
end tell
end if
i also tried this:
winWaitActive(“button "Continue" of sheet 1 of window 1”) of me
help would be very much appreciated.
First of all you must add a System Events tell block in the handler, because the parameter contains System Events terminology. Second of all pass the reference of the UI elements, not a literal string
on winWaitActive(objectID)
tell application "System Events"
repeat until exists objectID
delay 0.2
end repeat
end tell
end winWaitActive
on clicked theObject
tell application "System Events"
tell process "Installer"
set buttonContinue to a reference to button "Continue" of sheet 1 of window 1
my winWaitActive(buttonContinue)
click buttonContinue
end tell
end tell
end clicked
I decided to add the application name and the process name as a variable. How do I do this?
Currently I’m using the code below, which won’t build successfully:
on winWaitActive(theAppName, theProcName, theObjectID)
tell application theAppName
tell process theProcName
repeat until exists theObjectID
delay 0.2
end repeat
click theObjectID
end tell
end tell
end winWaitActive
I also noticed that:
set buttonControl to a reference to button “Continue” of sheet 1 of window 1
causes a build to fail.
Is there another way to declare this? I cannot find any resources on the net about this.
Thanks
tell application [variable]
doesn’t work. The application must be specified by a literal string to be able to resolve the terminology at compile time.
In your case it’s not necessary anyway, because process is a part of System Events
Thanks so much StefanK.
How about the line:
set buttonContinue to a reference to button "Continue" of sheet 1 of window 1
Is it the correct syntax? It causes the build to fail.
try it without a reference to
still won’t work. Is there some special way of declaring a “button x of sheet 1 of window 1” ?
I’m new to applescript and i cannot find any references about this online.
thanks
There must be another cause.
The syntax is correct (even with the a reference to) if the line is within a System Events tell block
Thanks so much stefank. I finally got the handler declaration and calling to work.
I made some alterations to the code:
on ButtonClick(theObjectID)
tell application "System Events"
repeat until exists theObjectID
delay 0.2
end repeat
click theObjectID
end tell
end ButtonClick
tell application "System Events"
tell process "Installer"
my ButtonClick("Installer", button "Continue" of window 1)
keystroke "password"
keystroke return
my ButtonClick("Installer", button "Close" of window 1)
end tell
end tell
Problem now is that the part with the repeat until doesn’t seem to work anymore.
Before I placed the repeat clause in a handler, it worked perfectly, now, it seems to just move to the next line imediately giving me an error that goes something like "Cannot find button “Close”… if there is a slight delay in displaying the button.
What is the difference? The buttons click properly so I doubt it is the declaration.
Another problem i noticed is that there is a few seconds delay before the keystroke command is sent which delays the entering of the password into the form.
Please help.
You’re passing two parameters to the handler but in the handler declaration there’s only one.
I noticed also that there is a delay before accepting username and password in an authentication window.
It seems to be “normal”
sorry, i made a mistake in posting the script. it should have been the following:
on ButtonClick(theObjectID)
tell application "System Events"
repeat until exists theObjectID
delay 0.2
end repeat
click theObjectID
end tell
end ButtonClick
tell application "System Events"
tell process "Installer"
my ButtonClick(button "Continue" of window 1)
keystroke "password"
keystroke return
my ButtonClick(button "Close" of window 1)
end tell
end tell
There’s only one parameter in the actual code.
So there really is an expected delay when you enter the password into the authentication dialog? I think its a bit long (prbably around 5 seconds)
the UI elements inherit from the process, so include the process in the handler
on ButtonClick(theObjectID)
tell application "System Events"
tell process "Installer"
repeat until exists theObjectID
delay 0.2
end repeat
click theObjectID
end tell
end tell
end ButtonClick
tell application "System Events"
my ButtonClick(button "Continue" of window 1)
keystroke "password"
keystroke return
my ButtonClick(button "Close" of window 1)
end tell
Rather than scripting keystrokes try to insert the text directly into the text field
Done that, I used new handler used is below:
on ButtonClick(theProcess, theObjectID)
tell application "System Events"
tell process "Installer"
repeat until exists theObjectID
delay 0.2
end repeat
click theObjectID
end tell
end tell
end ButtonClick
\
error message i get is:
System Events got an error: Can’t get button “Close” of window 1 of process “Installer”. (-1728)
i’ve been stuck with this since last week.
Thanks for being so accomodating.
Probably the UI reference is wrong.
Download UIEelementinspector, the sample code includes also the application
the reference is correct. If i proceed to the window and use
click button “Close” of window 1
it works. The problem only occurs if for the repeat clause.
I’ve tested this script with an installer using Installer.app, it works
on ButtonClick(theObjectID)
tell application "System Events"
repeat until exists theObjectID
delay 0.2
end repeat
click theObjectID
end tell
end ButtonClick
tell application "System Events"
tell process "Installer"
my ButtonClick(button "Continue" of window 1)
-- keystroke "password"
-- keystroke return
my ButtonClick(button "Go Back" of window 1)
end tell
I’m having difficult making this happen. I too am trying to make a WinWaitActive-like functionality from AHK or AutoIt. It blows past it every time though.
Here’s what I have.
property Helpers : load script POSIX file "helpers.scpt" -- load helper file
tell Helpers
activate_finale()
menu_click_finale({"Utilities", "Change", "Ties."})
win_wait_active("Change Note Durations")
end tell
display dialog "Was it right?"
Here is the relevant section of the helper file for win_wait_active (stolen and edited above):
on win_wait_active(theObjectID)
tell application "System Events"
repeat until exists theObjectID
delay 0.2
end repeat
end tell
end win_wait_active
I intentionally set it up to fail by opening up the WRONG window (I tell it to open “Change Ties”). When “Change Ties” opens up I tell it to wait for “Change Note Durations” to show up to see if it will wait before executing the dialog. Since “Change Note Durations” is never going to show up, I should never see the dialog, but instead it immediately goes to the dialog every time as if the win_wait_active wasn’t even there.
I’m a applescript noob, so I bet it’s pretty simple.
Thanks in advance.
I tried the code straight forward in Finale 2014
property finaleProcess : "Finale 2014"
activate application finaleProcess
tell application "System Events"
tell process finaleProcess
click menu item "Ties." of menu 1 of menu item "Change" of menu 1 of menu bar item "Utilities" of menu bar 1
repeat until exists window "Change Ties"
delay 0.2
end repeat
end tell
end tell
you pass a literal string to the handler win_wait_active() but it’s supposed to be a reference to a window.
Try this, the reference must also include the process
property finaleProcess : "Finale 2014"
on win_wait_active(theObjectID)
tell application "System Events"
repeat until exists window theObjectID of process finaleProcess
delay 0.2
end repeat
end tell
end win_wait_active