GUI Scripting

Good Evening and sorry for sinning…
I’m quite new to AS, but getting the hang of it and realizing the fun of it because of this great forum.
My problem: I work for a Dutch airline, pretty good in safely moving people, but not very good in building websites.
Every week I had to accomplish a manual login (autocomplete…off), mouse-click a terrible amount of buttons, just in order to get my flight-schedule downloaded. So a couple of weeks ago I decided to pick up GUI scripting to automate that process. (the AS “Autocomplete always on”, a patch for Safari, helped me with the auto-login)
I got the thing working, but alas: after figuring out the UI elements with PreFab, the next day the “Group” UI elements apparently had changed. And after a couple days once again. Headache… So I coded a handler with two repeat loops for two groups of UI elements (for instance: the websites creators change the first group from 12 to 15 and visa versa, the second group from 3 to 5 to 4, back to 3 etc., etc. Beats me why though).
My script works, but takes ages to finish.
I hope that you good people can come up with a suggestion for a more streamlined and faster solution.
Part of my code (for one the required “clicks”) sofar:


on my_work()
	set correctClick to false
	set group_one_list to {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
	set group_two_list to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	repeat with i from 1 to (count group_one_list)
		set group_one to item i of group_one_list
		repeat with j from 1 to (count group_two_list)
			set group_two to item j of group_two_list
			tell application "System Events"
				tell application process "Safari"
					try
						tell static text " My Work " of UI element " My Work " of group group_one of UI element 1 of scroll area 1 of group group_two of window "KLM Intranet Portal"
							set pos to position as list
							set siz to size as list
							set x to item 1 of pos
							set y to item 2 of pos
							set width to item 1 of siz
							set height to item 2 of siz
							click at {x + width / 2, y + height / 2}
						end tell
						set correctClick to true
						exit repeat
					on error
						set j to j + 1
						if j = 1 + (count group_two_list) then
							exit repeat
						end if
					end try
				end tell
			end tell
		end repeat
		if correctClick then exit repeat
		set i to i + 1
	end repeat
end my_work

Model: Powerbook 12" G4 + Imac G5 (Mac OSX (10.4.9)
Browser: Safari 312.6
Operating System: Mac OS X (10.3.9)

Welcome merwed@;

As a first time poster, you’re forgiven for a big sin: Just above the text entry box in which you enter or edit a post you’ll see an “AppleScript” button. You should click that and put your script between the two tags. The server will look after the rest. The script you used to colorize and create an AppleScript link in your post will not work in this forum (which has it’s own bbcode setup to do this).

Would you mind editing your post and just copy your script between AppleScript tags inserted with the button?

Hello

Have you look in the page structure if there is a relation between the index of the useful group and the total number of groups?

Maybe you may use this total number to get the correct index faster.

In your code, it seems that you may skip some instructions and variables:

replacing


set pos to position as list
set siz to size as list
set x to item 1 of pos
set y to item 2 of pos
set width to item 1 of siz
set height to item 2 of siz

by


set {x,y} to (position)
set {width, height} to (size)

Yvan KOENIG (from FRANCE vendredi 6 avril 2007 18:34:20)

Thanks Yvan for your reply.
There is no relationship whatsoever ; the groups apparently change at random.
And as I said : it beats me why.
The code you presented could help to speed things up. I’ll give it a try.
By the way : that particular piece of code is generated by PreFab UI Browser when asking for : applescript, click by position.
Thanks again.
Cheers

Hi, merwed@.

I think the following achieves the same result as your handler, but I can’t tell without access to your Web page (which is obviously out of the question) and I’m only guessing what’s supposed to be clicked anyway! (A link called " My Work "?) Also, I’m not sure if this method is faster or not! Apologies if it doesn’t work at all. :rolleyes:

on my_work()
	tell application "System Events"
		tell application process "Safari"
			set group_two to first group of window "KLM Intranet Portal" whose scroll areas is not {}
			set group_one to first group of UI element 1 of scroll area 1 of group_two whose name of UI elements contains " My Work "
			click UI element " My Work " of group_one
		end tell
	end tell
end my_work

If you know anything about the URL behind the link that would make it easy to pick out from other links on the page, there might be much faster ways to access it using JavaScript.

Nigel, been out on “My Work” for a couple of days.
Yeah, as I said: website building… :stuck_out_tongue:
But anyway, thanks for the reply.
Otherwise I’ll follow up on your suggestion and dig into javascript.
But it’s great fun just trying!

One last try:
The difference in output from my (too long a) script and Nigels script:

Events on “My Work” of own script:
get position of static text " My Work " of UI element " My Work " of group 12 of UI element 1 of scroll area 1 of group 3 of window “KLM Intranet Portal” of application process “Safari”{105, 179}
get size of static text " My Work " of UI element " My Work " of group 12 of UI element 1 of scroll area 1 of group 3 of window “KLM Intranet Portal” of application process “Safari” {70, 15}
click static text " My Work " of UI element " My Work " of group 12 of UI element 1 of scroll area 1 of group 3 of window “KLM Intranet Portal” of application process “Safari” at {140, 186.5}
static text " My Work " of «class » " My Work " of group 12 of «class » 1 of scroll area 1 of group 3 of window “KLM Intranet Portal” of application process “Safari”

Events on “My Work” of Nigels script
get group 1 of window “KLM Intranet Portal” of application process “Safari” whose every scroll area ≠{}
group 3 of window “KLM Intranet Portal” of application process “Safari”
get group 1 of UI element 1 of scroll area 1 of group 3 of window “KLM Intranet Portal” of application process “Safari” whose name of every UI element contains " My Work "
group 12 of «class » 1 of scroll area 1 of group 3 of window “KLM Intranet Portal” of application process “Safari”
click UI element " My Work " of group 12 of «class 1 » of scroll area 1 of group 3 of window “KLM Intranet Portal” of application process “Safari”
“System Events got an error: NSCannotCreateScriptCommandError”

Please, any suggestions?

Good Morning again!
Found a script on your forum (:D) and modified it slightly. It uses javascript (great suggestion, Nigel) and it works great : you’re only dependent on the name of the link (which hardly ever changes) and not on the layout of the webpage. (GUI scripting is very dependent on that). Thanks again!
The script:


tell application "Safari"
	set counter to 0
	-- the number of links in the front document
	set the_link_number to do JavaScript "document.links.length" in document 1
	repeat the_link_number times
		set counter to counter + 1
		set the_link to do JavaScript "document.links[" & counter & "].innerHTML" in document 1
		if the_link contains "My Work" then
			delay 1
			set thelink to do JavaScript "document.links[" & counter & "].href" in document 1
			exit repeat
		end if
	end repeat
	set the URL of document 1 to thelink
end tell

Hi, merwed@.

That’s great. I’ve only dabbled a little in JavaScript and didn’t know about the ‘innerHTML’ possibility. I’m glad you were able to find a solution to your problem.

Fooling around with this, and rummaging around in the JavaScript book I have, it seems possible to keep most of the process in JavaScript. Does this work for you?

set JS to "for (i = 0; i < top.document.links.length; i++) {
	if (document.links[i].innerHTML.indexOf('My Work') >= 0)  {
		window.location = document.links[i].href ;
		return ;
	}
}
alert('No link containing \\'My Work\\' was found on this page.') ;"

tell application "Safari" to (do JavaScript JS in front document)