Forum Discussion

coffee's avatar
coffee
Contributor
8 years ago

NameMapping & Object Browser for Dynamically Created Object

Hi,

 

I have a newbie question about how to use NameMapping and Object Browser properly.

 

I understand that when I start Recording, TC will "remember" all objects on my webpage, what I type in the text boxes, and what buttons do I click. So, when I playback, TC knows about all those objects and which one to Click().

 

I have a blank website with one "ADD" button.. 

  1. When I click that "ADD" button once, a text-box and a "Submit" button will appear, so user can write e.g. "Hello1" and click "Submit".
  2. When I click that "ADD" button once again, a second text-box and a second "Submit" button will appear, so user can write e.g. "Hello2" and click "Submit". 
  3. And so on ...

If I don't use Recording functionality, I would

  • Explore the DOM and find the parent. 
  • After I Click() that "ADD" button for the first time, I would see the first child.  That first child will have two children (one for the text-box and another one for the "Submit" button).

 

var parent = Page.QuerySelectorAll(CSSselector);
... //Click() ADD Button; var textbox = parent.children.item(0).QuerySelector(XXX); // Find the 1st textbox var submit = parent.children.item(0).QuerySelector(YYY); //Find the 1st submit button

 

  • After I Click() that "ADD" button for the second time, I would see the second child.  That second child will have two children (one for the text-box and another one for the "Submit" button). 
var parent = Page.QuerySelectorAll(CSSselector);
... //Click() ADD Button;
... //Click() ADD Button; var textbox = parent.children.item(1).QuerySelector(XXX); //Find the 2nd textbox var submit = parent.children.item(1).QuerySelector(YYY); //Find the 2nd submit button

If I want to click that ADD button 100 times, then I could easily find the 100th text-box and submit button by 

var textbox = parent.children.item(99).QuerySelector(XXX);
var submit = parent.children.item(99).QuerySelector(YYY);

Now if I want to use Recording functionality and take advantage of NameMapping and Object Browser functionalities, How can I do that? 

 

TC won't know what and where is the 100th Submit button object, unless I start recording and click that "ADD" 100 times until the 100th Submit button appears and TC remember and put that object in the NameMapping & Object Browser (I don't think that is an efficient way of creating automation script :smileytongue:).  

 

Is there any way to create a logic in the NameMapping & Object Browser, so I don't need to record and click 100 times ?

Thank You.

 

6 Replies

  • NisHera's avatar
    NisHera
    Valued Contributor

    If you are going to record anything and everything ..yes it's not an efficient way of creating automation script.

     

    Now in your example you do repetitive operation ie. you add and submit "Hello(i)"  100th time

    where (i) is 1 to 100.....

     

    hear the idea is to  write a single script for all your 100 operation which can run 1 to 100.

    this could be achieved with couple of things

    1) Using Wildcards in Name Mapping

    2) For loop operation

    3) Data-Driven Testing

     

    so you can use wild card in name-mapping such that it could identify any of your   "ADD", "text box" and "submit" using wild card eg 

    parent.children.item(i).QuerySelector(XXX)

    and with DDT you can put any value instead of "Hello 1" and with for loop run it 100 times changing i (1 to 100).

    Please go-through above links and try your self. any practical problems forum can help

     

    • coffee's avatar
      coffee
      Contributor

      Thanks for the reply. 

       

      In name mapping , I can see that everytime user click the "ADD" button , a new cell will be created under the parent "table" and that cell now has a unique properties (RowIndex and ColumnIndex). 

       

       

       

       

       

       

       

       

       

      That is very helpful because now I know when I click the ADD button for the first time, I can expect a cell with Row "1".

      If I click the ADD button for the second time, I can expect two cells with row "1" and row "2". 

       

      But how can I wildcard this property and put it in my JS script? 

       

      If I put like this in my script

      Aliases.browser.xxx.yyy.zzz.table.cell ;

      It will refer to the cell in row "1" 

      After I click the ADD button for the second time, how can I ask TC to please search for cell with row index = row index + 1

      Assume that cell11 has row index "2" , can TC search for cell with Row Index = '2' , after clicking the ADD button for the second time?

       

      Thank You. 

       

      • Colin_McCrae's avatar
        Colin_McCrae
        Community Hero

        OK.

         

        Between your first post, and your second post, you added some important information.

         

        The initial post mentions nothing about a table. Your second one does. As soon as you have a table, you are dealing with rows, columns and cells. It sounds like your text boxes are being added to a cell in a table.

         

        So your object hierarchy now becomes:

         

        • Page
          • Table
            • Cell 1
              • TextBox
            • Cell 2
              • TextBox
            • Cell 3 (Empty?)
            • Cell 4

        And Row and Column may be in there as well. Or the cells may be children of the table. Or found as an object within a property of the table. There are various different table types and they are populated and rendered in many different ways. It's impossible to say for sure without inspecting it or knowing exactly what it is.

         

        What I would say though, is that individual cells are seldom worth mapping. The table itself I would map. The cells within it, I would not as they tend to be too dynamic. Things move around, content changes etc etc.

         

        I would probably end up with the table object mapped, and a sensible Alias applied. (Aliases should be much more concise and readable than full object names. They should NOT be a straight copy of the full object reference!) And then helper functions to find and manipulate the cells and their contents within it. In fact, I have things set up EXACTLY that way in my current project!

         

        Going back to how you could handle several instances of a similar button - I think you may be coming at it from slightly the wrong angle. You use the wildcards in the identification properties of the mapped object to account for things which are dynamic at runtime. So if the table "Name" property (for example) had some sort of timestamp in it which changed every run, you would replace that with a "*" to allow it to still identify correctly.

         

        https://support.smartbear.com/screencasts/testcomplete/wildcard-dynamic-property-in-testcomplete/

         

        Using a single mapped object to try and control multiple on screen objects is not a great idea as that is ambiguous by it's nature. How do you know you have the right instance? And if there are more than one present on screen, you'll get an ambiguous mapping error as it won't know which one it should be using.

         

        Mapping isn't always the right way. With table cells, and their contents, it's almost never the right way in my opinion.