Chrome pageLoad handler recursion

I am trying to write a handler which will wait for page to load using both chrome loading property and javascript. If the page exceeds maxWaitSeconds, I want to refresh the page and have the handler call itself again, limiting the refresh attempts to three times. After third attempt fails, return an error.

Thanks for the fresh eyes/brain!

on waitForPageLoad(maxWaitSeconds)
	set startTime to (current date)
	delay 0.5
	
	tell application "Google Chrome"
		tell window 1 to tell active tab
			
			set tryCount to 0
			repeat until not loading
				delay 0.2
				set tryCount to tryCount + 1
				if tryCount mod 5 = 0 then
					set nowTime to (current date)
					if nowTime - startTime ≥ maxWaitSeconds then
						set currentUrl to URL
						error "Page took to long to load"
					end if
				end if
			end repeat
			
			repeat
				set readyState to execute javascript "document.readyState"
				if readyState = "complete" then exit repeat
				log readyState
				delay 0.5
			end repeat
			
		end tell
	end tell
end waitForPageLoad

I don’t know how to tell Chrome to refresh the page, but for the recursion, the idea would be for the handler to have a countdown parameter. Pass the value 3 on the initial call. If the page hasn’t loaded within the time limit, the handler should decrement the countdown and call itself with the new value ” unless the value would be below 1, in which case the error should be thrown instead.

on waitForPageLoad(maxWaitSeconds, tryCountdown)
	set startTime to (current date)
	delay 0.5
	
	tell application "Google Chrome"
		tell window 1 to tell active tab
			
			set tryCount to 0
			repeat until not loading
				delay 0.2
				set tryCount to tryCount + 1
				if tryCount mod 5 = 0 then
					set nowTime to (current date)
					if nowTime - startTime ≥ maxWaitSeconds then
						if (tryCountdown > 1) then
							-- Do refresh action here, then:

							my waitForPageLoad(maxWaitSeconds, tryCountdown - 1)
						else
							set currentUrl to URL
							error "Page took too long to load"
						end if
					end if
				end if
			end repeat
			
			repeat
				set readyState to execute javascript "document.readyState"
				if readyState = "complete" then exit repeat
				log readyState
				delay 0.5
			end repeat
			
		end tell
	end tell
end waitForPageLoad

Hi Nigel. Thanks.

I had added the tryCount to avoid script having to do date math every .2 seconds. However, it still has to go the incrementing tryCount and evaluating tryCount mod 5. Do you think it makes more sense to simply use the second script below?

on waitForPageLoad(maxWaitSeconds, tryCountdown)
	set {longDelay, shortDelay} to {0.5, 0.2}
	set startTime to (current date)
	delay longDelay
	
	tell application "Google Chrome"
		tell window 1 to tell active tab
			set currentUrl to URL
			
			set tryCount to 0
			repeat until not loading
				delay shortDelay
				set tryCount to tryCount + 1
				if tryCount mod 5 = 0 then
					set nowTime to (current date)
					if nowTime - startTime ≥ maxWaitSeconds then
						if (tryCountdown > 1) then
							set URL to currentUrl
							my waitForPageLoad(maxWaitSeconds, tryCountdown - 1)
						else
							error "Page took too long to load"
						end if
					end if
				end if
			end repeat
			
			repeat
				set readyState to execute javascript "document.readyState"
				if readyState = "complete" then exit repeat
				log readyState
				delay longDelay
			end repeat
			
		end tell
	end tell
end waitForPageLoad
on waitForPageLoad(maxWaitSeconds, tryCountdown)
	set {longDelay, shortDelay} to {0.5, 0.2}
	set startTime to (current date)
	delay longDelay
	
	tell application "Google Chrome"
		tell window 1 to tell active tab
			set currentUrl to URL
			
			repeat until not loading
				delay shortDelay
				set nowTime to (current date)
				if nowTime - startTime ≥ maxWaitSeconds then
					if (tryCountdown > 1) then
						set URL to currentUrl
						my waitForPageLoad(maxWaitSeconds, tryCountdown - 1)
					else
						error "Page took too long to load"
					end if
				end if
			end repeat
			
			repeat
				set readyState to execute javascript "document.readyState"
				if readyState = "complete" then exit repeat
				log readyState
				delay longDelay
			end repeat
			
		end tell
	end tell
end waitForPageLoad

Hi John.

Another way to handle the elapsed times would be simply to augment a variable by the lengths of the delays. The inaccuracy probably wouldn’t be any worse than using ‘current date’.

on waitForPageLoad(maxWaitSeconds, tryCountdown)
	set {longDelay, shortDelay} to {0.5, 0.2}
	delay longDelay
	set elapsedTime to longDelay
	
	tell application "Google Chrome"
		tell window 1 to tell active tab
			set currentUrl to URL
			
			repeat until not loading
				delay shortDelay
				set elapsedTime to elapsedTime + shortDelay
				if (elapsedTime ≥ maxWaitSeconds) then
					if (tryCountdown > 1) then
						set URL to currentUrl
						my waitForPageLoad(maxWaitSeconds, tryCountdown - 1)
					else
						error "Page took too long to load"
					end if
				end if
			end repeat
			
			repeat
				set readyState to execute javascript "document.readyState"
				if readyState = "complete" then exit repeat
				log readyState
				delay longDelay
			end repeat
			
		end tell
	end tell
end waitForPageLoad