Automator error when running Watch Me Do-created script

Hi everyone,

I'm trying to use Automator to batch process PDF files. I have hundreds of academic journal article PDFs whose page sizes vary from 5x7 inches to A4 format (8.27 x 11.69 inches). I want to scale all the PDFs to US Letter size (8.5 x 11.0 inches) such that smaller originals remain 100% scale but are centered on the larger page and larger originals are scaled down to fit the page.

Manually opening a PDF in Preview.app, scaling it to US Letter paper, and using the Save as PDF option is producing the desired output for me. I captured my workflow using the Watch Me Do action in Automator, then adjusted it into the following AppleScript.

-- a Get Specified Finder Items action to specify the input PDFs precedes this script

on run {input, parameters}
	repeat with filePath in input
		-- Open the file in Preview
		tell application "Preview"
			open filePath
			activate
		end tell
		
		-- Give Preview some time to open the file
		delay 2.0
		
		-- Press ⌘P
		set timeoutSeconds to 0.25
		set uiScript to "keystroke \"p\" using command down"
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “Scale to Fit:” radio button.
		delay 2.0
		set timeoutSeconds to 2.0
		set uiScript to "click radio button \"Scale to Fit:\" of radio group 1 of group 1 of group 2 of scroll area 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “<fill in title>” menu button.
		delay 4.0
		set timeoutSeconds to 2.000000
		set uiScript to "click menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout( uiScript, timeoutSeconds )
	
		-- Save as PDF…
		delay 2.0
		set timeoutSeconds to 2.0
		set uiScript to "click menu item 2 of menu 1 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “Save” button.
		delay 8.0
		set timeoutSeconds to 2.0
		set uiScript to "click UI Element \"Save\" of sheet 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Press ⌘W to close the file
		delay 0.25
		set timeoutSeconds to 2.0
		set uiScript to "keystroke \"w\" using command down"
		my doWithTimeout(uiScript, timeoutSeconds)
	end repeat
	return input
end run

on doWithTimeout(uiScript, timeoutSeconds)
	set endDate to (current date) + timeoutSeconds
	repeat
		try
			run script "tell application \"System Events\"
" & uiScript & "
end tell"
			exit repeat
		on error errorMessage
			if ((current date) > endDate) then
				error "Can not " & uiScript
			end if
		end try
	end repeat
end doWithTimeout

My problem arises at the Save as PDF step. When this action runs, I see the PDF menu pop open:

but the Save as PDF... menu item doesn't get clicked. Instead, I get an error:

Can anyone advise on how to overcome this error?

Answered by DTS Engineer in 825838022

It's tricky trying to figure out the proper GUI scripting path for accessing items in the menu. I was able avoid the issue all together by accessing the menu item using two down arrow keystrokes followed by an enter keystroke. Here's the modified script:

on run {input, parameters}
	
	repeat with filePath in input
		-- Open the file in Preview
		tell application "Preview"
			open filePath
			activate
		end tell
		
		-- Give Preview some time to open the file
		delay 2.0
		
		-- Press ⌘P
		tell application "System Events"
			tell process "Preview"
				keystroke "p" using command down
			end tell
		end tell

		-- set timeoutSeconds to 0.25
		-- set uiScript to "keystroke \"p\" using command down"
		-- my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “Scale to Fit:” radio button.
		delay 2.0
		set timeoutSeconds to 2.0
		set uiScript to "click radio button \"Scale to Fit:\" of radio group 1 of group 1 of group 2 of scroll area 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “<fill in title>” menu button.
		delay 4.0
		set timeoutSeconds to 2.0
		set uiScript to "click menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Save as PDF…
		delay 2.0
		set timeoutSeconds to 2.0
		
		
		set uiScript to "click menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- type down arrow twice
		tell application "System Events"
			tell process "Preview"
				keystroke (ASCII character 31) -- type a down arrow
				-- note, 'keystroke (ASCII character 31)' is the same as 'key code 125'
			end tell
		end tell
		delay 0.1
		tell application "System Events"
			tell process "Preview"
				keystroke (ASCII character 31) -- type a down arrow
			end tell
		end tell
		delay 0.1
		
		-- type the enter key
		tell application "System Events"
			tell process "Preview"
				keystroke (ASCII character 13) -- type a return
				-- note, 'keystroke (ASCII character 13)' is the same as 'key code 36'
			end tell
		end tell
		delay 0.1
		
		--set uiScript to "select menu item 2 of menu 1 of menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		--my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “Save” button.
		delay 8.0
		set timeoutSeconds to 2.0
		set uiScript to "click UI Element \"Save\" of sheet 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Press ⌘W to close the file
		delay 0.25
		set timeoutSeconds to 2.0
		set uiScript to "keystroke \"w\" using command down"
		my doWithTimeout(uiScript, timeoutSeconds)
	end repeat
	return input
