Instructions for dealing with AppMap entries. The following instructions for dealing with AppMap entries are techniques for ways to improve the recognition strings generated by either classic ProcessContainer or RobotJ ProcessContainer. #1 Remove superfluous parts of the string when there may be problems recognizing multiple components; one place this has been demonstrated is with a TabControl ahead of other types of controls. It is not necessary to prove that a superfluous part will cause a problem before removing it, if you can convince yourself that it is indeed superfluous. A superfluous part of the string is a part which is not needed, based on assuring that sufficient unique parts are still available. - example 1: JCTable1="Type=CIMainFrame;Caption={Commercial Instructions*};\;Type=RootPane;Index=1;\;Type=JavaPanel;Index=1;\;Type=JavaPanel;Index=2;\;Type=CIDealPanel;Index=1;\;Type=TabControl;Index=1;\;Type=JavaPanel;Index=4;\;Type=JCTable;Index=1" For this particular example the unique part is this: Type=TabControl;Index=1;\; And one superfluous part for this example is: Type=JavaPanel;Index=4;\; This is the part between the TabControl and the component of interest, it might have had one, two or more of these JavaPanel types. And finally the component part, as always, is the last part: Type=JCTable;Index=1 After removing the superfluous part, the recognition string will be: JCTable1="Type=CIMainFrame;Caption={Commercial Instructions*};\;Type=RootPane;Index=1;\;Type=JavaPanel;Index=1;\;Type=JavaPanel;Index=2;\;Type=CIDealPanel;Index=1;\;Type=TabControl;Index=1;\;Type=JCTable;Index=1" Also notice that there was no need to modify the parts ahead of the tablcontrol, although there may have been superfluous parts there as well, like for instance the first two JavaPanel's with index 1 and 2 respectively. - example 2: JCTable2="Type=CIMainFrame;Caption=Commercial Instructions - [sn jcrew];\;Type=RootPane;Index=1;\;Type=JavaPanel;Index=1;\;Type=JavaPanel;Index=2;\;Type=CIDealPanel;Index=1;\;Type=JavaSplitPane;Index=1;\;Type=JavaPanel;Index=6;\;Type=JCTable;Index=1" For this particular example the unique part is this: Type=JavaSplitPane;Index=1;\; And one superfluous part for this example is: Type=JavaPanel;Index=6;\; This is the part between the TabControl and the component of interest, it might have had one, two or more of these JavaPanel types. And finally the component part, as always, is the last part: Type=JCTable;Index=1 After removing the superfluous part, the recognition string will be: JCTable2="Type=CIMainFrame;Caption=Commercial Instructions - [sn jcrew];\;Type=RootPane;Index=1;\;Type=JavaPanel;Index=1;\;Type=JavaPanel;Index=2;\;Type=CIDealPanel;Index=1;\;Type=JavaSplitPane;Index=1;\;Type=JCTable;Index=1" #2 In Commercial Instructions, it turned out that the two JCTable types in the split pane needed getter methods added so that we could get to them, but it also turns out that additional code added to our RobotJ framework library was able to test those tables using the embedded CellArea types. If you use any of the CellArea types which are contained by the JCTable, then the Table Component Function keywords should work as if it were the JCTable itself. #3 Use Name= instead of Index= wherever possible - example 1, for use in 'tiled' JavaPanel types: comp1="Type=JavaPanel;Name=This is the text in the tile;\;Type=Comp;Index=1" most of the rest of the recognition string generated by PC can be considered 'superfluous' because matching on a JavaPanel with Name=tilename is a very good (not fragile) way to do so. -other examples: Label1="Type=Label;Name=LabelName" OK1="Type=PushButton;Name=OK" #4 Use Index= instead of Name= for components which may change dynamically. For instance a Label which may change over time. You will have to determine empirically, or by investigating the map visually for other similar types to try to determine the index to use. Normally the index will always increment, but be careful, because components under separate tabs of a TabControl do not increment from tab to tab. Also, components found after the TabControl will increment, but only based on the first tab. #5 Be careful of Index= when dealing with TabControls. If two components of the same type are under two separate tabs of a tab control, then the index will be the same, if there is then again another of these component types after and outside of the tab control, then it's index will increment, but only once. - example 1: --TabControl --Tab1 --EditBox1 --Tab2 --EditBox1 --Panel --EditBox2 - example 2: --TabControl --Tab1 --EditBox1 --EditBox2 --Tab2 --EditBox1 --Panel --EditBox3 In example 2, there may be a problem at run-time matching EditBox3 when Tab2 is selected. My preferred solution for this problem is to define EditBox3 twice in the appmap section: EditBox3WithTab1Selected="Type=Panel;Index=1;\;Type=EditBox;Index=3" EditBox3WithTab2Selected="Type=Panel;Index=1;\;Type=EditBox;Index=2" And to make sure that the proper name is 'tested' in the test steps based on which tab is selected. #6 For a window with a tree control associated with panes that change as nodes are clicked in the tree control (as in DealMaintenance); make sure you click every node to make sure all dynamic components are loaded into the applications memory before running ProcessContainer. #7 Testing. To test if a recognition for a component works, test it, and if it is not recognized. then try to test one of the container components which contain it. For instance, Panel1="Type=Panel;Index=1" EditBox3WithTab2Selected="Type=Panel;Index=1;\;Type=EditBox;Index=2" If the EditBox does not work, the backup one level and test the Panel1. If that does not work or get recognized, keep backing up until you get to a component which is recognized, then try to figure out what the problem is with that level in the hierarchy before continuing. #8 Captions, Change captions with odd characters for all lines, like this: Replace all: Caption=Commercial Instructions - [sn jcrew] With: Caption={Commercial Instructions*} ### Example, this is an example for DealMaintenance, a dialog obtained from "View->Header" [headerDialogN] headerDialogN="Type=Window;Caption=Deal*" calendarComboBoxN="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Index=5;\;Type=ComboBox;Index=1" yearComboBoxN="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Index=5;\;Type=ComboBox;Index=2" buyTypeComboBoxN="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Index=5;\;Type=ComboBox;Index=3" treeTree="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaTree;Index=1" cmdCancelButton="Type=JavaWindow;JavaCaption=Deal*;\;Type=PushButton;Name=Cancel" invCritTable="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Invoice Generation Criteria;\;Type=MSAGrid;Index=1" policiesExpTable="Type=JavaWindow;JavaCaption=Deal*;\;Type=PoliciesCard;Index=1" policiesCanTable="Type=JavaWindow;JavaCaption=Deal*;\;Type=PoliciesCard;Index=1" policiesTotTable="Type=JavaWindow;JavaCaption=Deal*;\;Type=PoliciesCard;Index=1" policiesExpTableOld="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Expansion;\;Type=JavaTable;Index=1" policiesCanTableOld="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Cancellation;\;Type=JavaTable;Index=1" policiesTotTableOld="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Totals;\;Type=JavaTable;Index=1" dealAccessTabbedPane="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Deal Access;\;Type=TabControl;Index=1" addButton="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Deal Access;\;Type=PushButton;Name=Add >" list="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Deal Access;\;Type=ListBox;Index=1" dealAccessTable1="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Deal Access;\;Type=MSAGrid;Index=4" dealAccessTable2withAccessGroupsTabSelected="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Deal Access;\;Type=MSAGrid;Index=4" dealAccessTable2="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Deal Access;\;Type=JavaTable;Index=5" postTable1="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Selected Demographics;\;Type=JavaTable;Index=1" postTable2="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Brand Detail;\;Type=JavaTable;Index=2" addButtonActExec="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Account Exec Split;\;Type=PushButton;Name=Add" execsGridTable="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Account Exec Split;\;Type=MSAGrid;Index=1" tabbedPanePageTabList="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Agency Maintenance;\;Type=TabControl;Index=1" activeAgenciesGridTable="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Agency Maintenance;\;Type=MSAGrid;Index=1" ShowInvoicingOnlyCheckBox=ShowInvoicingOnlyCheckBox availAgenciesListBoxList=availAgenciesListBoxList invoicingAgenciesGridTable="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Agency Maintenance;\;Type=TabControl;Index=1;\;Type=MSAGrid;Index=2" flightsTable1="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Selected Ranges;\;Type=MSAGrid;Index=4" revTable1="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Deal Changes/Revisions;\;Type=MSAGrid;Index=4" nonCommTable1="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Existing Items;\;Type=MSAGrid;Index=4" postingTable1="Type=JavaWindow;JavaCaption=Deal*;\;Type=JavaPanel;Name=Define Posting Quarters;\;Type=MSAGrid;Index=4" [policiesExpTable] gridProperty=expansionTable [policiesCanTable] gridProperty=cancellationsTable [policiesTotTable] gridProperty=totalsTable