How to get the current executing step information in Specflow
Asked Answered
P

3

8

We are trying to take screenshots for each step.

Everything works fine. But we are not able to correlate the screenshots to the steps which created them.

What we would like is something like FeatureContext.FeatureInfo and ScenarioContext.ScenarioInfo. But at individual step level. So that we can tag the screenshots accordingly.

Pre answered 4/11, 2014 at 0:23 Comment(0)
D
9

EDIT

Classes have been added which expose:

ScenarioStepContext.StepInfo.Text and ScenarioStepContext.StepInfo.StepDefinitionType

Which should give you what you want.

Original answer This is not currently possible, although I have just (yesterday) submitted a pull request which adds this functionality. If you are happy with building specflow yourself then you can clone my fork of the specflow repo and switch to the ScenarioStepContext branch, then open the TechTalk.Specflow_VS2013.sln and build the project yourself.

First you need to give specflow a new version number for the nuget package. Open the SpecFlow.nuspec file and edit the version to be something higher than the current version (I used 1.9.3.4), then build the solution (you need to installed the VS2013 SDK, and other VS SDKs if you want to build those versions).

Once the solution is built, you will need to install the vsix from

\SpecFlow\IdeIntegration\Vs2013Integration\bin\Debug\TechTalk.SpecFlow.Vs2013Integration.vsix

and then add the nuget package from

\SpecFlow\Installer\NuGetPackages\bin\SpecFlow.1.9.3.4.nupkg.

Once you have done this you will be able to access ScenarioStepContext.StepInfo.Text and ScenarioStepContext.StepInfo.StepDefinitionType to be able to tag the elements you want with the current step details.

We are currently using this, but please raise any issues on the PR at the main Specflow github page and I'll fix them if I can.

Decontaminate answered 4/11, 2014 at 9:14 Comment(1)
This was really helpful for me. It also showed me how to expose the Table values easily too.Particularly
P
4

Implementing your own LogTraceListener allows you to get the current Step Definition:

public class LogTraceListener : ITraceListener
{
    static public string LastGherkinMessage;

    public void WriteTestOutput(string message)
    {
        LastGherkinMessage = message;

        Console.WriteLine(message);
    }

    public void WriteToolOutput(string message)
    {
       Console.WriteLine(message);
    }
}

This needs to be registered in the SpecFlow section in App.Config:

<specFlow>
    <trace listener="MyNameSpace.LogTraceListener, MyAssemblyName" />
    <unitTestProvider name="NUnit" />
</specFlow>

Having done this, the LastGherkinMessage property will contain the text of the Step Definition just entered. You can access this from within the Step Definition or from anywhere else.

Particiaparticipant answered 13/5, 2015 at 12:10 Comment(0)
K
1

I'm a bit late to the party, but this method will return a string that contains the currently running step text:

private static string GetCurrentPositionText()
    {
        int currentPositionText = 0;
        try
        {
            var frames = new StackTrace(true).GetFrames();
            if (frames != null)
            {
                var featureFileFrame = frames.FirstOrDefault(f =>
                                                             f.GetFileName() != null &&
                                                             f.GetFileName().EndsWith(".feature"));

                if (featureFileFrame != null)
                {
                    var lines = File.ReadAllLines(featureFileFrame.GetFileName());
                    const int frameSize = 20;
                    int currentLine = featureFileFrame.GetFileLineNumber() - 1;
                    int minLine = Math.Max(0, currentLine - frameSize);
                    int maxLine = Math.Min(lines.Length - 1, currentLine + frameSize);

                    for (int lineNo = currentLine - 1; lineNo >= minLine; lineNo--)
                    {
                        if (lines[lineNo].TrimStart().StartsWith("Scenario:"))
                        {
                            minLine = lineNo + 1;
                            break;
                        }
                    }

                    for (int lineNo = currentLine + 1; lineNo <= maxLine; lineNo++)
                    {
                        if (lines[lineNo].TrimStart().StartsWith("Scenario:"))
                        {
                            maxLine = lineNo - 1;
                            break;
                        }
                    }

                    for (int lineNo = minLine; lineNo <= maxLine; lineNo++)
                    {
                        if (lineNo == currentLine)
                        {
                            currentPositionText = lineNo - minLine;
                            return String.Format("->" + lines[lineNo]);
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex, "GetCurrentPositionText");
        }

        return String.Format("(Unable to detect current step)");
    }

Taken from a post Gaspar Nagy made some time ago when a similar question was asked, and modified slightly to only return the string of the current step.

Kumler answered 5/6, 2015 at 9:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.