Applescript Toggle between tabs in Safari - safari

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"})

Related

AppleScript -- Menu Item in the Menu Button popup is not selectable while using keystroke return or (key code 36) command

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.

Open a webpage in the default browser with specific size in VB.NET

I want my users to be able to click a button to open my company webpage in the default browser with specific size(Like-width=SomeSize,height=SomeSize')when clicked. How would I do this?
I'm using VB.net so all .net examples are acceptable.
To do this in whatever browser the user has installed would be very difficult. Each browser has its own command line arguments, so you would have to detect which browser is being used, and code for all possible browsers..
If you are willing to have windows open the page in Internet explorer, you could use add a reference in your solution explorer to the windows Shell Document Viewer.
To do this, in your solution explorer window, right-click on "References".
Click "Add Reference". This opens the "Reference Manager" window
In the window that opens, down at the bottom right click the button "Browse"
In the file dialog, in the file name box type "C:\Windows\System32\shdocvw.dll" without quotes.
Click the "Add" button. and the dialog should close, leaving you with the "Reference Manager" window.
In this window, in the list in the middle, you should see "shdocvw.dll" with a tick next to it. Click the "Ok" button.
You now have a reference to the Shell Document Viewer
Finally, add the following code to wherever you want the window to open and change the parameters to whatever you require
Dim TheBrowser = New SHDocVw.InternetExplorerMedium With {
.Visible = True,
.Width = 500,
.Height = 500
}
TheBrowser.Navigate(URL:="http://www.google.com")
You can just write:
System.Diagnostics.Process.Start("http://google.com")

AppleScript Safari : Click button after page has fully loaded

I have this script here which is loading a profile on an unfocused safari tab and saving the text I want in a variable
tell application "Safari" to set the URL of tab 2 of window 1 to "https://URLproduct/" & serialNumber & "/definition"
delay 2.5
However some of the data is only available after a click on a button (this is a pop-up like overlay with a button, which make the another text not accessible until you press on "OK", also this button is not always here)
button HTML is :
<button class="btn btn-primary" autofocus="" ng-click="ok()" tabindex="0">OK</button>
which I press with this script :
do JavaScript "document.getElementsByClassName('btn btn-primary')[1].click();" in tab 2 of window 1
Weirdly sometime is working sometime not and I can't add too much delay
Can I add a script which would wait for this button ('btn btn-primary') been availible (fully loaded) and then try again to get the text by with my 1st script?
--
May be I can add something like
tell application "Safari"
tell document 1
repeat until ("btn btn-primary" is in its source)
delay 0.5
end repeat
end tell
end tell
then the click script?
yes, you can start executing your script after the page has loaded. This makes sure that the button is clickable (in case it appears at all).
Put this code in to your script:
tell application "Safari"
repeat until (do JavaScript "document.readyState" in document 1) is "complete"
end repeat
end tell
Happy scripting!

How to access UI which applescript can not access?

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"

Trap mouse click in Safari with Applescript

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