Hello,
I wrote a GUI script that targets SecurityAgent, a faceless application that’s starts every time you must supply your credentials for things like viewing passwords in Keychain Access and granting levels of access, e.g always or only once. Every time it kicks off the fields are filled in automatically.
I have succeeded in achieving that in pre-ElCapitan macOS but in Mojave even if the application “SecurityAgent” is frontmost then retrieving its structure in Script Editor (by referencing its elements like [format]get window 1[/format], [format]get every UI element of window 1[/format] etc.) poses an unexpected difficulty: one moment it’s retrievable the next one it errors out with the message[format] "Invalid index. Can’t get window 1 of application “SecurityAgent” of application “System Events”[/format]. Requesting its objects by calling them with [format]get every UI element of process “SecurityAgent”[/format] returns an empty list.
Is there a workaround to make it work the old way?
NB. BTW, no problem with unlocking “System Preferences” as well as signing in with Apple ID in relevant applications because those follow a more traditional GUI structure.
My script is
tell application "System Events"
try
if application process "SecurityAgent" exists then
tell application process "SecurityAgent"
set frontmost to true -- debugging. Not needed in the real-life scenario because it's already frontmost.
tell window 1
set TheButtons to buttons
set ButtonNames to {"OK", "Unlock", "Always Allow"}
set AllElems to entire contents
set TxtFlds to {}
repeat with Elem in AllElems
if Elem's contents's role is "AXTextField" then set end of TxtFlds to Elem's contents
end repeat
if (count TxtFlds) is equal to 2 then
set SbRls to {}
repeat with Elem in TxtFlds
set end of SbRls to subrole of Elem's contents
end repeat
set _Classes to {}
repeat with Elem in SbRls
set end of _Classes to Elem's contents's class
end repeat
set InputSecureFields to {}
repeat with i from 1 to the number of items in SbRls
set ElemInfo to {SbrlClass:missing value, GenericClass:missing value, ElemValue:missing value}
set {ElemInfo's SbrlClass, ElemInfo's GenericClass} to {_Classes's item i's contents, TxtFlds's contents's class}
if _Classes's item i's contents is class then set ElemInfo's ElemValue to TxtFlds's item i's contents's value
set end of InputSecureFields to ElemInfo
end repeat
set IsMacUserNameEmpty to ""
repeat with aRecord in InputSecureFields
if aRecord's contents's SbrlClass is class then
set IsMacUserNameEmpty to aRecord's contents's ElemValue
exit repeat
end if
end repeat
-- end tell
if IsMacUserNameEmpty is "" then
tell (the first text field whose subrole is missing value)
set focused to true
keystroke MYUSERNAME using shift down
key code 48
end tell
end if
delay 1
tell (the first UI element whose subrole is "AXSecureTextField")
keystroke MYPASSWORD using shift down
end tell
delay 1
repeat with aButton in TheButtons
if aButton's contents's name is in ButtonNames then
tell aButton's contents to perform action "AXPress"
exit repeat
end if
end repeat
else if (count TxtFlds) is equal to 1 then -- only the password field.
tell (the first UI element whose subrole is "AXSecureTextField")
keystroke MYPASSWORD using shift down
end tell
repeat with aButton in TheButtons
if aButton's contents's name is "Always Allow" then
tell aButton's contents to perform action "AXPress"
exit repeat
end if
end repeat
else -- no input fields at all, only buttons.
repeat with aButton in TheButtons
if aButton's contents's name is "Always Allow" then
tell aButton's contents to perform action "AXPress"
exit repeat
end if
end repeat
end if
end tell
end tell
end if
end try
Model: MacBook Pro 9,1 (mid-2012 15") Core i7 2.3 GHz, 16 GB RAM, 1TB SSD
AppleScript: 2.7
Browser: Safari 605.1.15
Operating System: macOS 10.14