Click Button on Web Page

The url is https://www.dividend.com/login/?redirect_url=/login. That as you would expect brings up the login page. I see I left both user name and password in my post that described the part that worked. I will change the password.

I may not have explained myself but what you did in your example
set anElement to UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 of anElement

is what I have been doing and I am trying to avoid GUI scripting as some parts change . I have been using UI Browser to get the GUI portion of the script but that adds time to the process every time something changes .

The part of the script that adds the input vales in this case username and password works what does not work is cling the “Log in” button. I could use GUI for this but the page I was using was to show the issue it gets a lot more complicate at least for me when I need to access a drop down list in say a footer or an item in a drop down list which itself is part of another drop down list.

I apologise if this all sounds unwieldy but Dividend.com often changes its site layout. Also I may be using terms incorrectly. But it seems to me if I can enter data into boxes on a website it should be relatively simple to click on another box using Javascript

thanks

What happens if you use the button class?

to clickClassName(theClassName, elementnum)
	tell application "Safari"
		do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
	end tell
end clickClassName

set cn to "t-w-full t-mt-2 t-bg-indigo-775 hover:t-bg-indigo-750 t-text-white t-font-semibold t-p-3 t-rounded"

clickClassName(cn, 0)

This works for me, and it’s the same approach as mockman’s.

clickClassName("t-w-full t-mt-2 t-bg-indigo-775 hover:t-bg-indigo-750 t-text-white t-font-semibold t-p-3 t-rounded", 0)

to clickClassName(theClassName, elementnum)
	tell application "Safari"
		activate
		do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
	end tell
	
end clickClassName

I know you’re not interested, but I had fun getting a GUI version to work.

Here is my sample

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

local UIElements, i, anElement, subElements, loginPane, anItem, emailFlag, pwdFlag

tell application "System Events"
	set anElement to application process "Safari"
	set anElement to UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 of anElement
	
	set subElements to groups of anElement whose subrole is "AXLandmarkMain"
	repeat with i in subElements
		set i to contents of i
		if (subrole of i) = "AXLandmarkMain" then
			set loginPane to i
			exit repeat
		end if
	end repeat
	try
		get loginPane
	on error
		return false
	end try
	set emailFlag to false
	set subElements to groups of loginPane whose subrole is not "AXEmptyGroup"
	repeat with i in subElements -- finds the Email group
		set i to contents of i
		if (static text 1 of i) exists then
			if (value of static text 1 of i) = "Email" then
				set anItem to text field 1 of i
				set focused of anItem to true
				tell me to delay 0.2
				set value of anItem to some item of "email@domain.com"
				set emailFlag to true
			end if
			if emailFlag then -- refresh screen to remove optional 'This field is required' notice
				set focused of text field 1 of i to true
				tell me to delay 0.2
				exit repeat
			end if
		end if
	end repeat
	set pwdFlag to false
	set subElements to groups of loginPane whose subrole is not "AXEmptyGroup"
	repeat with i in subElements -- finds the Password group
		set i to contents of i
		if (static text 1 of i) exists then
			if (value of static text 1 of i) = "Password" then
				set anItem to text field 1 of i
				set focused of anItem to true
				tell me to delay 0.2
				set value of anItem to my "mypwd"
				set pwdFlag to true
			end if
		end if
		if pwdFlag then exit repeat
	end repeat
	if emailFlag and pwdFlag then
		repeat with i in subElements -- finds the Login button
			set i to contents of i
			if (button "Log in" of i) exists then
				tell button "Log in" of i to perform action "AXPress"
				exit repeat
			end if
		end repeat
	end if
end tell

hi all

Sorry no response been in hospital for a couple days will get back to this shortly

Back on deck thanks again for all the help. Stockly & Mockman got me there.

The class name approach worked I had thought just the name of the button would work but it requires more precision . For me at least a lot easier to get to than using a GUI approach.

Peter

robertfern

Sorry I failed to acknowledge your GUI approach, thank you. I have been using UI browser to create the GUI part of my script. The web pages in Dividend.com have so many items and sub pages it takes for ever to locate the item I want and when it changes I have to start over again.

