AppleScript error when trying to get URL from Opera browser - applescript

I have a page opened in Opera browser and I'm trying to get its URL from terminal.
I've managed to do it like this:
osascript -e 'tell application "System Events" to return value of text field "Address field" of first group of text field "Address bar" of toolbar "Navigation" of group "Browser contents" of second group of first group of front window of application process "Opera"'
It works, but it requires access to System Events and Accessibility permission set. I'd like to access Opera directly like in this solution for Google Chrome.
So I've tried to rewrite it like this:
osascript -e 'tell application "Opera" to return value of text field "Address field" of first group of text field "Address bar" of toolbar "Navigation" of group "Browser contents" of second group of first group of front window'
But got an error:
49:56: syntax error: A “"” can’t go after this identifier. (-2740)
Any ideas how to fix it?

It is possible to interact with Opera (or Safari and Chromium based browsers) without using of "System Events".
With opening the "Script Editor.app":
File > Open Dictionary > and choosing "Opera.app" from the list of dictionaries you can browse it's dictionary.
Based on this with the following snippet you can fetch the URL of the active tab:
tell application "Opera"
return URL of active tab of front window
end tell

Related

Need script to click button on website that downloads a file

I am new to this so this is probably a dumb question but....
I am trying to get a download to happen off a website by clicking on a link but I don't think I have my code right for AppleScript.
The script opens the right website, but when I try to get it to download the file I need by clicking "export data" the code below doesnt seem to do anything, and am not sure what I am missing/did wrong. No error code. Just doesnt do anything.
Website Here
to clickId(LeaderBoard1_cmdCSV)
tell application "Safari"
do JavaScript "document.getElementById('" & LeaderBoard1_cmdCSV & "').click();" in document 1
end tell
end clickId
Thanks for the help.
The following example AppleScript code will open a new Safari window to the designated URL, wait for the page to finish loading, then click the Export Data link to download the FanGraphs Leaderboard.csv file.
Note: This was tested on macOS High Sierra, however for macOS Mojave and later there is a note in the waitForPageToFinishLoadingInSafari() handler to modify its code. Don't forget to do it if applicable.
To use JavaScript with AppleScript and Safari the Allow JavaScript from Apple Events on the Safari > Develop menu, which is hidden by default, must be checked. It can be shown by checking [√] Show Develop menu in menu bar in: Safari > Preferences… > Advanced
set theURL to "https://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=50&type=c%2c6%2c11%2c12%2c13%2c21%2c23%2c39%2c35%2c34%2c41%2c42%2c43%2c104%2c107%2c110%2c206%2c209%2c211%2c50%2c61&season=2019&month=0&season1=2019&ind=0&team=0&rost=0&age=0&filter=&players=0"
tell application "Safari" to ¬
make new document with properties {URL:theURL}
my waitForPageToFinishLoadingInSafari()
my clickId("LeaderBoard1_cmdCSV")
-- # Handlers:
to clickId(ElementID)
tell application "Safari"
do JavaScript "document.getElementById('" & ElementID & "').click();" in document 1
end tell
end clickId
on waitForPageToFinishLoadingInSafari()
-- # NOTE: For macOS Mojave and later, change 'UI element 1' to 'UI element 2` in the code below.
tell application "System Events"
repeat until (accessibility description of ¬
button 1 of UI element 1 of every group of toolbar 1 of window 1 of ¬
process "Safari" whose name = "Reload this page") contains "Reload this page"
delay 0.5
end repeat
end tell
end waitForPageToFinishLoadingInSafari
Note: The example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

AppleScript returns "missing value" for URLs of some tabs in Safari

I periodically save all URLs open in Safari to a file. (Don't want to use browser bookmarks or rely on the app's memory after a crash)
The following code works well but returns "missing value" for some tabs. (Safari 12 in OS 10.13)
tell application "Safari"
set tabList to URL of every tab of every window
end tell
The "missing value" result for the tab's URL happens when a background tab goes dormant. The tab title shows the correct value in the background but it does not return the URL. I can activate the dormant tab by bringing it to the front and after the page loads, the proper URL is returned by the script.
Is there a way to return the correct URLs of all tabs without having the script cycle through all the tabs and activating them?
Incidentally, the dormant tabs return the correct values for the names of the tabs using this line of script:
set tabList to name of every tab of every window

Accessing "hidden" windows in AppleScript

