icnocop / cuite

Coded UI Test enhanced Framework
Microsoft Public License
52 stars 29 forks source link

Not able to limit searching for a control to a specific Screen #87

Closed icnocop closed 8 years ago

icnocop commented 8 years ago

The anomaly I noticed is that if the parent Screen has an "OK" button and the modal dialog has an "OK" button, I can't be certain the correct one will be found when trying to search for the control by its name because the NavigateTo<T> method doesn't seem to limit the search specifically to the child dialog.

Steps to reproduce:

  1. Edit .\src\SystemsUnderTest\Sut.Wpf.ScreenObjects\MainWindow.xaml:
    a. Append <RowDefinition /> within the <Grid.RowDefinitions>
    b. Add <Button Grid.Row="3" Content="OK"></Button> before </Grid>
  2. Edit .\src\SystemsUnderTest\Sut.Wpf.ScreenObjects\Dialog.xaml:
    Add <Button Content="OK"/> before </StackPanel>
  3. Add the following property to .\src\SystemsUnderTest\Sut.Wpf.ScreenObjectsTest\ScreenObjects\DialogScreen.cs:

    public WpfButton OkButton
    {
       get { return Find<WpfButton>(By.Name("OK")); }
    }
  4. Add the following test to .\src\SystemsUnderTest\Sut.Wpf.ScreenObjectsTest\ScreenComponentsTest.cs:

    [TestMethod]
    public void ClickOkButtonInChildDialog()
    {
       // Act
       var dialogScreen = mainScreen.MiddleScreenObject.NavigateToModalDialogScreen();
    
       dialogScreen.OkButton.DrawHighlight();
    
       // Assert
       dialogScreen.OkButton.Click();
    }
  5. Run the ClickOkButtonInChildDialog test method and observe that the "OK" button on the parent dialog is highlighted and clicked.

I expected the "OK" button on the child dialog to get highlighted and clicked.

I'm wondering if the NavigateTo<T>() should allow passing in search properties (and a window title). In this way, if there are multiple dialogs visible the search properties will help identify which specific dialog the subsequent code should be interacting with.

As a side note, I would have liked to be able to call dialogScreen.DrawHighlight(); (or something equivalent).

Thank you.

icnocop commented 8 years ago

This is a continuation of the discussion started here: https://github.com/icnocop/cuite/pull/76#issuecomment-208707115

FantasticFiasco commented 8 years ago

I'll take a look at it, I'll get back to you when I've found something.

spelltwister commented 8 years ago

Hello, I'm not too familiar with CUITe other than it is super similar to what I wrote for coded ui fluent extensions, but using the same thinking, is this not a bug with your property? In my case, when I model out something like this the property would look like:

public WpfButton OkButton
{
    get { return this.Me.Find<WpfButton>(By.Name("OK")); }
}

where this.Me is the UI element representing the control modeled by this class containing the OkButton. I also have other abstractions to anchor the search to a specific starting point.

FantasticFiasco commented 8 years ago

There is the concept of Me in ScreenObject<T>, but there it is called Self. When it comes to Screen there is no such concept, but perhaps should? However, it would probably be intuitive to limit the scope of the method Find to the screen, but currently in the code the scope is set to the application, which is plain wrong.

I've added tests that fail, and am working on the code that will fix them.

Regarding similarities to the coded UI fluent extensions, I don't think you are wrong. Both the syntax of your library and White where investigated before implementing the new features in CUITe.

spelltwister commented 8 years ago

I think the reference in the current object to it's UI element is a must. In nearly every case of a component, the outer component contains any inner components and searching is naturally very hierarchical.

Window -> Search Control -> Search Criteria Window -> Search Control -> Search Result (Sibling of Criteria)

If there are multiple search controls on a page, how to figure out which search result you are looking for if you do not start with the search control ui element containing the result that you want. I wrote up some examples of how and why I do this here.

I plan to flush out the documentation around when to use what type of model more, but I think this is a good start. I'd love to collaborate on what a great abstraction over UI would look like. :)

FantasticFiasco commented 8 years ago

I love the feedback, and you've clearly thought a great deal regarding these problems. I'd love to get hold of you in a IM client or something with a quicker feedback-loop. @icnocop I think you should be a part of that conversation.

Regarding your comments, I think we cover many of your concerns. For terminology what you call page models we call page objects (and in desktop applications screen objects). The term is borrowed from Martin Fowlers article, and I think he borrowed it from the Selenium driver. The Find method of a page object is originating from the page object itself as can be seen in the code of ViewObject:

/// <summary>
/// Finds the control object from the descendants of this control using the specified
/// search configuration.
/// </summary>
/// <typeparam name="T">The type of control to find.</typeparam>
/// <param name="searchConfiguration">The search configuration.</param>
protected T Find<T>(By searchConfiguration = null) where T : ControlBase
{
    if (searchLimitContainer == null)
        throw new InvalidOperationException("The view object has not been configured with a search limit container.");

    return searchLimitContainer.Find<T>(searchConfiguration);
}

So calling the Find method on a page object is drilling down in that scope and creates a new scope based on the found control. Would that cover the scenario you have in your article about good customers and sucky customers?

spelltwister commented 8 years ago

I'm not sure best way to exchange contact details, but I'm definitely open to talking more about this. I also stole the term from Selenium, but seemed to make more sense as 'modeling' the UI for testing than creating objects to power the UI so I took some liberty.

I'll have to study up more about how CUITe is setup so I'm not talking non-sense :) I would like to implement my page modeling abstraction using CUITe as the underlying searching technology to get a better understanding of how to use it.

FantasticFiasco commented 8 years ago

I'm accessible at mattias.kindborg@gmail.com. If you like to use another mean of contacting me, send me your details and we continue from there.

Regarding getting your head around CUITe, unfortunately we lack severely when it comes to documentation but we have many tests and I think you should start there. Within the solution there is a directory called Systems under test or similar, there you will find all tests categorized by feature.

Let me know if you experience any problems.

icnocop commented 8 years ago

I created a chat room here: https://gitter.im/icnocop/cuite :smiley:

FantasticFiasco commented 8 years ago

@icnocop Nice! Lets see if it attracts any attention.