Finding a text field on a webpage only works if run manually

A script I recently developed to log in to a particular website worked reliably in Sonoma 14.0 and 14.1, but has issues in an unreleased version of Sonoma. If I open the script and run it manually in Script Debugger, it works. If I run it remotely using on run … end run, it fails. Attached is the problematic portion of the script which is intended to identify and select “text field 1” where my user ID will be entered. Assume the front window of Safari is the login page for the website.

Any ideas what is going on?

activate application "Safari"
tell application "System Events" to tell application process "Safari"
	set found to false
	repeat with i from 5 to 7
		repeat with j from 4 to 6
			try
				set listItems to UI elements of group j of group i of UI element 1 ¬
					of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 as list
				repeat with k from 1 to length of listItems
					if (class of item k of listItems as text) is "text field" then
						set focused of (text field 1 of group j of group i of UI element 1 ¬
							of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1) to true
						set found to true
						exit repeat
					end if
				end repeat
			end try
			if found then exit repeat
		end repeat
		if found then exit repeat
	end repeat
end tell

It would be helpful if you posted the webpage url

Thanks. It did occur to me after posting.

https://www.cibc.com/en/personal-banking.html

More info:
The script runs properly if run remotely from another Script Debugger script, but not from Butler or Keyboard Maestro.

That led me to a workaround, which is to run a simple script from Butler which in turn runs the original script presented here. Hopefully this is fixed in the Sonoma 14.2 release.

Thanks for having a look.

I don’t see a field to enter a User ID. Only a Card Number & a Password field.

Also your script gets all the UI Elements of group j. It will exit the loop after the first text field. According to your script is the field you want always the first text field?

I also cleaned it up a little.

activate application "Safari"
tell application "System Events" to tell application process "Safari"
	set found to false
	repeat with i from 5 to 7
		repeat with j from 4 to 6
			try -- why get all UI Elements when you are only interested in the text fields
				set listItems to text fields of group j of group i of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 as list
				repeat with anItem in listItems
					set anItem to contents of anItem
					set focused of anItem to true
					set found to true
					exit repeat
				end repeat
			end try
			if found then exit repeat
		end repeat
		if found then exit repeat
	end repeat
end tell

Here is another version that will verify that the Static text right before the text field I want is “Card number”

activate application "Safari"
tell application "System Events" to tell application process "Safari"
	set found to false
	repeat with i from 5 to 7
		repeat with j from 4 to 6
			try
				set listItems to UI elements of group j of group i of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 as list
				repeat with k from 1 to count listItems
					set anItem to item k of listItems
					if found then -- Card number was found
						if class of anItem = text field then
							set focused of anItem to true
							set value of anItem to "1234567845687451"
							exit repeat
						end if
					else -- search for Card number
						if class of anItem = static text then
							if value of anItem = "Card number" then
								set found to true
							end if
						end if
					end if
				end repeat
			end try
			if found then exit repeat
		end repeat
		if found then exit repeat
	end repeat
end tell

And here is another version that will do both the “Card Number” & “Password” fields…

activate application "Safari"
tell application "System Events" to tell application process "Safari"
	set found to false
	set fieldlist to {{"Card number", "1234567845687451"}, {"Password", "mypassword"}}
	set k to 1
	repeat with i from 5 to 7
		repeat with j from 4 to 6
			try
				set listItems to UI elements of group j of group i of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 as list
				repeat with anItem in listItems
					set anItem to contents of anItem
					if found then -- field k in fieldlist was found
						if class of anItem = text field then
							set focused of anItem to true
							set value of anItem to item 2 of item k of fieldlist
							if k < (count fieldlist) then
								set found to false
								set k to k + 1
							else
								exit repeat
							end if
						end if
					else -- search for field k in fieldlist
						if class of anItem = static text then
							if value of anItem = item 1 of item k of fieldlist then set found to true
						end if
					end if
				end repeat
			end try
			if found then exit repeat
		end repeat
		if found then exit repeat
	end repeat
end tell

Sorry, yes it’s Card Number, not User ID. I only need the first text field since I can then tab to the Password field.

I tend to only use AppleScript to accomplish what I want. If it works, it’s done, rather than thinking much about its efficiency or good coding. A lazy coder for sure, but that comes with reliability risks such as this example.

I truly appreciate your cleanup of my code, which is now lightening fast, and runs properly directly from Butler. I will save the second and third versions in case one is ever needed, and try to learn from them.

Thanks for your outstanding help, Robert !