end run


on doWithTimeout(uiScript, timeoutSeconds)
	set endDate to (current date) + timeoutSeconds
	repeat
		try
			run script "tell application \"System Events\"
" & uiScript & "
end tell"
			exit repeat
		on error errorMessage
			if ((current date) > endDate) then
				error "Can not " & uiScript
			end if
		end try
	end repeat
end doWithTimeout

note, I made some minor changes to the ⌘P part to get it working over here at this end. I had this working on Sequoia 15.3.1 (24D70).

It's tricky trying to figure out the proper GUI scripting path for accessing items in the menu. I was able avoid the issue all together by accessing the menu item using two down arrow keystrokes followed by an enter keystroke. Here's the modified script:

on run {input, parameters}
	
	repeat with filePath in input
		-- Open the file in Preview
		tell application "Preview"
			open filePath
			activate
		end tell
		
		-- Give Preview some time to open the file
		delay 2.0
		
		-- Press ⌘P
		tell application "System Events"
			tell process "Preview"
				keystroke "p" using command down
			end tell
		end tell

		-- set timeoutSeconds to 0.25
		-- set uiScript to "keystroke \"p\" using command down"
		-- my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “Scale to Fit:” radio button.
		delay 2.0
		set timeoutSeconds to 2.0
		set uiScript to "click radio button \"Scale to Fit:\" of radio group 1 of group 1 of group 2 of scroll area 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “<fill in title>” menu button.
		delay 4.0
		set timeoutSeconds to 2.0
		set uiScript to "click menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Save as PDF…
		delay 2.0
		set timeoutSeconds to 2.0
		
		
		set uiScript to "click menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- type down arrow twice
		tell application "System Events"
			tell process "Preview"
				keystroke (ASCII character 31) -- type a down arrow
				-- note, 'keystroke (ASCII character 31)' is the same as 'key code 125'
			end tell
		end tell
		delay 0.1
		tell application "System Events"
			tell process "Preview"
				keystroke (ASCII character 31) -- type a down arrow
			end tell
		end tell
		delay 0.1
		
		-- type the enter key
		tell application "System Events"
			tell process "Preview"
				keystroke (ASCII character 13) -- type a return
				-- note, 'keystroke (ASCII character 13)' is the same as 'key code 36'
			end tell
		end tell
		delay 0.1
		
		--set uiScript to "select menu item 2 of menu 1 of menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
		--my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Click the “Save” button.
		delay 8.0
		set timeoutSeconds to 2.0
		set uiScript to "click UI Element \"Save\" of sheet 1 of sheet 1 of window 1 of application process \"Preview\""
		my doWithTimeout(uiScript, timeoutSeconds)
		
		-- Press ⌘W to close the file
		delay 0.25
		set timeoutSeconds to 2.0
		set uiScript to "keystroke \"w\" using command down"
		my doWithTimeout(uiScript, timeoutSeconds)
	end repeat
	return input
end run


on doWithTimeout(uiScript, timeoutSeconds)
	set endDate to (current date) + timeoutSeconds
	repeat
		try
			run script "tell application \"System Events\"
" & uiScript & "
end tell"
			exit repeat
		on error errorMessage
			if ((current date) > endDate) then
				error "Can not " & uiScript
			end if
		end try
	end repeat
end doWithTimeout

note, I made some minor changes to the ⌘P part to get it working over here at this end. I had this working on Sequoia 15.3.1 (24D70).

Automator error when running Watch Me Do-created script
 
 
Q