Having got past the login page with help from this forum I ma working on trying to access items on a sub page so far no luck.

Thanks again for all the help.

Peter

So, on the browser page with the item you’re trying to access, try this:

Right-click (or control-click) on the item you want to access. Select “inspect” (or “Inspect Element”).

A new pane will open in your safari window (if it’s not already there) and the “Elements” tab will be active, and some portion of the HTML will be selected.

Copy that text.

Run the first script below in your script editor.

A Choose from List dialog will appear and show you the options for addressing that element.

By ID is preferred. If you use name, class name, etc. you’ll also need to provide a number. (The default is 0 for the first instance)

Select the ones you want to try, and paste them into the second script below (after the use statement).

That has the appropriate JavaScript handlers to click an element.

Uncomment handler calls for the method(s) you selected and pasted in above.

See if that works. (If you want to do more than click the element I may have a handler for that too.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

 set elementStuff to the clipboard

set clipboardText to ParseElementInspector(elementStuff)
set userSelection to choose from list clipboardText ¬
	with title ("Element Name, Id or Class") ¬
	with prompt ("Sected variable(s) for this element to copy/paste into your script") ¬
	default items 1 ¬
	OK button name ¬
	"Okay" cancel button name ¬
	"Cancel" multiple selections allowed true ¬
	with empty selection allowed
if userSelection is not in {false, {}} then
	
	set saveTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {return & return}
	set clipboardText to clipboardText as text
	set AppleScript's text item delimiters to saveTID
	set the clipboard to clipboardText
end if

on ParseElementInspector(elementInfo)
	set elementInfoText to {}
	set saveTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {" name="}
	set nameElements to text items of elementInfo
	if the (count of nameElements) > 1 then
		set elementName to text item 2 of nameElements
		set AppleScript's text item delimiters to {"\""}
		set elementName to text item 2 of elementName
		set the end of elementInfoText to "set theName to \"" & elementName & "\""
	end if
	set AppleScript's text item delimiters to {" id="}
	
	set idElements to text items of elementInfo
	if the (count of idElements) > 1 then
		set elementID to text item 2 of idElements
		set AppleScript's text item delimiters to {"\""}
		set elementID to text item 2 of elementID
		set the end of elementInfoText to "set theId to \"" & elementID & "\""
	end if
	
	set AppleScript's text item delimiters to {" class="}
	set classElements to text items of elementInfo
	if the (count of classElements) > 1 then
		set elementClass to text item 2 of classElements
		set AppleScript's text item delimiters to {"\""}
		set elementClass to text item 2 of elementClass
		set the end of elementInfoText to "set theClass to \"" & elementClass & "\""
	end if
	set AppleScript's text item delimiters to saveTID
	return elementInfoText
end ParseElementInspector

Handler Script


use scripting additions

set the elementNumber to 0
--set theScript to JSForClickByID(theId)
--set theScript to JSForClickByName(theName, elementnum)
--set theScript to JSForClickByClassName(theClassName, elementnum)
--set theScript to JSForClickBytagName(thetagName, elementnum)

tell application "Safari"
	activate
	set safariJSScriptResults to do JavaScript " " & theScript in current tab of window 1
end tell

to JSForClickByID(theId)
	return " document.getElementById('" & theId & "').click();"
end JSForClickByID

to JSForClickByName(theName, elementnum)
	return " document.getElementsByName('" & theName & "')[" & elementnum & "].click();"
end JSForClickByName

to JSForClickByClassName(theClassName, elementnum)
	return " document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();"
end JSForClickByClassName

to JSForClickBytagName(thetagName, elementnum)
	return " document.getElementsByTagName('" & thetagName & "')[" & elementnum & "].click();"
end JSForClickBytagName


NOTE: These two snippets are from a JavaScriptBrowser library I’m working on. When it’s ready I’ll share if anyone’s interested.

Hi eStockly

I know I must be thick but I just cannot follow your I instructions properly.

When I select the box with the Ex-Div date I get this

Run the 1st routine and use selection is

Clipboard text is

I am sure I am not making this very clear. But I cannot copy the data from the listbox it just beeps but even if I could not sure where to put the result.

My apologies

It’s not you, it’s the script. It is definitely a work in progress, but I think you gave me some useful information.

What were looking for in doing the Inspect Element right-click is a way to identify the object. In this case it’s a button we want to click.

It’s best to use ID (because those are unique and you don’t need an element number).

In this case we have a class we can identify it with. The class a long and complicated name, but that makes it more likely it will be the right one, in my experience.

Try running this script with that page open in Safari.

If it clicks a button, but not the right button, you’ll need to try different numbers for the element number (1, 2, 3, etc.)

If it doesn’t work at all we can try something else.


 set theClassName to "t-py-3 t-mr-2 t-mb-2 t-w-max t-px-3 t-text-black hover:t-bg-mitre-gray-200 t-text-sm t-flex t-items-center t-relative t-min-w-150 t-justify-between"

set the elementNumber to 0
set theScript to JSForClickByClassName(theClassName, elementnum)

tell application "Safari"
	activate
	set safariJSScriptResults to do JavaScript " " & theScript in current tab of window 1
end tell

to JSForClickByClassName(theClassName, elementnum)
	return " document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();"
end JSForClickByClassName


Do you have an example of using xPath?

Ideally you would use the “id” of an element, but when that is not available you use name, classname, etc. with the element number. It does take trial and error to get right, and is vulnerable to the page layout changing, but as far as I know all schemes like this are.

Using the element number is also vulnerable to a page loading different HTML elements contextually, but (so far) I’ve found when they do that the elements I need generally have an ID.

Hi elstockly

That worked once I got the right element number “4” ,as you may have thought that produces a drop down box that needs a start and end date they have to be selected from calendars that appear when the drop down box is activated . Cannot write the dates one has to select. When was using GUI I selected the next 7 days.

So now I have to loop your solution to opening the drop down box then get the date selection. I do not know how to use xpath so I figured I would loop until I had the name of the box. That may be giving me work than I need absent xpath so if there is a link to that it would be appreciated .

thanks again for all the help this site is the best.

Peter

Irrelevant but this was how I got the dates suing GUI

on NewStocks()
	log "In NewStocks"
	set {TodaysDate, Date1, cnt, Cnt2, CheckSYM, GrpNo} to {day of (current date), "", 0, 0, "", 20}
	tell application "System Events" to tell process "Safari"
		--Open "All Filters" box so dates can be set
		set RefEnd to UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1
		repeat until CheckSYM is "Stocks"
			set GrpNo to GrpNo + 1
			try --Using "Stocks" as the button has a name and the filter button does not
				set CheckSYM to get name of button 1 of group GrpNo of RefEnd
			end try
			delay 0.25
		end repeat
		delay 2
		click button 2 of group GrpNo of RefEnd --"All Filters" icon. 
		delay 2 --Need find way to check the box "All Filters" is open
		set CheckName to ""
		repeat with cnt from 10 to 50
			set CheckName to name of button cnt of group GrpNo of RefEnd --Ex Div Date
			if CheckName is "Ex-div Date" then exit repeat
		end repeat
		click button cnt of group GrpNo of RefEnd --Ex Div Date
		repeat with cnt from 175 to 250 --Open the From Calendar
			try
				click text field 1 of group cnt of group GrpNo of RefEnd --opens From calendar
				exit repeat
			end try
		end repeat
		--the "From" Date	
		repeat with Cnt3 from 20 to 45 --get major group no
			try
				set Date1 to value of static text 1 of group 1 of group 1 of group 9 of group Cnt3 of RefEnd --The Date
				exit repeat
			end try
		end repeat
		delay 2 --Added as next leg could stall
		repeat until Date1 as number = TodaysDate as number --Data Starting to day
			set Cnt2 to Cnt2 + 1
			set Date1 to value of static text 1 of group Cnt2 of group 1 of group 9 of group Cnt3 of RefEnd --The Date
		end repeat
		click static text 1 of group Cnt2 of group 1 of group 9 of group Cnt3 of RefEnd --The Date
		--The "To" date
		click text field 2 of group cnt of group GrpNo of RefEnd --opens the "To" calendar
		click static text 1 of group (Cnt2 + 7) of group 1 of group 9 of group Cnt3 of RefEnd -- "To" Date + 7 days 
		click button 2 of group GrpNo of RefEnd --Closes the Date box
		delay 2
		click button 50 of group GrpNo of RefEnd --Close the "ALL FILTERS" box
		click UI element 25 of group GrpNo of RefEnd --Download Button
		delay 5 --Give it time to download
	end tell
end NewStocks

I edited my previous script to be way better.

It now will create a tab or window if needed then go to the URL
It will wait till the page is done loading.
Then it will find email & password groups and fill them out. in my case it generates a random name and password since I don’t have an account

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- https://www.dividend.com/login/?redirect_url=/login

property myURL : "https://www.dividend.com/login/?redirect_url=/login"
property eNames : {"Robert", "Mark", "Steven", "Joseph", "Anthony", "Edward", "James", "Ethan", "Henry", "Carlos", "Noah", "Arthur", "Louis", "Zachary", "Thomas", "Alexander", "Jacob", "Vincent", "Dylan", "William", "Jack", "Samuel", "Andrew", "Gabriel", "Benjamin", "Lawrence", "Christopher", "Matthew", "George", "Nicholas", "Daniel", "Nathan", "Peter", "Paul", "Harold", "Adam", "Charles", "Aaron", "Kenneth", "Walter", "Patrick", "Philip", "Austin", "Jesse", "Ryan", "Bruce", "Albert", "Michael", "Eugene", "David", "Eric", "Jonathan", "Frank", "Paul", "Jason", "Brian", "Richard", "Jordan", "Keith", "Kevin", "Russell", "Roger", "Jeremy", "Justin", "Timothy", "Greg", "Alan", "Brandon", "Tyler", "Scott", "Wayne", "Jeffrey", "Dennis", "Douglas", "Roy", "Sean", "Carl", "Ronald", "Donald", "Gerald", "Gary", "Randolph", "Terry"}

on run
	local myTab, myURLs, UIElements, subElements, loginPane, anElement, anItem, i, uname, emailFlag, pwdFlag, tmp
	tell application "Safari"
		if it is not running then activate it
		set tmp to windows
		if (count tmp) = 0 then -- Safari is running but has no windows
			make new document
			set myTab to current tab of window 1
			set URL of myTab to myURL
		else
			set myURLs to URL of tabs of window 1
			if myURL is in myURLs then -- check to see if one of it's tabs already has the URL
				repeat with i from 1 to count myURLs
					if (item i of myURLs) = myURL then
						exit repeat
					end if
				end repeat
				if current tab of window 1 ≠ tab i of window 1 then
					set current tab of window 1 to tab i of window 1
				end if
			else -- no tab or window with URL was found
				if (source of current tab of window 1) = "" then -- empty page found, so load URL
					set myTab to current tab of window 1
				else -- no empty window found, so create a new tab
					set myTab to (make new tab at window 1)
					set current tab of window 1 to myTab
				end if
				set URL of myTab to myURL
			end if
		end if
		repeat
			if (name of window 1) = "Login - Dividend.com - Dividend.com" then exit repeat
			delay 0.2
		end repeat
	end tell
	
	tell application "System Events"
		set anElement to application process "Safari"
		set subElements to groups of toolbar 1 of window 1 of anElement -- test if page done loading
		repeat with i in subElements -- find group in toolbar that has 'Reload' button
			set tmp to contents of i
			if exists (button "Add page to Reading List" of tmp) then exit repeat
		end repeat
		tell tmp
			repeat until exists button "Reload this page"
				delay 0.2
			end repeat
		end tell
		set flag to false
		repeat until flag
			try
				window 1 of anElement
				set anElement to UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 of anElement
				--get anElement
				set flag to true
			on error --errMsg number errNum
				delay 0.2
			end try
			if anElement = missing value then set flag to false
		end repeat
		--tell me to display alert "anElement " & ((class of anElement) as text)
		set flag to false
		repeat until flag
			try
				set subElements to groups of anElement whose subrole is "AXLandmarkMain"
				--get subElements
				set flag to true
			on error --errMsg number errNum
				beep 1
			end try
			if (subElements = missing value) or ((count subElements) = 0) then set flag to false
			if flag then
				set loginPane to item 1 of subElements
				try
					set subElements to groups of loginPane whose subrole is not "AXEmptyGroup"
				on error
					set flag to false
				end try
				if (count subElements) = 0 then set flag to false
				if not flag then delay 0.2
			end if
		end repeat
		--tell me to display alert "Flags " & (count of subElements)
		set emailFlag to false -- **EDIT** forgot to initialize the email flag
		repeat with i in subElements -- finds the Email group
			set i to contents of i
			if (static text 1 of i) exists then
				if (value of static text 1 of i) = "Email" then
					set anItem to text field 1 of i
					set focused of anItem to true
					tell me to delay 0.2
					set tmp to value of anItem
					set uname to tmp
					repeat while uname = tmp
						set uname to some item of eNames
					end repeat
					set value of anItem to uname --"Robert"
					set emailFlag to true
					set focused of text field 1 of i to true -- screen refreshes to remove 'This field is required' notice (if there is one)
					tell me to delay 0.2
					exit repeat
				end if
			end if
		end repeat
		set pwdFlag to false
		set subElements to groups of loginPane whose subrole is not "AXEmptyGroup"
		repeat with i in subElements -- finds the Password group
			set i to contents of i
			if (static text 1 of i) exists then
				if (value of static text 1 of i) = "Password" then
					set anItem to text field 1 of i
					set focused of anItem to true
					tell me to delay 0.2
					set value of anItem to my getPWD() --"mypwd"
					set pwdFlag to true
					exit repeat
				end if
			end if
		end repeat
		if emailFlag and pwdFlag then
			repeat with i in subElements -- finds the Login button
				set i to contents of i
				if (button "Log in" of i) exists then
					tell button "Log in" of i to perform action "AXPress"
					exit repeat
				end if
			end repeat
		end if
	end tell
end run

on getPWD()
	local pwd, c
	set pwd to ""
	set c to random number from 6 to 12
	repeat with i from 1 to c
		set pwd to pwd & some character of "abcdeefghijklmnopqrstuvwxyz!#$%^*-+?~"
	end repeat
end getPWD

Ed

Stuck again, I now cannot figure out how to stop the loop at present I have amended your script (see below) to run 5 times works as I know the element I want is 5 but that of course that could change. I need to return the name in the box with I thought would be easy, but a day later it’s not at least for me.

The start is the is in the box below and is classified as button class. The last line in the quote is classified as span class and do not know if that changes things. But it is that line that will confirm I have reached the correct block and can exit the loop.

Easy enough parse to out the “Ex-div date” but obviously I 1st need to return the whole line.

I apologise if I am wasting your time but cannot get their myself.

Thanks again

--This selects the "Ex-Div Date" box code macscripter Ed Stockly
--M variation but have to stop when "Ex-Div Date" selected
--So need to work out how to check name of each box selected
set theClassName to "t-py-3 t-mr-2 t-mb-2 t-w-max t-px-3 t-text-black hover:t-bg-mitre-gray-200 t-text-sm t-flex t-items-center t-relative t-min-w-150 t-justify-between"

set the elementNumber to 0
repeat 5 times --added  PM
	set theScript to JSForClickByClassName(theClassName, elementNumber)
	log theScript
	
	tell application "Safari"
		activate
		set safariJSScriptResults to do JavaScript " " & theScript in current tab of window 1
		log
	end tell
	set the elementNumber to elementNumber + 1
end repeat

to JSForClickByClassName(theClassName, elementNumber)
	log elementNumber
	return " document.getElementsByClassName('" & theClassName & "')[" & elementNumber & "].click();"
end JSForClickByClassName

Robert

Thank you, I had that part working but like yours better so will incorporate that as soon as I have tested it.

Thanks

Peter

I have a slightly newer version of the above script.

I made a few changes, but the biggest is adding a repeat loop.
Sometimes when making a new tab in safari, the page isn’t finished fully loaded when the script tries to find the Email & Password fields, so it doesn’t find one or both.
The repeat loop catches this and tries again. EDIT fixed repeat loop so its not infinite

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- https://www.dividend.com/login/?redirect_url=/login

property myURL : "https://www.dividend.com/login/?redirect_url=/login"
property eNames : {"Robert", "Mark", "Steven", "Joseph", "Anthony", "Edward", "James", "Ethan", "Henry", "Carlos", "Noah", "Arthur", "Louis", "Zachary", "Thomas", "Alexander", "Jacob", "Vincent", "Dylan", "William", "Jack", "Samuel", "Andrew", "Gabriel", "Benjamin", "Lawrence", "Christopher", "Matthew", "George", "Nicholas", "Daniel", "Nathan", "Peter", "Paul", "Harold", "Adam", "Charles", "Aaron", "Kenneth", "Walter", "Patrick", "Philip", "Austin", "Jesse", "Ryan", "Bruce", "Albert", "Michael", "Eugene", "David", "Eric", "Jonathan", "Frank", "Paul", "Jason", "Brian", "Richard", "Jordan", "Keith", "Kevin", "Russell", "Roger", "Jeremy", "Justin", "Timothy", "Greg", "Alan", "Brandon", "Tyler", "Scott", "Wayne", "Jeffrey", "Dennis", "Douglas", "Roy", "Sean", "Carl", "Ronald", "Donald", "Gerald", "Gary", "Randolph", "Terry"}

on run
	local myApp, myTab, myURLs, UIElements, subElements, loginPane, anElement, anItem, i, stack, uname, flag, emailFlag, pwdFlag, tmp
	tell application "Safari"
		if it is not running then activate it
		set tmp to windows
		if (count tmp) = 0 then -- Safari is running but has no windows
			make new document
			set myTab to current tab of window 1
			set URL of myTab to myURL
			--delay 0.5
		else
			set myURLs to URL of tabs of window 1
			if myURL is in myURLs then -- check to see if one of it's tabs already has the URL
				repeat with i from 1 to count myURLs
					if (item i of myURLs) = myURL then
						exit repeat
					end if
				end repeat
				if current tab of window 1 ≠ tab i of window 1 then set current tab of window 1 to tab i of window 1
			else -- no tab or window with URL was found
				if (source of current tab of window 1) = "" then -- empty page found, so load URL
					set myTab to current tab of window 1
				else -- no empty window found, so create a new tab
					set myTab to (make new tab at window 1)
					set current tab of window 1 to myTab
				end if
				set URL of myTab to myURL
			end if
		end if
		set flag to true
		repeat 50 times
			if (name of window 1) = "Login - Dividend.com - Dividend.com" then
				set flag to false
				exit repeat
			end if
			delay 0.2
		end repeat
	end tell
	if flag then return false
	tell application "System Events"
		set myApp to application process "Safari"
		repeat 3 times
			set emailFlag to false
			set pwdFlag to false
			set subElements to groups of toolbar 1 of window 1 of myApp -- test if page done loading
			repeat with i in subElements -- find group in toolbar that has 'Reload' button
				set tmp to contents of i
				if exists (button "Add page to Reading List" of tmp) then exit repeat
			end repeat
			tell tmp
				repeat until exists button "Reload this page" --accessibility description
					delay 0.2
				end repeat
			end tell
			
			set flag to false
			repeat until flag
				try
					window 1 of myApp
					set anElement to UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 of myApp
					--get anElement
					set flag to true
				on error --errMsg number errNum
					set anElement to missing value
					delay 0.2
				end try
				if anElement = missing value then set flag to false
			end repeat
			set flag to false
			repeat until flag
				try
					set subElements to groups of anElement whose subrole is "AXLandmarkMain"
					--get subElements
					set flag to true
				on error --errMsg number errNum
					beep 1
				end try
				if (subElements = missing value) or ((count subElements) = 0) then set flag to false
				if flag then
					set loginPane to item 1 of subElements
					try
						set subElements to groups of loginPane whose subrole is not "AXEmptyGroup"
					on error
						set flag to false
					end try
					if (count subElements) = 0 then set flag to false
					if not flag then tell me to delay 0.2
				end if
			end repeat
			try
				repeat with i in subElements -- finds the Email group
					set i to contents of i
					if (static text 1 of i) exists then
						if (value of static text 1 of i) = "Email" then
							set anItem to text field 1 of i
							set focused of anItem to true
							tell me to delay 0.2
							set tmp to value of anItem
							set uname to tmp
							repeat while uname = tmp
								set uname to some item of eNames
							end repeat
							set value of anItem to uname --"Robert"
							set emailFlag to true
							set focused of anItem to true --text field 1 of i to true -- screen refreshes to remove 'This field is required' notice (if there is one)
							tell me to delay 0.2
							exit repeat
						end if
					end if
				end repeat
			end try
			if emailFlag then -- do Password only if Email is done
				try
					set subElements to groups of loginPane whose subrole is not "AXEmptyGroup"
					repeat with i in subElements -- finds the Password group
						set i to contents of i
						if (static text 1 of i) exists then
							if (value of static text 1 of i) = "Password" then
								set anItem to text field 1 of i
								set focused of anItem to true
								tell me to delay 0.2
								set value of anItem to my getPWD() --"mypwd"
								set pwdFlag to true
								exit repeat
							end if
						end if
					end repeat
				end try
			end if
			if pwdFlag then exit repeat -- both fields found, so continue on
		end repeat
		
		if pwdFlag then
			repeat with i in subElements -- finds the Login button
				set i to contents of i
				if (button "Log in" of i) exists then
					tell button "Log in" of i to perform action "AXPress"
					exit repeat
				end if
			end repeat
		end if
	end tell
end run

on getPWD()
	local pwd, c
	set pwd to ""
	set c to random number from 6 to 12
	repeat with i from 1 to c
		set pwd to pwd & some character of "abcdeefghijklmnopqrstuvwxyz!#$%^*-+?~"
	end repeat
end getPWD

I would try something like this (but, since I don’t have access to the actual page, I can’t verify it will work).

set theClass to "t-text-sm"
set elementNumber to 0

set theScript to JSForGetInputByClass(theClass, elementNumber)
set scriptResult to JavaScriptInSafari(theScript)

to JSForGetInputByClass(theClass, num)
	return " document.getElementsByClassName('" & theClass & "')[" & num & "].innerHTML;"
end JSForGetInputByClass

on JavaScriptInSafari(theScript)
	my WaitUntillSafariPageIsLoaded()
	tell application "Safari"
		activate
		set safariJSScriptResults to do JavaScript " " & theScript in current tab of window 1
	end tell
end JavaScriptInSafari

on WaitUntillSafariPageIsLoaded()
	try
		tell application "Safari"
			tell current tab of window 1
				repeat until the length of (get the source as text) is not 0
					delay 0.1
				end repeat
				return "Complete"
			end tell
		end tell
	end try
end WaitUntillSafariPageIsLoaded

Ed thank u again but this did not work but that could be because I described the problem badly.

My log in details for Dividend.com are user mitchbvi@mac.com PW Div10182022#. from the log in this page should open https://www.dividend.com/premium/ at the bottom select “Best Dividend Capture stocks” which is under the heading tools. From there the 1st script below opens the page with “Ex-div Date” on it.

The 2nd script shows the loop which is set to a max of 4 but that could change and the way I know I am in the correct place is to get the name in the last line of the quote below “Ex-div Date”. I hope this makes sense

--Based on Ed Stockly advise this opens the 2nd page which containes Ex-div date , Dec Date etc
set theClassName to "mp-page-filter-all-filter-button mp-page-filter-all-filter-button__on_page 12"
set the elementNumber to 0
set theScript to JSForClickByClassName(theClassName, elementNumber)

tell application "Safari"
	activate
	set safariJSScriptResults to do JavaScript " " & theScript in current tab of window 1
end tell

to JSForClickByClassName(theClassName, elementNumber)
	log elementNumber
	return " document.getElementsByClassName('" & theClassName & "')[" & elementNumber & "].click();"
end JSForClickByClassName

--Source Ed Stockly
set theClassName to "t-py-3 t-mr-2 t-mb-2 t-w-max t-px-3 t-text-black hover:t-bg-mitre-gray-200 t-text-sm t-flex t-items-center t-relative t-min-w-150 t-justify-between"

set the elementNumber to 0
repeat 4 times
	set theScript to JSForClickByClassName(theClassName, elementNumber)
	tell application "Safari"
		activate
		set safariJSScriptResults to do JavaScript " " & theScript in current tab of window 1
	end tell
	set elementNumber to elementNumber + 1
end repeat

to JSForClickByClassName(theClassName, elementNumber)
	return " document.getElementsByClassName('" & theClassName & "')[" & elementNumber & "].click();"
end JSForClickByClassName

This is kind of a complex page. Explain what you want to do via the user interface. (Which buttons or links to click, what to click and hold, what values to enter or get) and I’ll see if I can help.

Hi Ed

On that page I first need to set the start and end dates .

Clicking on the “Ex-div Date” box produces another menu with start and end dates. Unfortunately it does not allow the operator to type in the date but they must be select it from the calendars that drop down when clicked. My present GUI code select the current date as the start and then 7 days later for the end date.

Then I click the apply filters box which is at the bottom of that page. That obviously goes back to the page it was opened from and next to the filter icon is a download icon which has to be clicked and that downloads the data as a CSV file which I have further GUI code to process the results.

So far I have not addressed either “Recovery” or “Frequency” in my GUI approach but I would like to set the days to recovery and select the frequency of payments .

Thanks once again for all your help.

Peter

PS The following subroutine shows how I set the dates using GUI

on NewStocks()
	log "In NewStocks"
	set {TodaysDate, Date1, cnt, Cnt2, CheckSYM, GrpNo} to {day of (current date), "", 0, 0, "", 20}
	tell application "System Events" to tell process "Safari"
		--Open "All Filters" box so dates can be set
		set RefEnd to UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1
		repeat until CheckSYM is "Stocks"
			set GrpNo to GrpNo + 1
			try --Using "Stocks" as the button has a name and the filter button does not
				set CheckSYM to get name of button 1 of group GrpNo of RefEnd
			end try
			delay 0.25
		end repeat
		delay 2
		click button 2 of group GrpNo of RefEnd --"All Filters" icon. 
		delay 2 --Need find way to check the box "All Filters" is open
		set CheckName to ""
		repeat with cnt from 10 to 50
			set CheckName to name of button cnt of group GrpNo of RefEnd --Ex Div Date
			if CheckName is "Ex-div Date" then exit repeat
		end repeat
		click button cnt of group GrpNo of RefEnd --Ex Div Date
		repeat with cnt from 175 to 250 --Open the From Calendar
			try
				click text field 1 of group cnt of group GrpNo of RefEnd --opens From calendar
				exit repeat
			end try
		end repeat
		--the "From" Date	
		repeat with Cnt3 from 20 to 45 --get major group no
			try
				set Date1 to value of static text 1 of group 1 of group 1 of group 9 of group Cnt3 of RefEnd --The Date
				exit repeat
			end try
		end repeat
		delay 2 --Added as next leg could stall
		repeat until Date1 as number = TodaysDate as number --Data Starting to day
			set Cnt2 to Cnt2 + 1
			set Date1 to value of static text 1 of group Cnt2 of group 1 of group 9 of group Cnt3 of RefEnd --The Date
		end repeat
		click static text 1 of group Cnt2 of group 1 of group 9 of group Cnt3 of RefEnd --The Date
		--The "To" date
		click text field 2 of group cnt of group GrpNo of RefEnd --opens the "To" calendar
		click static text 1 of group (Cnt2 + 7) of group 1 of group 9 of group Cnt3 of RefEnd -- "To" Date + 7 days 
		click button 2 of group GrpNo of RefEnd --Closes the Date box
		delay 2
		click button 50 of group GrpNo of RefEnd --Close the "ALL FILTERS" box
		click UI element 25 of group GrpNo of RefEnd --Download Button
		delay 5 --Give it time to download
	end tell
end NewStocks