A subroutine for Safari to pause a script until a web page has loaded

Over the last month I’ve been teaching myself applescript and I found this website very helpful so I wanted to give something back.

This script is a subroutine you can call to pause your script until a web page in Safari has fully loaded. The script will watch the page for a predetermined amount of time. Once the web page fully loads the script will exit. If the web page hasn’t fully loaded in the predetermined time then the script will stop the page from loading and try to reload the page. It will go through this watch/wait/stop/reload process 3 times until the script will tell you that the web page couldn’t load.

As such, there’s 2 variables at the top of the script which you can customize. 1) “theDelay” which is the amount of time in seconds the script will watch for the web page to load until the stop/reload cycle starts. 2) “numTries” which is the number of times the stop/reload cycles before the script gives up.

This script works because I noticed that when a web page is loading Safari names the window with the word “Loading” while the web page is loading. Once a web page has loaded the word “Loading” goes away. So the script looks for this word and waits until it goes away.


on web_page_loading()
	set theDelay to 10 -- the time in seconds the script will wait to let a web page load
	set numTries to 3 -- the number of stop/reload cycles before giving up
	set myCounter to 0
	set finished to false
	repeat until finished is true
		set myCounter to myCounter + 1
		set my_delay to 0.25
		set startTime to current date
		set endTime to startTime + theDelay
		set web_page_is_loaded to false
		delay my_delay
		tell application "Safari"
			activate
			repeat until web_page_is_loaded is true
				if endTime is greater than (current date) then -- only wait theDelay seconds for a web page to load otherwise stop the page loading and try to reload again
					if name of window 1 contains "Loading" or name of window 1 contains "Untitled" or name of window 1 contains "Failed to open page" then
						delay my_delay
					else
						set web_page_is_loaded to true
						set finished to true
						delay my_delay
					end if
				else
					tell application "System Events"
						tell process "Safari"
							if myCounter is numTries then -- give up if the page doesn't load after numTries stop/reload cycles
								keystroke "." using command down -- stop the page
								delay my_delay
								tell application "Finder"
									activate
									display dialog "The web page will not load!"
								end tell
								set connected to true -- a global variable which will stop this script if there's a problem
								set web_page_is_loaded to true
								set finished to true
								tell application "Safari" to activate
							else
								keystroke "." using command down -- stop the page
								delay my_delay
								keystroke "r" using command down -- reload the page
								delay my_delay
								set web_page_is_loaded to true
							end if
						end tell
					end tell
				end if
			end repeat
		end tell
	end repeat
end web_page_loading

Model: PM dual 2.0 GHz G5
AppleScript: AppleScript 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

Hi

here is a different solution from Apple using “do Javascript”:

on page_loaded(timeout_value) – in seconds
delay 2
repeat with i from 1 to timeout_value
tell application “Safari”
if (do JavaScript “document.readyState” in document 1) is “complete” then
return true
else if i is timeout_value then
return false
else
delay 1
end if
end tell
end repeat
return false
end page_loaded

Yes, I saw that solution when I was searching these forums, but it didn’t do all the stuff I wanted it to do… so I wrote my own. First, it did some weird things when I was testing it such as in a few instances it successfully completed when a web page failed to load, so it wasn’t always reliable. Second I didn’t want to use a javascript solution when I could just check for the name “Loading” in the window title. Third, I wanted to also check for window titles of “Untitled” and “Failed to open page” which it can’t. Fourth it doesn’t have any of the stop/reload cycles which I wanted because sometimes you can get a web page to load by stopping and reloading it. Bottom line is that solution didn’t work for me.

Hi,

I have tried using the window names as suggested by regulus6633, but ran into issues if I tried running the AppleScript anywhere other than an English locale (since
“Loading”, “Untitled”, are all localized).

I have been looking for an alternative to the “do JavaScript document.readyState” as it is not very reliable, and does not work all the time. It appears that sometimes if the “do JavaScript document.readyState” is executed while the page is in transition (like a redirect), the script just stops and Safari just shows a blank page!

I’d be interested to hear if anyone has successfully gotten an AppleScript working that waits until Safari has loaded a web page.

The 1st solution doesn’t work with none English local, the 2nd doesn’t work if JavaScript is disabled in Develop menu (of browser) and doesn’t stable for few reasons.
So, I like more the following solution:

For Safari:


tell application "Safari" to make new document with properties ¬
	{URL:"https://www.macscripter.net/viewtopic.php?id=19262"}
my waitSafariWebPageLoading()
display dialog "The webpage is fully loaded now."

on waitSafariWebPageLoading()
	tell application "System Events" to tell application process "Safari"
		repeat until (UI element "Reload this page" of group 2 of toolbar 1 of window 1 exists)
			delay 0.1
		end repeat
	end tell
end waitSafariWebPageLoading