0

I have a fluent API which I am trying to add another implementation for by passing in an enum to determine which object will be created and delegated to behind the scenes. It's for a UI testing framework, the fluent calls look like this:

CreateSomeBrowserObjectWrapper( BrowserType.NewImplementation )
    //'Click' here could be on a button, to launch the dialog we want to enter text into 
    .Click( x => x.FindByCssSelector( "dialogLauncherDivCssSelector" ) )
    .EnterTextIntoDialogBox( "some text" )
    .ClickDialog(DialogOptions.OK)
    .Assert( b => b.PageContains( "good job! you clicked the button and entered: 'some text'" ) );

The different implementations behave very differently. One can handle each call being made as the caller requests it but another needs to cache calls and then only perform them when certain conditions are met. In this example my problem implementation would need to cache the click and then pass the lambda to the call behind EnterTextIntoDialogBox(..) to do that all in one go. BUT not in every case, because the order of the chained calls and the call types is what determines that they need to be cached or not. Just clicking the element alone would be fine, that could be done as the caller invokes it.

What I am thinking is to try to add attributes to my methods behind the scenes:

[NonChainable]
public T EnterTextIntoDialogBox( string text )
{
    //do stuff
    return this as T;
}

And then use reflection somehow to analyse the fluent method call chain to see if anything called has this attribute and if so then I will handle them entire chain differently.

The only thing I can think of is to add a method which must be called at the end of the chain - then store the calls as they are invoked and analyse them. But then I will have references to delegates as opposed to the actual methods and so the attributes would be lost..

Does anyone have any ideas?

thisextendsthat
  • 1,266
  • 1
  • 9
  • 26
  • I don't understand your specific problem. Your user chains your methods in the wrong order (click before text) and you want it to magically work in the right order anyway? How would you even know it's the wrong order? – nvoigt May 04 '17 at 10:52
  • The first call to Click() is on a separate element (button, div, whatever) which launches a dialog box, into which the second call enters the text. Ill edit to make that clearer. – thisextendsthat May 04 '17 at 11:08

0 Answers0