I'm looking for the way to access UI which applescript can not access. I know applescript can access UI element. But sometimes I meet the case I can't access UI element by applescript. Like below ...
tell application "System Preferences" to activate
delay 1
tell application "System Events"
tell process "System Preferences"
set frontmost to true
click button 22 of scroll area 1 of window 1
delay 1
UI elements of last group of list 1 of window 1
end tell
end tell
This just returns 2 UI elements image and static text.
{
image 1 of group 3 of list 1 of window "Users & Groups" of application process "System Preferences" of application "System Events",
static text "Login Options" of group 3 of list 1 of window "Users & Groups" of application process "System Preferences" of application "System Events"
}
Apparently there is a clickable UI element which above 2 elements belonging. Because I can click "Login Options".
Fortunately by sending key stroke and key code commands were received properly.
set DownArrow to 125
set UpArrow to 126
tell application "System Preferences" to activate
delay 1
tell application "System Events"
tell process "System Preferences"
set frontmost to true
click button 22 of scroll area 1 of window 1
delay 1
keystroke tab
repeat 3 times
delay 1
key code DownArrow
delay 1
key code UpArrow
end repeat
end tell
end tell
tell application "System Preferences" to quit
My question is ...
Why does applescript seem to ignore "Login Options" UI element?
Why can't I click "Login Options" UI element with a mouse or trackpad?
Why can't key stroke and key code command access the "Login Options" UI element?
Is there really no way to select the "Login Options" UI element without using key stroke and key code commands?
How to access applescript non-accessible UI element?
Any hint is appreciated. Any code(python, c, objective-c, etc) is more appreciated.:)
Thanks.
To solve many of these problems you do not need System Events. For example, System Preferences is script-able enough to at least do this, which solves a few of your problems:
tell application "System Preferences"
activate
set the current pane to pane id "com.apple.preferences.users"
reveal anchor "loginOptionsPref" of current pane
end tell
So,
AppleScript isn't "ignoring" the Login Options control;
You don't need to click, you can use "reveal" (do you mean to type "can't" instead of "can"? -- I've edited your post to format your questions more correctly);
I think this makes the 3rd question moot;
My example shows the way to do it w/o clicking
How to access "non-accessable" items -- much bigger question:
While it is true that System Preferences is script-able, there are times when you may need System Events. For example, I have a script for the Sound pane that uses the following handler (subroutine):
on doSysEvSelect(whatToSelect, whatWindow)
tell application "System Events"
tell process "System Preferences"
select (row 1 of table 1 of scroll area 1 of tab group 1 of window whatWindow whose value of text field 1 is whatToSelect)
end tell
end tell
end doSysEvSelect
, which I can use by doing, for example:
doSysEvSelect("Internal Microphone", "Sound")
Using System Events can be frustrating to figure out. But of course there are many examples around to find. And if you're really in a bind, you can use Sikuli (http://sikuli.org/) to automate just about anything, but which relies totally on the UI and clicking.
[edit]
And here's an example of what to do with an item in Login Options once you're there (this is where you need to use System Events):
tell application "System Events"
tell process "System Preferences"
if value of checkbox "Show password hints" of group 1 of window "Users & Groups" is 0 then
click checkbox "Show password hints" of group 1 of window "Users & Groups"
end if
end tell
end tell
You can simulate clics like you do directly when using system preferences, but you need to know which object to click.
Fyi, here is an example of system preferences click and select for Bluetooth. it gives an idea of the way to do it :
tell application "System Preferences"
activate
set current pane to pane "com.apple.preferences.Bluetooth"
tell application "System Events"
tell process "System Preferences"
-- select row containing the word "mouse"
repeat with I from 1 to count of row of table 1 of scroll area 2 of group 1 of front window
set Nom_Perif to (description of static text 1 of row I of table 1 of scroll area 2 of group 1 of front window) as string
if Nom_Perif contains "Mouse" then
set selected of row I of table 1 of scroll area 2 of group 1 of front window to true
if Nom_Perif contains "not connected" then
-- sert connection via item 1 of menu
click menu button of group 1 of front window
delay 1
click menu item "Connect" of menu of menu button of group 1 of front window
delay 3
end if
end if
end repeat
end tell
end tell
end tell
quit application "System Preferences"
Related
I have gone through stack overflow, this might seem like a duplicate question but this is more like an extended question to the existing issue!
I am facing a very strange issue, in my application we have customised the pop up button (Inheriting from NSPopupButton).
When I use Apple Script to access the pop up item, the script is not able to select any value from the popup list.
Let me be more clear!
For eg.
Imagine the Popup button has "Car, Bike, Cycle, Bus" as its items. Now if I use AppleScript to select Bike and then click enter, the value is not getting reflected. But manually if I select "Bike" it will reflect in the application.
This is the script that I wrote.
click menu button "Car" of window 1 of application process "My Sample Application" of application "System Events"
key code 125 //I am using these to navigate down the list
delay 1
key code 125 //I am using these to navigate down the list
delay 1
key code 125 //I am using these to navigate down the list
delay 3
key code 36 //This line simulated ENTER/Return key (or NOT?)
I have also tried running this command in Apple Script
--set xxx to value of every button of menu button "Car" of window 1 of application process "LG Calibration Studio" of application "System Events"
This command was suppose to show me all the items present in the Popup, but unfortunately it is returning an empty array(or Dictionary). Even though the pop up is populated with values I am not sure why this is returning empty.
I am kind of new to Apple Script and do not have much knowledge in this domain. Any help is appreciated.
Thanks in advance :)
When using UI scripting, the relationships between ui objects is not always clear. I'll use Apple's Pages (as it's freely available — I use an untouched 'Essay' document) as an example. Here are two suggestions to explore. If they make sense, you can try similar actions with your own app.
UI Elements command
In a new script…
tell application "Pages"
-- activate -- Not necessary until you want to act upon the window
tell application "System Events" to tell front window of application process "Pages"
UI elements -- generate list of window's ui elements
properties of splitter group 1 -- the first element in the list (branch 1)
UI elements of splitter group 1 -- generate list of first branch
-- entire contents
end tell
end tell
Partial result of command 1
{splitter group 1 of window "Untitled" of application process "Pages" of application "System Events", button 1 of window "Untitled" of application process "Pages" of application "System Events", button 2 of window "Untitled" of application process "Pages" of application "System Events"}
Partial result of command 2
{minimum value:missing value, orientation:missing value, position:{40, 22}}
Partial result of command 3
{scroll area 1 of splitter group 1 of window "Untitled" of application process "Pages" of application "System Events", static text "0 Comments & Changes" of splitter group 1 of window "Untitled" of application process "Pages" of application "System Events", button "Comment" of splitter group 1 of window "Untitled" of application process "Pages" of application "System Events"}
Using ui elements you can work your way through the myriad interface objects in your window. You can also ask for specific properties, e.g. name of every pop up button. Finally, you can get a list of all ui elements with entire contents.
Accessibility Inspector
Using the application Accessibility Inspector, you can inspect the window and discover its elements. This is located inside XCode's app bundle and is also accessible through the XCode > Open Developer Tool menu.
It changes with the version of XCode so there isn't any point in getting too detailed (I'm on Xcode 9) but once it is launched, click on the 'All Processes' drop down button at the top left and it should list the open apps; select Pages from this list.
A couple of things to note: At the bottom is the hierarchy of elements which can help in determining which object to act upon. Each line's bracketed text references the class of object but the text isn't always literal (e.g. your script should use 'window' not 'standard window').
If you use the 'pointer' and then in Pages, click on the empty area at the bottom of the Format inspector, the hierarchy will show a long list of items under (scroll area). Also, there are various ways to interact with an interface object, of which 'click' is but one.
If I insert this code into the script and then select the body text, the script will format the selection as italics (which matches the hierarchy entry 'Regular (pop up button)', with 'Regular' being the selection's existing font format.
tell pop up button 2 of scroll area 2 of splitter group 1 of ¬
window "Untitled" of application process "Pages" of ¬
application "System Events" to perform action "AXPress"
delay 0.5
keystroke "i"
key code 36
Hopefully, utilizing these two approaches may yield some useful results before the onset of ui scripting headache.
Attempting to create automation to open a Safari browser with multiple tabs and login to common websites I use each day. I've achieved opening the browser and adding new tabs with specific URL's and prompting user for username and password but am having difficulty with simply moving between the open tabs.
I have tried assigning an index, naming the "current tab", using a title, etc. nothing seems to work... see sample below...
--Prompt user for login information
set GEmail to text returned of (display dialog "Enter Password" with title "Gmail" default answer "")
set GPassword to text returned of (display dialog "Enter Password" with title "Gmail" default answer "")
--Activate Safari and open new tab with URL
tell application "Safari"
activate
make new document with properties {URL:"https://gmail.com"}
delay 3
tell application "System Events"
delay 2
keystroke tab
keystroke GEmail
delay 2
keystroke tab
keystroke GPassword
keystroke return
end tell
--Create new tab pointing to Google > this does not actually open the new tab
set the URL of (make new tab in window 1) to "http://www.google.com"
end tell
I’ve tried multiple things but still cannot seem to actually move between the tabs and will eventually need to add several more tabs which I will need to toggle between.
To create a new tab, while setting focus to it, at a given URL use, e.g.:
tell application "Safari" to ¬
tell front window to ¬
set current tab to ¬
(make new tab with properties {URL:"http://www.google.com"})
I need to perform automatic installation extension in Safari.
Now I have this part of code:
property extension_list : {"safariextz"}
on adding folder items to this_folder after receiving these_items
try
tell application "Finder"
repeat with i from 1 to (number of items in these_items)
set this_item to item i of these_items
set item_extension to name extension of this_item
if item_extension = "safariextz" then
tell application "Safari" to open this_item
delete this_item
end if
end repeat
end tell
on error errmsg
display dialog errmsg buttons {"OK"} default button 1
end try
end adding folder items to
This works, file is running after downloading.
But I cannot press button Install for starting installation extension.
I tried something like that
tell application "System Events"
tell process "Safari"
click the button "Install"
end tell
end tell
But this doesn't help.
Cloud you please assist to me with completing script for extension installation?
You must specify a window like this : click button 1 of window 1
open an "safariextz" file in Safari blocks the script, you must use ignoring application responses
The script must check that the dialog is displayed
on adding folder items to this_folder after receiving these_items
repeat with this_item in these_items
if (this_item as string) ends with ".safariextz" then
ignoring application responses
tell application "Safari" to open this_item
end ignoring
tell application "System Events"
tell process "Safari"
set frontmost to true
repeat until (exists window 1) and subrole of window 1 is "AXDialog" -- wait until the dialog is displayed.
delay 1
end repeat
click button 1 of front window -- install
end tell
end tell
end if
end repeat
end adding folder items to
Updated : as ignoring application responses doesn't work for you, try this
on adding folder items to this_folder after receiving these_items
repeat with this_item in these_items
if (this_item as string) ends with ".safariextz" then
tell application "Finder" to open this_item
For Safari 9, the button's context changed. Here's the script I figured out to get it back working. (This is only to show the order of commands and how to click the button.)
tell application "Safari" to activate
delay 2
tell application "System Events"
tell application process "Safari"
set frontmost to true
tell application "Safari" to open location "/path/to/SafariDriver.safariextz"
delay 2
click button 1 of sheet 1 of window 1
end tell
end tell
tell application "Safari" to quit
I am trying to trap mouse click events in Safari with Applescript. My Applescript does what it needs to do, but I want to terminate if the user clicks on the document in Safari. I would like to set up an On_Click event in Applescript that would fire if the user clicks in the Safari document.
I do not know how to "trap" a mouse event with applescript. You'd have to use objective-c and the cocoa APIs for that.
However you might do it another way. Here's a quick example. Save this as a stay-open applescript application. When you run it the Safari window will scroll. To pause the scrolling just click the dock icon of the applescript. If you click the dock icon again then the scrolling will start again and vice versa. You'll notice that every time you click the dock icon the "on reopen" handler is executed which toggles the shouldScroll variable between true and false.
Anyway, I hope this gives you an idea for making your own script work. Remember you can quit the stay-open applescript by right-clicking on its dock icon and choosing quit. Good luck.
property shouldScroll : missing value
property theCounter : missing value
property counterMaxValue : missing value
on run
tell application "Safari" to activate
set shouldScroll to true
set theCounter to 0
set counterMaxValue to 2000
end run
on reopen
tell application "Safari" to activate
set shouldScroll to not shouldScroll
end reopen
on idle
if shouldScroll then
if theCounter is greater than counterMaxValue then set theCounter to 0
tell application "Safari" to tell document 1
do JavaScript "window.scroll (0," & (theCounter as text) & ")"
end tell
set theCounter to theCounter + 20
end if
return 0.1
end idle
You might exit the script when the focused window becomes a normal browser window, by for example testing if the frontmost window has a full screen button:
tell application "System Events" to tell process "Safari"
repeat until exists value of attribute "AXFullScreenButton" of window 1
--do something
delay 1
end repeat
end tell
Or if the script is supposed to stop when Safari becomes the frontmost application:
repeat until frontmost of application "Safari"
--do something
delay 1
end repeat
I'm trying to automatically select a menu item in iTunes using applescript. However, every time that I run this script I get an error message that says "expected end of line but found number, and points me to "scrollarea 1". I'm using Apple's UIElement inspector to get the names of the GUI elements in iTunes. Any help would be greatly appreciated.
Here's what I have so far:
tell application "iTunes"
activate
delay 10
tell application "System Events"
key code 53
tell outline 1 of scrollarea 1 of window 1
click menu 1
end tell
end tell
end tell
Well, I have it clicking what I need it to be clicking. The only problem now is that it's not actually clicking it, it's just returning the AXValue. I need it to actually click the item in iTunes itself.
activate application "iTunes"
tell application "System Events"
tell process "iTunes"
select row 15 of outline 1 of scroll area 2 of window "iTunes"
end tell
end tell