I am trying to click a simple button in safari when on a web page using applescript. I have the following code:
tell application "Safari"
activate
repeat 5 times
do JavaScript "document.all(\"Roll Again\").click()" in document 1
delay 2
end repeat
end tell
However, when I run this code, I get an error: "missing value". The event log displays the following result:
tell application "Safari"
activate
do JavaScript "document.all(\"Roll Again\").click()" in document 1
--> missing value
do JavaScript "document.all(\"Roll Again\").click()" in document 1
--> missing value
do JavaScript "document.all(\"Roll Again\").click()" in document 1
--> missing value
do JavaScript "document.all(\"Roll Again\").click()" in document 1
--> missing value
do JavaScript "document.all(\"Roll Again\").click()" in document 1
--> missing value
end tell
Could someone please tell me why the button is not being pressed and what missing value means? Is there another simpler way to achieve the button press? I can press the button using automator, however I would like to do it using AppleScript.
P.S. document is the current window in safari
document.all is specific to IE and doesn't work in Safari. Try using getElementById or querySelectorAll:
tell application "Safari"
activate
tell document 1
do JavaScript "document.getElementById(\"nav-badges\").click()"
delay 5
do JavaScript "document.querySelectorAll(\"#hmenus a\")[0].click()"
end tell
end tell
Related
Please note: The site is not letting me post this question unless I incorrectly format it i.e. the two middle sections of "code" which aren't actually code. I've done my best to edit it, to fix it, and I apologise if the formatting is poor.
I’ve found and adjusted two scripts, which run, individually. This is my first AppleScript project, and I’d like help joining them together to MAKE ONE SCRIPT.
I want Script 2 to use the result from Script 1.
e.g. set menuItems to (Script 1 Result names)
I made a dummy testGroup in my Contacts. The Pop-Up Menu only needs the names. I will use the corresponding email addresses later, in another script.
I hope this is clear enough. Thanks in advance for your help.
Script 1
--returns Contacts testGroup’s names and email addresses
set myList to ""
tell application "Contacts" to repeat with p in people in group "testGroup"
if emails of p is {} then
set e to ""
else
set e to value of email 1 of p
end if
set myList to myList & name of p
end repeat
Script 1 Result needs parsing...
"Joe BloggsMolly MousePeter Pan"
to this...
{"Joe Bloggs", "Molly Mouse", "Peter Pan"}
so I can use it in Script 2 menuItems below.
Script 2 MUST use names from Script 1 Result, like this
-- Make Pop-Up Menu in Numbers spreadsheet which is already open.
set menuItems to {"Joe Bloggs", "Molly Mouse", "Peter Pan"}
tell application "Numbers"
activate
tell the first table of the active sheet of document 1
tell cell "A3"
set value to item 1 of menuItems
set the format to pop up menu
end tell
end tell
end tell
tell application "System Events"
tell application process "Numbers"
set frontmost to true
tell window 1
click radio button "Cell" of radio group 1
repeat with i from 2 to (count menuItems)
click button 1 of group 1 of scroll area -1
keystroke (item i of menuItems)
end repeat
end tell
end tell
end tell
The first script is going through the items of a list list to create a string, while the second script is just wanting the list. Since the Contacts application will give you a list of names, the first script isn't needed at all - the menuItems of the second script can just be set with:
tell application "Contacts" to set menuItems to the name of people in group "testGroup"
I tried to fill a web form with the data from Excel using AppleScript, but Safari said:
TypeError: undefined is not an object (evaluating 'document.getElementsByName('txtnama')[0].value=txtnama')
Here's the code :
tell application "Microsoft Excel"
activate
set txtnama to value of cell "I2"
tell application "Safari"
activate
do JavaScript "
var txtnama= '" & txtnama & "';
document.getElementsByName("txtnama")[0].value=txtnama;" in document 1
end tell
end tell
The element of the form I'm trying to fill is:
<input type="text" name="txtnama" style="width:300px;" maxlength="80" value="">
Your quotes are mismatched and/or unescaped, but the basic code is correct. Here is the Safari part of your code re-formatted with correct quoting:
tell application "Safari"
do JavaScript ¬
"var txtnama=" & quoted form of txtnama & ";" & ¬
"document.getElementsByName('txtnama')[0].value=" & ¬
quoted form of txtnama ¬
in document 1
end tell
You also shouldn't nest the Safari tell block inside the Microsoft Excel tell block unless there's specific reason to do so. Therefore, move the end tell at the end to just after you define your variable txtnama. It should be laid out like this:
tell application "Microsoft Excel"
-- Commands sent to Excel
end tell
tell application "Safari"
-- Commands sent to Safari (As above)
end tell
Is there a way to click OK button on system dialog from applescript? Currently I have made all my workflow on it and only closing that dialog part is missing.
Dialog appears on Safari app (since I make my script to work on Safari) when button "stop reminders" clicked via Javascript function. It's confirmation dialog for destructive action (stoping reminders).
clickId("stop reminders button id") --clicking on button I need
delay 2 -- making sure that dialog has enough time to appear
pressEnterButton() --just trying to close it
to clickId(theId)
tell application "Safari"
do JavaScript "document.getElementById('" & theId & "').click();" in document 1
end tell
end clickId
to pressEnterButton()
tell application "System Events"
keystroke return
end tell
end pressEnterButton
that's how I try to do it now, but it not works that way (it's sad, because when I press "enter" on keyboard, it works as it should and dismisses dialog).
Try this:
to pressEnterButton()
tell application "Safari" to activate
tell application "System Events"
tell application process "Safari"
keystroke return
end tell
end tell
end pressEnterButton
#ShooTeKo had a good point about wrapping the dialog part of the code in a
ignoring application responses block
This does work with your existing code.
I tested using a adjusted html - javascript code snippet from www.w3schools
( I added an id to the button. )
The html page to test on is:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to demonstrate the prompt box.</p>
<button id="myBtn" type="button"" onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
var person = prompt("Please enter your name", "Harry Potter");
if (person != null) {
document.getElementById("demo").innerHTML =
"Hello " + person + "! How are you today?";
}
}
</script>
</body>
</html>
And you code adjusted.
clickId("myBtn") --clicking on button I need
delay 2 -- making sure that dialog has enough time to appear
pressEnterButton() --just trying to close it
to clickId(theId)
tell application "Safari"
ignoring application responses
activate
do JavaScript "document.getElementById('" & theId & "').click()" in document 1
end ignoring
end tell
end clickId
to pressEnterButton()
tell application "System Events"
keystroke return
end tell
end pressEnterButton
While trying to make an automator action that opens multiple tabs from selected text as input I ran into an applescript issue I wasn't able to solve for awhile. This includes the answer and I'm posting this here because I just wasn't able to find documentation on how to handle data in "input" for a receives selected "text" in "any application" automator action, everything is for files which comes in as a list already.
When putting an applescript action in, you get:
on run {input, parameters}
the problem here is that input isn't in a list format and trying to do anything with it breaks the script or throws an error. ie I can't do:
repeat with URL in input
set this_URL to URL
So how can I treat a list of selected text as a list of items?
the solution is first treat input as a string then break apart every paragraph.
on run {input, parameters}
set inputText to input as string
set URL_list to every paragraph of inputText
Without treating input "as string" first before doing "every paragraph of" it won't work.
Here's the end working script, replace the "some_url" with your own. You'll be able to select several lines of text in an editor and treat each one as a parameter to your fixed url opening each in a new safari tab. This could be expanded upon by having each line be delimited for multiple params on the url.
on run {input, parameters}
set inputText to input as string
set URL_list to every paragraph of inputText
tell application "Safari"
activate
repeat with URL in URL_list
set this_URL to URL
# extra processing of URL could be done here for multiple params
my new_tab()
set tab_URL to "http://some_url.com?data=" & this_URL
set the URL of document 1 to tab_URL
end repeat
end tell
return input
end run
on new_tab()
tell application "Safari" to activate
tell application "System Events"
tell process "Safari"
click menu item "New Tab" of ¬
menu "File" of menu bar 1
end tell
end tell
end new_tab
As an example say you had the list and had a service of the above using "http://stackoverflow.com/posts/" & this_URL
6318162
6318163
6318164
you could now select them click services and choose your "StackOverflow - view questions" service and it'll append and open each one in a new safari tab. In my case I needed to verify multiple dns entries in our server as still valid and do a bunch of whois lookups.
I was looking for the same thing, just for files as input from Automator to AppleScript.
ddowns's trick didn't work for that, but ended up using this, hope it's helpful for someone looking for solving the same issue I ran into:
on run {input, parameters}
-- create empty list
set selectedFiles to {}
-- add each list item to the empty list
repeat with i in input
copy (POSIX path of i) to end of selectedFiles
end repeat
-- show each item (just for testing purposes of course)
repeat with currentFile in selectedFiles
display dialog currentFile as text
end repeat
end run
As Hanzaplastique says, for AppleScript within Automator, you don't need the Safari AppleScript because there's an Action for that. I use the following Actions:
Extract URLs from Text (actually the 'Extract Data from Text' Action)
Run AppleScript
Display Webpages
I use it as a Workflow added to the Services menu so that I can right-click on selected text in an email and open multiple URLs in Safari tabs.
In particular, I get Server / WordPress updates in an email but the URLs are just the top level of the domains and I want to jump to the plugins page of WordPress. So, my AppleScript (with thanks to Hanzaplastique) is:
on run {input, parameters}
set AppleScript's text item delimiters to {return & linefeed, return, linefeed, character id 8233, character id 8232}
-- create empty list
set selectedFiles to {}
-- add each list item to the empty list
repeat with i in input
set AppleScript's text item delimiters to {" "}
set i to i & "/wp-admin/plugins.php"
copy i to end of selectedFiles
end repeat
return selectedFiles
end run
I found I needed the 'return selectedFiles'. The always mysterious (to me) text delimiters may not be necessary and come from the previous version which only pulled out a single URL.
I have followed this youtube tutorial: http://www.youtube.com/watch?v=0ux3S_G8HuU
I want the second button go to a special website....
I have tried this:
if "button 2" then open location "(the name of the site)"
What do I do? I hope you can help.
Try this:
set search to (display dialog "Enter YouTube Video Search" default answer "" buttons {"Cancel", "Search", "Search2"} default button 3)
set keyword to text returned of search
set buttonPressed to button returned of search
if buttonPressed is equal to "Search" then
tell application "Safari"
open location "http://www.youtube.com/results?search_query=" & keyword
end tell
else if buttonPressed is equal to "Search2" then
tell application "Safari"
open location "http://www.youtube.com/results?search_query=" & keyword
end tell
end if
Just change the URLs to whatever you want for Search or Search2.