Forum Discussion

sothqamb's avatar
sothqamb
Occasional Contributor
4 years ago

Mapped objects being mapped again with some of the exact same selectors

I am trying to map a calendar date picker and after I map one of the dates it maps with 4 selectors as shown below

If I remove the first selector (//td[.='31']) and try to inspect the same date TC does not recognize the date which was just mapped

If I then try to remap the date which was previously mapped it remaps with the exact same selectors as in the first picture.

 

This also occurs if I only lower the (//td[.='31']) to the bottom of the selector priority, leaving it enabled and everything

 

It would seem that if I could change how TC is defaultly prioritizing the order of the selectors this would solve my problem but I have no idea how to go about doing this.

  • Hi,

     

    Everything is quite simple 🙂

    Priority of selectors (and this is documented) is defined by their order. So TestComplete first searches for the object using first (topmost) selector. If the search fails, then second selector is given a try. (Note OR operator) And so on until the search succeeds or the end of the list is reached.

     

    From your description, it looks like that date selector in your application is implemented as an html table where each table's cell defines a date. And the cell in the table is implemented via the <td> tag.

    So, when you mapped the date, TestComplete mapped it as a <td> element (which is top-level element in the hierarchy) that has value equal to 31. Definitely, this is 'hard-coded' mapping, but I bet that table cells in the date picker do not have other stable and unique attributes but the value of the cell.

     

    For html tables, TestComplete provides additional .cell property that makes it possible for test code to reference some table's cell using <row,column> notation. That is why you can address cells with dates from your test code if you work not with the cells themselves but with their parent table object.

     

    P.S. Personally I found automation of date picker controls to be complex and not worth efforts. So, unless you need to test date picker itself, a bit alternative approach usually works fine for me:

    -- Focus date field and type required date into it (or assign a date to the field's value if the field is not editable);

    -- This usually causes date picker control to be displayed and focused with the entered date been selected;

    -- Send .Keys("[Enter]") to the control to confirm date selection and to close date picker;

    -- Continue with the test.

     

  • AlexKaras's avatar
    AlexKaras
    Champion Level 3

    Hi,

     

    Everything is quite simple 🙂

    Priority of selectors (and this is documented) is defined by their order. So TestComplete first searches for the object using first (topmost) selector. If the search fails, then second selector is given a try. (Note OR operator) And so on until the search succeeds or the end of the list is reached.

     

    From your description, it looks like that date selector in your application is implemented as an html table where each table's cell defines a date. And the cell in the table is implemented via the <td> tag.

    So, when you mapped the date, TestComplete mapped it as a <td> element (which is top-level element in the hierarchy) that has value equal to 31. Definitely, this is 'hard-coded' mapping, but I bet that table cells in the date picker do not have other stable and unique attributes but the value of the cell.

     

    For html tables, TestComplete provides additional .cell property that makes it possible for test code to reference some table's cell using <row,column> notation. That is why you can address cells with dates from your test code if you work not with the cells themselves but with their parent table object.

     

    P.S. Personally I found automation of date picker controls to be complex and not worth efforts. So, unless you need to test date picker itself, a bit alternative approach usually works fine for me:

    -- Focus date field and type required date into it (or assign a date to the field's value if the field is not editable);

    -- This usually causes date picker control to be displayed and focused with the entered date been selected;

    -- Send .Keys("[Enter]") to the control to confirm date selection and to close date picker;

    -- Continue with the test.

     

  • It looks to me like the first selector is needed to find the date picker.  What is the intent of removing it from the list or moving it to the bottom.

    • sothqamb's avatar
      sothqamb
      Occasional Contributor

      I assume it needs to be removed from the list of selectors because it would make TC look for the date number on the calendar, which would change every month. So unless I have a very large misunderstanding of how TC works leaving the selector looking for the number would mean I have to completely remake the tests every month which sounds extremely suboptimal.

  • sothqamb's avatar
    sothqamb
    Occasional Contributor

    I figured out a slightly different solution than what I was looking for.
    I deleted one of the cells holding the date on the calendar using the HTML Inspector then mapped the table which was behind the cell. After mapping the cell i was able to go into a script and access the cells of the dates using the CalendarTable.cell(x_pos,y_pos)

     

    Guidance or any insight as to why TC was not recognizing the date cells would still be appreciated as how the selector defines things still seems a little strange to me.

      • sothqamb's avatar
        sothqamb
        Occasional Contributor

        Sorry for the not clear explanation, I am using the integer indexes of the cells, not the (x,y) coords

         

        CalendarTable.cell(x_pos,y_pos)  -->  CalendarTable.cell(x_index, y_index)

         

        I'm pretty sure this is a robust solution