3

I am trying to create a script to open the URL csbsju.instructure.com in Safari, wait for the page to load all the way, click the login button, and then double check if the URL is correct (there's a bug that adds dashboard-sidebar, so I'm just checking the URL and if it's incorrect, redirecting the page. The typing of credentials is handled by Safari's iCloud Password thing, so I don't need to worry about that. The big issue I'm having is the waiting till page is loaded part. I've been looking around, and currently am attempting to use this code, although it does not work:

tell application "Safari"
    activate
    delay 1
    repeat
        if (do JavaScript "document.readyState" in document 1) is "complete" then exit repeat
        delay 1
    end repeat
    delay 1
end tell

I'm currently using this script to click the login button and check if the URL is correct:

tell application "Safari"
    set theURL to URL of front document



    tell front document
        do JavaScript "document.getElementById('btnLogin').click()"
    end tell

    set theURL to URL of front document
    if (theURL = "https://csbsju.instructure.com/dashboard-sidebar") then
        tell application "Safari" to set the URL of the front document to "https://csbsju.instructure.com"
    end if
end tell

Any suggestions on how to make this work better? Namely the checking if page is loaded part?

3

There are a few methods you could use to check whether the page has finished loading. Here are a selection that I've had good results with during testing:

Document name

Monitor for the existence of the Safari document that has the same name as the title of the webpage, which (I believe) only gets assigned after the page has finished loading, up until which point it retains the name it had previously, or "Untitled" if it's a newly created document:

tell application "Safari"
    make new document with properties {URL:"https://csbsju.instructure.com"}

    repeat until the document named ("Central Authentication Service " & ¬
        "| College of Saint Benedict & Saint John's University") exists
    end repeat

    log "Finished loading"
end tell

The Login button

Monitor for the existence of the "Login" button, given that you can't do what you need to do until that particular HTML element has been created:

tell application "Safari"
    make new document with properties {URL:"https://csbsju.instructure.com"}

    tell front document to repeat until (do JavaScript ¬
        "document.getElementById('btnLogin').id") as text is not ""
    end repeat

    log "Finished loading"
end tell

Safari's Reload button

Monitor particular properties of Safari's Reload button, which changes according to whether a page is loading or has loaded:

Note: This was written and tested under macOS High Sierra; however, for macOS Mojave one minor edit is required. Change UI element 1 to ¬ to UI element 2 to ¬ in the code directly below.

tell application "Safari" to ¬
    make new document with properties {URL:"https://csbsju.instructure.com"}

tell ¬
    application "System Events" to tell ¬
    process "Safari" to tell ¬
    window 1 to tell ¬
    toolbar 1 to tell ¬
    groups to tell ¬
    UI element 1 to ¬
    set reload_button to a reference to ¬
        (first button whose name is "Reload this page")

using terms from application "System Events"
    repeat until the accessibility description ¬
        of the reload_button ¬
        contains "Reload this page"
    end repeat
end using terms from

log "Finished loading"

Page content

Monitor for specific text to appear within the page content. In this case, I've chosen to monitor for all of it, but you can choose smaller elements instead. Items that appear towards the end of the page are most suitable:

tell application "Safari"
    make new document with properties {URL:"https://csbsju.instructure.com"}

    ignoring white space
        tell front document to repeat until its text contains ¬
            "Central Authentication Service Network Username: " & ¬
            "Password: Warn me before logging me into other sites. " & ¬
            "Copyright © 2017 - All Rights Reserved College of Saint " & ¬
            "Benedict and Saint John's University"
        end repeat
    end ignoring

    log "Finished loading"
end tell

Username & Password fields

Since these fields are getting filled out automatically by Safari's password manager—which only happens when the page has fully loaded—you can monitor the text content of the Username and Password fields:

tell application "Safari"
    make new document with properties {URL:"https://csbsju.instructure.com"}

    tell front document to repeat
        set a to (do JavaScript "document.getElementById('username').value") as text
        set b to (do JavaScript "document.getElementById('password').value") as text

        if length of (a & b) ≠ 0 then exit repeat
    end repeat

    log "Finished loading"
end tell
  • You've covered the bases nicely, I've use both the login and reload button in some of my scripts and find those methods quite solid for my usage. I'd suggest adding a delay command within the repeat loops. Without, hundreds of needless calls can be made wasting CPU cycles causing the fans to spin up, where the use of a delay can cut it down to a few or so calls. The reload button code looped 295 time as written, and 5 times with a delay 1 added. This will of course vary considerably depending on the overall load on the system how fast the system is and how fast the connection is. – user3439894 Mar 23 '18 at 21:31
  • @user3439894 Yes, you're right, and I am aware of this. I think I still haven't found my footing with regards to expressing a disclaimer that these are illustrative scripts to demonstrate a method. I notice you always describe your contributions as example scripts, and have a solid addendum stating that error-handling and delays may be necessary at the user's discretion, etc. I need to be more consistent in doing the same. – CJK Mar 23 '18 at 22:05
  • 1
    CJK, I've edited your answer, adding a note in the "Safari's Reload button" section for use under macOS Mojave. – user3439894 Jul 2 at 14:47
  • @user3439894 Thank you for doing this. That's very attentive of you. – CJK Jul 14 at 5:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .