locked
WpfCell - find cell by ColumnHeader & Value RRS feed

  • Question

  • Hi,

    I have uploaded an app demonstrating this problem to dropbox here: dropbox.com/sh/txzrytbdwkfysar/AACJPv-KTDnynLj39WITStWfa?dl=0

    I am trying to validate the content of a WPF DataGrid cell using Coded UI Tests. I would like to test the value of a cell on a row with matching Month. So for example I would like to be able to get the value of the IsTrue column on the row for January and Assert.IsTrue on it.

    Month

    IsTrue

    January

    True

    February

    False

    March

    False

    April

    True


    I have written the following code to achieve this:

            [TestMethod]
            public void TestValidateCellByColumnNameAndCellValue()
            {
                UIMap.ValidateCell("Month", "January", "IsTrue", true.ToString());
            }

    And in UIMap.cs:

            internal void ValidateCell(string keyColumn, string keyValue, string cellColumn, string cellValue)
            {
                var cell = FindCell(keyColumn, keyValue, cellColumn);
                Assert.AreEqual(cellValue, cell.Value);
            }
            private WpfCell FindCell(string searchHeader, string searchValue, string columnHeader)
            {
                var monthCell = new WpfCell(UIMainWindowWindow.UIItemTable);
                monthCell.SearchProperties.Add(WpfCell.PropertyNames.ColumnHeader, searchHeader);
                monthCell.SearchProperties.Add(WpfCell.PropertyNames.Value, searchValue);
                
                var targetCell = new WpfCell(UIMainWindowWindow.UIItemTable);
                targetCell.SearchProperties.Add(WpfCell.PropertyNames.ColumnHeader, columnHeader);
                targetCell.SearchProperties.Add(WpfCell.PropertyNames.RowIndex, monthCell.RowIndex.ToString());
    
                return targetCell;
            }

    But this produces the following error:

    Test Name: TestValidateCellByColumnNameAndCellValue
    Test FullName: CodedUITestProject1.CodedUITest1.TestValidateCellByColumnNameAndCellValue
    Test Source: c:\Users\pgan\Documents\Visual Studio 2012\Projects\WpfApplicationForTestingAutomation\CodedUITestProject1\CodedUITest1.cs : line 62
    Test Outcome: Failed
    Test Duration: 0:00:05.2771655

    Result Message:
    Test method CodedUITestProject1.CodedUITest1.TestValidateCellByColumnNameAndCellValue threw exception: 
    Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException: The playback failed to find the control with the given search properties. Additional Details: 
    TechnologyName:  'UIA'
    ControlType:  'Cell'
    ColumnHeader:  'Month'
    Value:  'January'
     Search may have failed at '' Table as it may have virtualized children. If the control being searched is descendant of '' Table then including it as the parent container may solve the problem. ---> System.Runtime.InteropServices.COMException: Error HRESULT E_FAIL has been returned from a call to a COM component.
    Result StackTrace:
    at Microsoft.VisualStudio.TestTools.UITest.Playback.Engine.IScreenElement.FindAllDescendants(String bstrQueryId, Object& pvarResKeys, Int32 cResKeys, Int32 nMaxDepth)
       at Microsoft.VisualStudio.TestTools.UITest.Playback.ScreenElement.FindAllScreenElement(String queryId, Int32 depth, Boolean singleQueryId, Boolean throwException, Boolean resetSkipStep)
       at Microsoft.VisualStudio.TestTools.UITest.Playback.ScreenElement.FindScreenElement(String queryId, Int32 depth, Boolean resetSkipStep)
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindFirstDescendant(String queryId, Int32 maxDepth, Int32& timeLeft)
     --- End of inner exception stack trace ---
        at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapControlNotFoundException(COMException ex, IPlaybackContext context)
       at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapAndThrowComException(COMException innerException, IPlaybackContext context)
       at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapAndThrowException(SystemException exception, IPlaybackContext context)
       at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapAndThrowException(SystemException exception, String queryId)
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindFirstDescendant(String queryId, Int32 maxDepth, Int32& timeLeft)
       at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetUITestControlRecursive(Boolean useCache, Boolean alwaysSearch, ISearchArgument searchArg, IList`1 windowTitles, Int32& timeLeft)
       at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetElement(Boolean useCache, ISearchArgument searchArg)
       at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.Search(ISearchArgument searchArg)
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindInternal()
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.<Find>b__d()
       at Microsoft.VisualStudio.TestTools.UITesting.CodedUITestMethodInvoker.InvokeMethod[T](Func`1 function, UITestControl control, Boolean firePlaybackErrorEvent, Boolean logAsAction)
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.Find()
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.GetPropertyPrivate(String propertyName)
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.<>c__DisplayClass11.<GetProperty>b__10()
       at Microsoft.VisualStudio.TestTools.UITesting.CodedUITestMethodInvoker.InvokeMethod[T](Func`1 function, UITestControl control, Boolean firePlaybackErrorEvent, Boolean logAsAction)
       at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.GetProperty(String propertyName)
       at Microsoft.VisualStudio.TestTools.UITesting.WpfControls.WpfCell.get_RowIndex()
       at CodedUITestProject1.UIMap.FindCell(String searchHeader, String searchValue, String columnHeader) in c:\Users\pgan\Documents\Visual Studio 2012\Projects\WpfApplicationForTestingAutomation\CodedUITestProject1\UIMap.cs:line 58
       at CodedUITestProject1.UIMap.ValidateCell(String keyColumn, String keyValue, String cellColumn, String cellValue) in c:\Users\pgan\Documents\Visual Studio 2012\Projects\WpfApplicationForTestingAutomation\CodedUITestProject1\UIMap.cs:line 31
       at CodedUITestProject1.CodedUITest1.TestValidateCellByColumnNameAndCellValue() in c:\Users\pgan\Documents\Visual Studio 2012\Projects\WpfApplicationForTestingAutomation\CodedUITestProject1\CodedUITest1.cs:line 63

    I am able to retrieve the correct cell using RowIndex and CellIndex, but that is not going to work for our testing scenario. Any help here would be appreciated.

    Thanks,


    Monday, October 17, 2016 12:03 PM

Answers

  • Hi Oscar,

    Thank you for your response.

    It turns out that there was an exception being thrown and handled under the hood which shed some light on the issue. It is actually possible to search on ColumnHeader but you have to filter by row first. I solved this issue following a similar pattern to what you have already suggested (iterating over the rows to find the cell in the correct column with the correct value and then using that row to inspect the cell I need to test):

            private WpfCell FindCell(string searchHeader, string searchValue, string columnHeader)
            {
                IEnumerable<UITestControl> rows = UIMainWindowWindow.UIItemTable.Rows;
                foreach (var row in rows)
                {
                    var monthCell = new WpfCell(row);
                    monthCell.SearchProperties.Add(WpfCell.PropertyNames.Value, searchValue);
                    monthCell.SearchProperties.Add(WpfCell.PropertyNames.ColumnHeader, searchHeader);
    
                    if (monthCell.TryFind())
                    {
                        var targetCell = new WpfCell(row);
                        targetCell.SearchProperties.Add(WpfCell.PropertyNames.ColumnHeader, columnHeader);
    
                        return targetCell;
                    }
                }
    
                return null;
            }

    From what I can see your suggestion does not take into account the column header.

    Thanks,
    Phil

    • Proposed as answer by Phil_G Tuesday, October 18, 2016 8:46 AM
    • Marked as answer by Philpips Tuesday, October 18, 2016 9:15 AM
    Tuesday, October 18, 2016 8:46 AM

All replies

  • Hi Philpips,

    Based on your code, I found we could not get the cell controls base on the ColumnHeader property. We need to get the cell from the row control. I have modified your code to get “January” cell. Please refer to the following code:

    private WpfCell FindCell(string searchHeader, string searchValue, string columnHeader)
    
            {
    
                Playback.Wait(5000);
    
                UIMainWindowWindow.UIItemTable.DrawHighlight();
    
                //UIMap.ValidateCell("Month", "January", "IsTrue", true.ToString());
    
                UITestControlCollection rows = UIMainWindowWindow.UIItemTable.Rows;
    
                WpfCell cell = null;
    
                foreach (var row in rows)
    
                {
    
                    var cells = row.GetChildren();
    
                    cell= (WpfCell)cells[1];
    
                    if (cell.Value.ToString().TrimEnd().Equals(searchValue))
    
                    {
    
                        break;
    
                    }
    
                }
    
                cell.DrawHighlight();
    
                return cell;
    
            }
    

    This code could return us a correct cell.

    Sincerely,

    Oscar


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com

    Tuesday, October 18, 2016 5:39 AM
  • Hi Oscar,

    Thank you for your response.

    It turns out that there was an exception being thrown and handled under the hood which shed some light on the issue. It is actually possible to search on ColumnHeader but you have to filter by row first. I solved this issue following a similar pattern to what you have already suggested (iterating over the rows to find the cell in the correct column with the correct value and then using that row to inspect the cell I need to test):

            private WpfCell FindCell(string searchHeader, string searchValue, string columnHeader)
            {
                IEnumerable<UITestControl> rows = UIMainWindowWindow.UIItemTable.Rows;
                foreach (var row in rows)
                {
                    var monthCell = new WpfCell(row);
                    monthCell.SearchProperties.Add(WpfCell.PropertyNames.Value, searchValue);
                    monthCell.SearchProperties.Add(WpfCell.PropertyNames.ColumnHeader, searchHeader);
    
                    if (monthCell.TryFind())
                    {
                        var targetCell = new WpfCell(row);
                        targetCell.SearchProperties.Add(WpfCell.PropertyNames.ColumnHeader, columnHeader);
    
                        return targetCell;
                    }
                }
    
                return null;
            }

    From what I can see your suggestion does not take into account the column header.

    Thanks,
    Phil

    • Proposed as answer by Phil_G Tuesday, October 18, 2016 8:46 AM
    • Marked as answer by Philpips Tuesday, October 18, 2016 9:15 AM
    Tuesday, October 18, 2016 8:46 AM
  • Hi Phil_G,

    Glad to know that you have resolved this issue, and thanks for sharing your solution here. Would you please mark your reply as the answer? So it would be helpful for other members who meet the same issue as yours.

    Have a nice day.

    Sincerely,

    Oscar


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com

    Tuesday, October 18, 2016 8:49 AM