90 lines
3.0 KiB
Plaintext
90 lines
3.0 KiB
Plaintext
====================
|
|
ATTRIBUTE RESOLUTION
|
|
====================
|
|
|
|
TWO LEVELS
|
|
* application.member (Python resolves)
|
|
an attribute of application object
|
|
* application.dialog
|
|
a dialog reference
|
|
|
|
THREE LEVELS
|
|
* application.member.attr (Python resolves)
|
|
another attribute of the previous member
|
|
* application.dialog.member
|
|
a member of the dialog object
|
|
* application.dialog.control
|
|
a control on the dialog
|
|
|
|
FOUR LEVELS (leaving out Python resolved)
|
|
* application.dialog.member.member
|
|
* application.dialog.control.member
|
|
|
|
|
|
DELAYED RESOLUTION FOR SUCCESS
|
|
Taking the example
|
|
app.dlg.control.action()
|
|
If we leave out syntax and programming errors there are still a number of reasons why it could fail.
|
|
|
|
dlg might not be found
|
|
control might not be found
|
|
either dlg or control may be disabled
|
|
|
|
dialog and control may be found but on the wrong dialog (e.g. in Notepad you can bring up 2 "Page Setup" dialogs both with an OK button)
|
|
|
|
One solution would just be to add a "sleep" before trying to find each new dialog (to ensure that it is there and ready) - but this will mean lots of unnecessary waiting.
|
|
|
|
So the solution I have tried is:
|
|
- perform the complete attribute access resolution at the latest possible time
|
|
- if it fails then wait and try again
|
|
- after a specified timeout fail raising the original exception.
|
|
|
|
This means that in the normal case you don't have unnecessary waits - and in the failure case - you still get an exception with the error.
|
|
|
|
Also waiting to do resolution as late as possible stops errors where an earlier part of the path succeedes - but finds the wrong item.
|
|
|
|
So for example if finds the page setup dialog in Notepad
|
|
# open the Printer setup dialog (which has "Page Setup" as title)
|
|
app.PageSetup.Printer.Click()
|
|
|
|
# if this runs too quickly it actually finds the current page setup dialog
|
|
# before the next dialog opens, but that dialog does not have a Properties
|
|
# button - so an error is raised.
|
|
# because we re-run the resolution from the start we find the new pagesetup dialog.
|
|
app.PageSetup.Properties.Click()
|
|
|
|
|
|
|
|
==================
|
|
WRITING TO DIALOGS
|
|
==================
|
|
We need a way of making sure that the dialog is active without having to access a control on it.
|
|
e.g.
|
|
app.MainWin.MenuSelect("Something That->Loads a Dialog")
|
|
app.Dlg._write("dlg.xml")
|
|
|
|
or a harder problem:
|
|
app.PageSetup.Printer.Click()
|
|
app.PageSetup._write("pagesetup.xml")
|
|
|
|
In this second example it is very hard to be sure that the correct Page Setup dialog is shown.
|
|
|
|
The only way to be realy sure is to check for the existance of certain control(s) (ID, Class, text, whatever) - but it would be nice to not have to deal with those :-(
|
|
|
|
Another less declarative (more magic?) is to scan the list of available windows/controls and if they haven't changed then accept that the correct one is shown.
|
|
|
|
When testing and having XML files then we should use those to make sure that we have the correct dialog up (by using Class/ID)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|