diff --git a/src/Samples/TestStack.BDDfy.Samples/TestStack.BDDfy.Samples.csproj b/src/Samples/TestStack.BDDfy.Samples/TestStack.BDDfy.Samples.csproj
index 803424c9..eb227dc8 100644
--- a/src/Samples/TestStack.BDDfy.Samples/TestStack.BDDfy.Samples.csproj
+++ b/src/Samples/TestStack.BDDfy.Samples/TestStack.BDDfy.Samples.csproj
@@ -14,7 +14,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
diff --git a/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.StepNameWillBeBuiltFromStepTitle.approved.txt b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.StepNameWillBeBuiltFromStepTitle.approved.txt
new file mode 100644
index 00000000..4d533684
--- /dev/null
+++ b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.StepNameWillBeBuiltFromStepTitle.approved.txt
@@ -0,0 +1,6 @@
+
+### Step name will be built from step title
+ i have a red car with a crazy horn
+ When i honk the horn at volume high
+ Then i verify diagnostics a red car honked crazy horn at high volume
+
diff --git a/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.StepNamesAreBuiltFromAllChanedMethods.approved.txt b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.StepNamesAreBuiltFromAllChanedMethods.approved.txt
new file mode 100644
index 00000000..26b83725
--- /dev/null
+++ b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.StepNamesAreBuiltFromAllChanedMethods.approved.txt
@@ -0,0 +1,6 @@
+
+### Step names are built from all chaned methods
+ Given i have a car with color red with horn crazy
+ When i honk the horn
+ Then i verify diagnostics a red car honked crazy horn
+
diff --git a/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.cs b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.cs
new file mode 100644
index 00000000..4410e187
--- /dev/null
+++ b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/StepsWithChainedMethods.cs
@@ -0,0 +1,57 @@
+using Shouldly;
+using TestStack.BDDfy.Reporters;
+using TestStack.BDDfy.Reporters.MarkDown;
+using TestStack.BDDfy.Tests.Reporters;
+using Xunit;
+
+namespace TestStack.BDDfy.Tests.Scanner.FluentScanner
+{
+ public class StepsWithChainedMethods
+ {
+ private SutStepBuilder _sutStepBuilder = new();
+ private class SutStepBuilder
+ {
+ public string state;
+ private string color;
+ private string horn;
+
+ public SutStepBuilder with_color(string color) { this.color = color; return this; }
+ public SutStepBuilder with_horn(string horn) { this.horn = horn; return this; }
+ internal void at_volume(string volume) { state+= $" at {volume} volume"; }
+ internal SutStepBuilder have_a_car() { state = "a"; return this; }
+ internal SutStepBuilder honk_the_horn() { state+= $" {color} car honked {horn} horn"; return this; }
+
+ internal void verify_diagnostics(string v) => state.ShouldBe(v);
+ }
+
+ [Fact]
+ public void StepNamesAreBuiltFromAllChanedMethods()
+ {
+ var story = this.Given(_ => i().have_a_car().with_color("red").with_horn("crazy"))
+ .When(_ => i().honk_the_horn())
+ .Then(_ => i().verify_diagnostics("a red car honked crazy horn"))
+ .LazyBDDfy();
+
+ var result = story.Run();
+ var model = new[] {result}.ToReportModel();
+ var fileReport = new FileReportModel(model);
+ ReportApprover.Approve(fileReport, new MarkDownReportBuilder());
+ }
+
+ [Fact]
+ public void StepNameWillBeBuiltFromStepTitle()
+ {
+ var story = this.Given(_ => i().have_a_car().with_color("red").with_horn("crazy"), "i have a {0} car with a {1} horn")
+ .When(_ => i().honk_the_horn().at_volume("high"))
+ .Then(_ => i().verify_diagnostics("a red car honked crazy horn at high volume"))
+ .LazyBDDfy();
+
+ var result = story.Run();
+ var model = new[] { result }.ToReportModel();
+ var fileReport = new FileReportModel(model);
+ ReportApprover.Approve(fileReport, new MarkDownReportBuilder());
+ }
+
+ private SutStepBuilder i() => _sutStepBuilder;
+ }
+}
diff --git a/src/TestStack.BDDfy.Tests/Startup.cs b/src/TestStack.BDDfy.Tests/Startup.cs
new file mode 100644
index 00000000..e4c67152
--- /dev/null
+++ b/src/TestStack.BDDfy.Tests/Startup.cs
@@ -0,0 +1,16 @@
+using System.Runtime.CompilerServices;
+using TestStack.BDDfy.Configuration;
+using TestStack.BDDfy.Tests;
+
+namespace TestStack.BDDfy.Samples
+{
+ public class Startup
+ {
+ [ModuleInitializer]
+ public static void Initialize()
+ {
+ Configurator.Processors.Add(() => new XUnitOutputReporter());
+ Configurator.Processors.ConsoleReport.Enable();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj b/src/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj
index f9fd8232..e4bb5a53 100644
--- a/src/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj
+++ b/src/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj
@@ -13,7 +13,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/src/TestStack.BDDfy/Abstractions/DefaultStepTitleFactory.cs b/src/TestStack.BDDfy/Abstractions/DefaultStepTitleFactory.cs
index 3aacce02..374ffde8 100644
--- a/src/TestStack.BDDfy/Abstractions/DefaultStepTitleFactory.cs
+++ b/src/TestStack.BDDfy/Abstractions/DefaultStepTitleFactory.cs
@@ -10,7 +10,7 @@ internal class DefaultStepTitleFactory : IStepTitleFactory
public bool IncludeInputsInStepTitle { get; set; } = true;
public StepTitle Create(
- string stepTextTemplate,
+ string? stepTextTemplate,
bool? includeInputsInStepTitle,
MethodInfo methodInfo,
StepArgument[] inputArguments,
@@ -19,7 +19,7 @@ public StepTitle Create(
{
string createTitle()
{
- var flatInputArray = inputArguments.Select(o => o.Value).FlattenArrays();
+ var flatInputArray = inputArguments.Select(o => o.Value!).FlattenArrays();
var name = methodInfo.Name;
var titleAttribute = methodInfo.GetCustomAttribute(true);
var executableAttribute = methodInfo.GetCustomAttribute(true);
diff --git a/src/TestStack.BDDfy/Abstractions/IStepTitleFactory.cs b/src/TestStack.BDDfy/Abstractions/IStepTitleFactory.cs
index 14c16bd5..3a264cbe 100644
--- a/src/TestStack.BDDfy/Abstractions/IStepTitleFactory.cs
+++ b/src/TestStack.BDDfy/Abstractions/IStepTitleFactory.cs
@@ -7,7 +7,7 @@ public interface IStepTitleFactory
bool IncludeInputsInStepTitle { get; set; }
public StepTitle Create(
- string stepTextTemplate,
+ string? stepTextTemplate,
bool? includeInputsInStepTitle,
MethodInfo methodInfo,
StepArgument[] inputArguments,
diff --git a/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs b/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs
index c5eabc5e..c65331c8 100644
--- a/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs
+++ b/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs
@@ -21,10 +21,10 @@ public static IEnumerable ExtractArguments(this Expression _arguments;
- private object _value;
+ private List _arguments = [];
+ private object? _value;
- public IEnumerable ExtractArguments(LambdaExpression methodCallExpression, object value)
+ public IEnumerable ExtractArguments(LambdaExpression methodCallExpression, object? value)
{
_arguments = [];
_value = value;
@@ -34,6 +34,8 @@ public IEnumerable ExtractArguments(LambdaExpression methodCallExp
protected override Expression VisitMethodCall(MethodCallExpression node)
{
+ if (node.Object is MethodCallExpression methodCallExpression) Visit(methodCallExpression);
+
var arguments = node.Arguments.Select(ExtractStepArgument);
_arguments.AddRange(arguments);
return node;
@@ -75,32 +77,32 @@ private StepArgument ExtractStepArgument(Expression a)
}
}
- private Func