0

I have the following code in my SeleniumSteps.cs code I am trying to get the AfterScenario to fire on debugging these tests

using PrivateDomain;
using Machine.Specifications;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using TechTalk.SpecFlow;

namespace Functional.Steps
{
    public class SeleniumSteps : PrivateDomain.Steps.SeleniumSteps
    {
        #region Hooks
        [BeforeScenario]
        public void Before()
        {
            // before 
        }

        [AfterTestRun, Scope(Tag = null)]
        public new static void AfterTestRun()
        {
            // after testrun
        }

        [AfterScenario]
        public void AfterScenarioErrorScreenshot()
        {
            // after scenario
        }

        #endregion
    }
}





using OpenQA.Selenium;
using TechTalk.SpecFlow;

namespace PrivateDomain.Steps
{
    [Binding]
    [Scope(Tag = "Selenium")]
    public class SeleniumSteps
    {
        protected static IWebDriver webDriver;

        public SeleniumSteps();

        public virtual IWebDriver WebDriver { get; }

        [AfterTestRun]
        [Scope(Tag = null)]
        public static void AfterTestRun();

        [AfterScenarioAttribute(new[] { })]
        public virtual void AfterScenario();

    }
}

My feature file looks like this: (Details removed)

@Customer_Portal
Feature: Account Management - Registration
    In order to create an account
    As a customer
    I want to register my details with the application

Scenario: Register

    # Registration Form
    When I navigate to "/Customer/Account/Register"
    // more code...


Scenario: Required Fields

    // more code...

Scenario: Invalid Contact Details

    // more code...

Scenario: Insufficient Password Strength

    // more code...

Scenario: Password Mismatch

    // more code...

Scenario: Already Registered

    // more code...

Scenario: Invalid Activation

    // more code...

Scenario: Already Activated

   // more code...

When I debug a test, I can see the debugger hitting the AfterTestRun portion. However, neither the BeforeScenario or the AfterScenario are being exercised.

Can someone tell me what I'm doing wrong?

dstewart101
  • 1,084
  • 1
  • 16
  • 38

2 Answers2

5

First, as Sandesh noted in his answer, you are missing [Binding] attribute for your SeleniumSteps subclass. It's not enough to have [Binding] only in base class, you must apply it to every class where are your hook methods or step definitions (bindings), because that is the way how specflow is searching for hooks and bindings under the hood. It is like scope identifier. If you miss to place [Binding] attribute to class, specflow will not search for potential hook methods or bindings in that class. Link on documentation: https://specflow.org/documentation/Hooks/

This link can be useful also. Check answer given by RunOfTheShipe: Specflow test step inheritance causes "Ambiguous step definitions"

Stefan
  • 1,608
  • 2
  • 14
  • 21
  • Thanks for the reply - [Binding] attribute is present. I tried the steps you mention but unfortunately the same result. Would you know why AfterTestRun is successfully called but the others aren't? – dstewart101 Dec 31 '19 at 10:21
  • No, i wouldn't know why is like that. Can you edit your question, and provide a bit more information about class where your hooks are defined? And is that class of yours used anywhere else - for inheritance? – Stefan Dec 31 '19 at 10:25
  • can you show your .feature file? And tags associated with feature and scenarios. Please update your question with it. – Stefan Dec 31 '19 at 10:51
  • 1
    Ok, there are few solutions.Try next: 1. can you remove `[Scope(Tag = "Selenium")]` from `public class SeleniumSteps`, or 2. just add another Scope attribute for same class, like : `[Scope(Tag = "Customer_Portal")]`, or 3. just add new `@Selenium` tag to your `Feature: Account Management - Registration` – Stefan Dec 31 '19 at 11:10
  • thanks guys - suggestion number 3 is what worked for me. the base class is actually coming from a dll so I can't change that. adding the tag in my feature file worked for me – dstewart101 Dec 31 '19 at 11:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205145/discussion-between-stefan-zivkovic-and-dstewart101). – Stefan Dec 31 '19 at 11:29
2

You have missed [Binding] attribute in your SeleniumSteps

    namespace Functional.Steps
    {
         [Binding]
        public class SeleniumSteps : PrivateDomain.Steps.SeleniumSteps
        {
            #region Hooks
            [BeforeScenario]
            public void Before()
            {
                // before 
            }
}
}
Sandesh A D
  • 162
  • 2
  • 12