Home > Software engineering >  c# how to make a conditional method chaining in fluent interface?
c# how to make a conditional method chaining in fluent interface?

Time:01-05

I'm developing .NET core app that using selenium, so I've designed the logic using fluent interface that make the code more readable and maintained.

I have a problem which is how to make a conditional logic in pipeline I followed this enter image description here here the source code

BasePage.cs

public class BasePage
    {
        public IWebDriver WebDriver { get; set; }
        public WebDriverWait DefaultWait { get; }

        public BasePage(IWebDriver webDriver)
        {
            WebDriver = webDriver;
            DefaultWait = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(1));
        }
    }

HomePage.cs

 public class HomePage: BasePage
    {
        
        private Select2 Driver => new Select2(WebDriver, WebDriver.FindElementIfExists(By.XPath("xpath")));

        private TextBox FirstName => new TextBox(WebDriver, WebDriver.FindElementIfExists(By.XPath("xpath")));

        private TextBox LastName => new TextBox(WebDriver, WebDriver.FindElementIfExists(By.XPath("xpath")));

        

        public HomePage(IWebDriver webDriver) : base(webDriver)
        {
        }
        
        public HomePage FillPostingInformationForm(Company company)
        {
            
            FirstName.SetText(company.ContactPerson.FirstName);
            LastName.SetText(company.ContactPerson.LastName);
            return new HomePage(WebDriver)
        }
        public HomePage IsDriverFound(Company company)
        {
            Driver.IsItemSelected(company.Drivers.First().FirstName   " "   company.Drivers.First().LastName);
            return new HomePage(WebDriver)
        }
        
    }

Select2.cs

public class BaseElement
    {
        public IWebDriver WebDriver { get; set; }
        public BaseElement(IWebDriver webDriver)
        {
            WebDriver = webDriver;
        }
    }
public class Select2 : BaseElement
    {
        public IWebElement _element;

        public Select2(IWebDriver webDriver, IWebElement element) : base(webDriver)
        {
            _element = element;
        }
        public bool IsItemSelected(string keyWord)
        {
            try
            {
                _element.Click();
                _element.SendKeys(keyWord);
                var option = WebDriver.FindElement(By.XPath(string.Format("//*[@{0} = '{1}']",
                                                "role", "option")));
                option.Click();
                _element.BodyClick();
                return true;
            }
            catch (NoSuchElementException ex)
            {
                Console.WriteLine(ex.Message);
               return false;
            }
        }
    }

BuilderExtensions.cs

public static class BuilderExtensions
    {
        public static T If<T>(this T t,bool cond, Func<T, T> builder)
          where T : HomePage
        {
            if (cond)
                return builder(t);
            return t;
        }
    }

and the call as following

public void Build()
        {
       HomePage HomePage => new HomePage(InitializeBrowser());
       
            var x = HomePage
                 .If(IsDriverFound(company), b => b.FillPostingInformationForm(company))
                 .If(!IsDriverFound(company), b => b
                 .GoToDriversPage());
       }

IsDriverFound(company) shown error, so what I did wrong here? and how to call this method inside if extension in the pipeline

CodePudding user response:

Probably you missed lambda parameter. The error says The name 'IsDriverFound' does not exist in the current context so there is no method in the context of Main, but it exists in HomePage object which is passed as lambda parameter into a method.

Check the second parameter - it's exactly the same. The lambda parameter is passed.

Just add x => x.IsDriverFound(company)

CodePudding user response:

Yo have a couple of issues here:

Return Type:

IsDriverFound() return a HomePage while if is expecting a bool.

you can either change it or create a new method:

public HomePage IsDriverFound(Company company) => 
Driver.IsItemSelected(company.Drivers.First().FirstName   " "   company.Drivers.First().LastName);

Class membership:

IsDriverFound() is a method of HomePage, so it can´t be called from outside of this class if it´s not referencing a HomePage instance. It should be:

HomePage.IsDriverFound(company);

That said, you can try this:

public void Build()
        {
            HomePage homePage => new HomePage(InitializeBrowser());
       
            var x = homePage
                 .If(homePage.IsDriverFound(company), b => b.FillPostingInformationForm(company))
                 .If(!homePage.IsDriverFound(company), b => b
                 .GoToDriversPage());
       }

Where IsDriverFound() return a bool or the method If expects a HomePage.

CodePudding user response:

Thank you all, I've solved by editing the following:

BuilderExtensions

public static class BuilderExtensions
{
   public static T If<T>(this T t, Func<T,bool> cond, Func<T, T> builder) where T : HomePage
    {
        if (cond.Invoke(t))
           return builder(t);
        return t;
    }
}

Condition

public bool IsDriverFound(Company company)
{
    return Driver.IsItemSelected(company.FirstName  " " company.LastName); 
}

pipeline execution

var x = HomePage
             .If(x => x.IsDriverFound(company), b => 
              b.FillPostingInformationForm(company))
             .If(x => x.IsDriverFound(company), b => b
             .GoToDriversPage());
  • Related