I'm trying to set up an applescript which will handle a slightly-annoying VPN login process for me. I use Cisco AnyConnect, and every time I have to log back on, I have to hit connect, accept a certificate warning, enter my username, password, and select the right group, and accept ANOTHER certificate warning.
It's that second certificate warning I can't seem to get around.
Some digging indicates that the warning dialog is owned by a process named vpndownloader, but the odd thing is that Applescript seems convinced that it has no windows and does not exist!
I've been using Accessibility Inspector to get the window IDs and such to make this script work. For this particular dialog, it looks like this (accessibility inspector behind the actual dialog I'm attempting to control)
The strangeness comes in when I try to get the window's ID so I can do things with it.
tell application "System Events" to windows of process "vpndownloader"
{}
Blank. Okay, maybe there's something useful in the properties of the process?
tell application "System Events" to properties of process "vpndownloader"
{has scripting terminology:false
bundle identifier:"com.yourcompany.vpndownloader"
file:alias "Macintosh HD:opt:cisco:anyconnect:bin:vpndownloader.app:" of application "System Events"
creator type:"????"
subrole:missing value
entire contents:{}
selected:missing value
application file:alias "Macintosh HD:opt:cisco:anyconnect:bin:vpndownloader.app:" of application "System Events"
orientation:missing value
role:"AXApplication"
accepts high level events:true
file type:"APPL"
value:missing value
position:missing value
id:1212712
displayed name:"vpndownloader"
name:"vpndownloader"
class:application process
background only:true
frontmost:false
size:missing value
visible:false
Classic:false
partition space used:0
role description:"application"
maximum value:missing value
architecture:"i386"
short name:"vpndownloader"
focused:missing value
minimum value:missing value
help:missing value
title:"vpndownloader"
accepts remote events:false
total partition size:0
description:"application"
accessibility description:missing value
enabled:missing value
unix id:9053}
(for giggles, note that Cisco didn't set their bundle identifier..)
No contents, no visible windows. Despite the dialog I've got up right in front of me.
So, on one hand it obviously has a window (accessibility inspector can see it), but AppleScript is convinced that it does not.
How do I programmatically locate and access this "phantom" dialog?
Things that didn't work:
tell application "vpndownloader" to windows
error "vpndownloader got an error: Can’t get every window." number -1728 from every window
Again the theme of this application being in a weird state between existence and nonexistence comes up
tell application "vpndownloader" to properties
error "vpndownloader got an error: Can’t get every property." number -1728 from every property
It has a menu bar, but no windows.
tell application "System Events" to get UI elements of process "vpndownloader"
{menu bar 1 of application process "vpndownloader" of application "System Events"}
You can probably just use keystrokes. For example when that window comes up you yourself can probably physically hit the "connect anyway" button by first pressing the "tab" key to change the focussed button and then press the "space bar" to select the focussed button.
NOTE: you may have to enable this functionality by enabling full keyboard access. Do this by going to system preferences->keyboard->shortcuts and checking "all controls" at the bottom of the window.
If you can then you can applescript it. The following will work as long as that window is frontmost when you issue the commands.
tell application "System Events"
keystroke tab
delay 0.2
keystroke space
end tell
Good luck.
It works for me (I use anyconnect 3.1.06073).
https://gist.github.com/lotreal/ce43f4a85d8ae73781fa
So I found an interesting workaround for this problem that doesn't involve scripting. It turns out the vpndownloader is entirely optional, and it apparently only serves the purpose of updating the client when an update is pushed from the upstream server
A local policy XML can be defined to disable the process. This will cause breakage if an update is pushed (the connection will just abort), but it at least allows the login to be scripted.
On Mac/Linux systems, this file is located in /opt/cisco/anyconnect/AnyConnectLocalPolicy.xml - I had to create one based on the schema file, AnyConnectLocalPolicy.xsd in the same folder. If it already exists, just edit the existing one.
The key line is <BypassDownloader>, which is set to false by default. Setting it to true means that the downloader is simply not run, meaning the second dialog I was trying to access simply never appears!

Can I manipulate the location of a dialog displayed through osascript?

I've been playing around with various UNIX commands and came across this one to display a dialog:
osascript -e 'tell app "System Events" to display dialog "Hello World"'
I'd like to change the position of the dialog. For most commands, I can just use man command to figure out how to do something for that command. However, man osascript doesn't tell me how I can change the position of the dialog box. How can I modify the command to put the dialog in a different place?
First, to get help with applescript just open the AppleScript Editor application and look under the help menu. The applescript language guide is in there and other tools. Also under the file menu is "Open Dictionary" which will show you the specific commands for applications.
To see the information about display dialog, open the dictionary of StandardAdditions and use the search field to find the command.
To answer your question, no, you cannot specify the location of a "display dialog" window. There are no parameters in that command for positioning the window, as you'll see in the dictionary. In addition, no other commands will help you either because you can't issue other commands while the dialog window is open because the code pauses while the window is open waiting for a response from the dialog window (like when you press the OK button).
If you need to set the position of a window to display information to a user then you'll need to use some other dialog tool other than "display dialog". You could create your own window in cocoa or google for some alternatives like cocoaDialog, SKProgressBar, and Notification Center.
There is a round-about way to go about this, which may be useful in some scenarios. Try the following:
on displayMessage(msg)
tell application "Finder"
activate
set c to (count windows)
ignoring application responses
display dialog msg with icon note
end ignoring
end tell
tell application "System Events"
tell application process "Finder"
repeat until ((count windows) > c)
delay 0.2
end repeat
set position of window 1 to {0, 22}
end tell
end tell
end displayMessage
displayMessage("I'm over here!")
Credit for this little script goes to a post here.
In implimenting this myself, I found it was limited to whether or not the application that is being called (Finder, in the example) supports the count window command (or whether it has API support at all).
I realise I've dragged up a question from 2013. I am posting this answer here in case it is of use to the OP or, more likely, someone else with a similar question.

How do I set Mac OS X 10.6 Terminal tab title programmatically?

I'm trying to learn Applescript as I'd like to, eventually, programmatically set the title of the tab in Terminal to whatever context I'm currently working in. Should be a simple task and I've gotten it almost right I think. This is my experimental code so far...
tell application "Terminal"
activate
set frontIndex to index of the first window whose frontmost is true
tell window frontIndex
set title displays custom title of selected tab to true
set custom title of selected tab to "Bazzy"
end tell
end tell
The problem is that when I set the tab's title, the title of all other tabs also get set. However, if I right-click and inspect a tab and then set the title manually on that tab, its title is not affected when I run my code and the title I manually typed in remains. It's as though the title displays custom title property is not being read or perhaps this property does not do what I think it does.
How can I set the title of exactly one tab to a custom value?
I you're executing the script from the Terminal itself you can use a simple echo, e.g.:
echo -n -e "\033]0;Tech-Recipes rules\007"
It event works if you put it inside $PS1 so that it changes each time the prompt is rendered.
source: How do I set Mac OS X 10.6 Terminal tab title programmatically?
I just tried this and it worked fine:
tell application "Terminal"
set custom title of tab 2 of window 1 to "beta"
set custom title of tab 1 of window 1 to "alpha"
end tell
I admit I wasn't using 10.6 so maybe Apple changed it.
This property does not do what you think it does. Setting the custom title to one tab applies to all tabs in all windows, per this code:
tell application "Terminal"
tell window 1
set title displays custom title of tab 1 to true
set custom title of selected tab to "foo"
end tell
tell window 2
set title displays custom title of tab 2 to true
set custom title of selected tab to "bar"
end tell
end tell
--> RESULT: All tabs in all windows show "bar"
I wonder if it has to do with the title relating to the environment—i.e., bash, csh, zsh, ksh—and not to individual tabs. Even if I quit Terminal and come back in, "bar" still shows everywhere. I'll freely admit that I don't know enough about how the CL interface works to know for sure.
At the same time, if you are learning Applescript, I would suggest learning it on something a little less wonky, like the Finder or something. There are loads more useful things that can be done there than in Terminal with Applescript.
There's some weird behaviour around these commands when grabbing the correct window/tab, but this ended up working for me in 10.5.8 (Terminal v2.0.2)
tell application "Terminal"
do script
set currWin to index of first window
tell window currWin
set custom title of first tab to "A Custom Title"
end tell
set current settings of window currWin to settings set "Grass"
end tell
The key here is that do script opens a new terminal window, thereby forcing it to be 'first' (do script also returns the created tab index, but I couldn't make any use of it).
The custom title then applies only to that window. Also threw in a line to set the profile for the terminal tab.
(Referenced: AppleScript to open named terminal window)
Additional
Example of weird behaviour: removing the do script line results in the custom title being applied to all windows, but only one window receives the settings set change!
As of Mac OS X Lion 10.7, Terminal only sets the custom title property of the target tab/window instead of changing the settings profile (which affects all terminals with that profile). Prior to 10.7, most—but not all—of the terminal properties applied only to the target terminal; however, a few of them applied to the settings profile used by the terminal. Those have been changed in 10.7 to only affect the target terminal.
I was looking for this for a while and as #tponthieux mentioned in his comment, all these scripts change the terminal window title not tab title. Unfortunately, it seems there is no option to change the tab title with a ready apple script, so I did it with using keys and it works without a problem on OSX El Capitan.
tell application "Terminal"
activate
tell application "System Events"
keystroke "i" using {shift down,command down}
keystroke Tab
keystroke "yourtitlehere"
key code 53
end tell
The titles for OSX Terminal come from a few different sources.
1) Preferences > Window: Select Terminal > Preferences > Window (tab). Here you will find all kinds of configuration for titling the window.
2) Preferences > Tab: Select Terminal > Preferences > Tab (tab). Here you will find all kinds of configuration for titling the tab.
3) Console codes: The VT100 commands you can use (more info by searching for OSC here)
echo -n -e "\033]0;Set icon name (tab) and window title to this.\007"
echo -n -e "\033]1;Set the icon name (tab) to this\007"
echo -n -e "\033]2;Set window title to this\007"
NOTE: as Elia Schito said, you can place these console codes inside $PS1 so it updates each command you enter.
This is what I needed to do:
tell application "Terminal"
do script "DISABLE_AUTO_TITLE=true" in selected tab of the front window
do script "echo -n -e \"\\033]0;" & title & "\\007\";" in selected tab of the front window
end tell
The first line is needed for ZSH.
However, it still doesn't work well for long-running processes, since their names continue to dominate the tab title.

Resources