Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hlaueriksson/4106aa68a0483ad7c619619c4d4001d9 to your computer and use it in GitHub Desktop.
Save hlaueriksson/4106aa68a0483ad7c619619c4d4001d9 to your computer and use it in GitHub Desktop.
2017-01-31-reuse-specflow-features-to-test-both-via-api-and-browser
using System;
using ConductOfCode.Specs.Clients;
using Should;
using Should.Core.Assertions;
using TechTalk.SpecFlow;
namespace ConductOfCode.Specs
{
[Binding]
public class StackSteps : BaseSteps
{
private StackFacade facade;
private string result;
// Empty
[Given(@"an empty stack")]
public void GivenAnEmptyStack()
{
facade = new StackFacade();
facade.Clear();
}
[Then(@"it has no elements")]
public void ThenItHasNoElements()
{
facade.ToArray().ShouldBeEmpty();
}
[Then(@"it throws an exception when calling pop")]
public void ThenItThrowsAnExceptionWhenCallingPop()
{
var exception = Assert.Throws<AggregateException>(() => facade.Pop());
exception.InnerException.ShouldBeType<SwaggerException<Error>>();
}
[Then(@"it throws an exception when calling peek")]
public void ThenItThrowsAnExceptionWhenCallingPeek()
{
var exception = Assert.Throws<AggregateException>(() => facade.Peek());
exception.InnerException.ShouldBeType<SwaggerException<Error>>();
}
// Not empty
[Given(@"a non empty stack")]
public void GivenANonEmptyStack()
{
facade = new StackFacade();
facade.Clear();
facade.Push("1");
facade.Push("2");
facade.Push("3");
}
[When(@"calling peek")]
public void WhenCallingPeek()
{
result = facade.Peek();
}
[Then(@"it returns the top element")]
public void ThenItReturnsTheTopElement()
{
result.ShouldEqual("3");
}
[Then(@"it does not remove the top element")]
public void ThenItDoesNotRemoveTheTopElement()
{
facade.ToArray().ShouldContain("3");
}
[When(@"calling pop")]
public void WhenCallingPop()
{
result = facade.Pop();
}
[Then(@"it removes the top element")]
public void ThenItRemovesTheTopElement()
{
facade.ToArray().ShouldNotContain("3");
}
}
}
using Coypu;
namespace ConductOfCode.Specs
{
public class BasePage
{
protected static BrowserSession Browser;
protected BasePage()
{
Init();
}
public void Dispose()
{
Browser.Dispose();
Browser = null;
}
private void Init()
{
if (Browser != null) return;
var configuration = new SessionConfiguration
{
AppHost = "http://localhost",
Port = 5000,
Browser = Coypu.Drivers.Browser.Chrome
};
Browser = new BrowserSession(configuration);
}
}
}
using SpecResults;
using SpecResults.WebApp;
using TechTalk.SpecFlow;
namespace ConductOfCode.Specs
{
[Binding]
public class BaseSteps : ReportingStepDefinitions
{
[BeforeTestRun]
public static void BeforeTestRun()
{
var webApp = new WebAppReporter();
webApp.Settings.Title = "ConductOfCode.Specs";
Reporters.Add(webApp);
Reporters.FinishedReport += (sender, args) =>
{
var reporter = args.Reporter as WebAppReporter;
reporter?.WriteToFolder("ConductOfCode.Specs", true);
};
}
}
}
using Coypu;
using Should;
namespace ConductOfCode.Specs
{
public static class PageShouldExtensions
{
public static void ShouldExist(this ElementScope element)
{
element.Exists().ShouldBeTrue();
}
}
}
Feature: Stack
In order to support last-in-first-out (LIFO) operations
As an developer
I want to use a stack
Scenario: Empty stack
Given an empty stack
Then it has no elements
And it throws an exception when calling pop
And it throws an exception when calling peek
Scenario: Non empty stack
Given a non empty stack
When calling peek
Then it returns the top element
But it does not remove the top element
When calling pop
Then it returns the top element
And it removes the top element
using System.Collections.Generic;
using System.Linq;
using ConductOfCode.Specs.Clients;
namespace ConductOfCode.Specs
{
public class StackFacade
{
private readonly StackClient _client;
public StackFacade()
{
_client = new StackClient();
}
public void Clear()
{
_client.ClearAsync().Wait();
}
public string Peek()
{
return _client.PeekAsync().Result.Value;
}
public string Pop()
{
return _client.PopAsync().Result.Value;
}
public void Push(string item)
{
_client.PushAsync(new Item { Value = item }).Wait();
}
public IEnumerable<string> ToArray()
{
return _client.ToArrayAsync().Result.Select(x => x.Value);
}
}
}
using System.Collections.Generic;
using System.Linq;
using Coypu;
namespace ConductOfCode.Specs
{
public class StackPage : BasePage
{
public ElementScope Result => Browser.FindId("result");
public ElementScope Error => Browser.FindId("error");
public void Visit()
{
Browser.Visit("/");
}
public void Clear()
{
Browser.ClickButton("clear");
}
public ElementScope Peek()
{
Browser.ClickButton("peek");
return Result;
}
public ElementScope Pop()
{
Browser.ClickButton("pop");
return Result;
}
public void Push(string item)
{
Browser.FillIn("value").With(item);
Browser.ClickButton("push");
}
public IEnumerable<string> ToArray()
{
var items = Browser.FindAllCss(".item");
return items.Select(x => x.Text);
}
}
}
using System;
using System.Collections.Generic;
using Should;
using Should.Core.Assertions;
using TechTalk.SpecFlow;
namespace ConductOfCode.Specs
{
[Binding]
public class StackSteps : BaseSteps
{
private Stack<int> stack;
private int result;
// Empty
[Given(@"an empty stack")]
public void GivenAnEmptyStack()
{
stack = new Stack<int>();
}
[Then(@"it has no elements")]
public void ThenItHasNoElements()
{
stack.ShouldBeEmpty();
}
[Then(@"it throws an exception when calling pop")]
public void ThenItThrowsAnExceptionWhenCallingPop()
{
Assert.Throws<InvalidOperationException>(() => stack.Pop());
}
[Then(@"it throws an exception when calling peek")]
public void ThenItThrowsAnExceptionWhenCallingPeek()
{
Assert.Throws<InvalidOperationException>(() => stack.Peek());
}
// Not empty
[Given(@"a non empty stack")]
public void GivenANonEmptyStack()
{
stack = new Stack<int>(new[] { 1, 2, 3 });
}
[When(@"calling peek")]
public void WhenCallingPeek()
{
result = stack.Peek();
}
[Then(@"it returns the top element")]
public void ThenItReturnsTheTopElement()
{
result.ShouldEqual(3);
}
[Then(@"it does not remove the top element")]
public void ThenItDoesNotRemoveTheTopElement()
{
stack.ShouldContain(3);
}
[When(@"calling pop")]
public void WhenCallingPop()
{
result = stack.Pop();
}
[Then(@"it removes the top element")]
public void ThenItRemovesTheTopElement()
{
stack.ShouldNotContain(3);
}
}
}
using Should;
using TechTalk.SpecFlow;
namespace ConductOfCode.Specs
{
[Binding]
public class StackSteps// : BaseSteps
{
private StackPage page;
private string result;
[AfterScenario]
public void AfterScenario()
{
page?.Dispose();
}
// Empty
[Given(@"an empty stack")]
public void GivenAnEmptyStack()
{
page = new StackPage();
page.Visit();
page.Clear();
}
[Then(@"it has no elements")]
public void ThenItHasNoElements()
{
page.ToArray().ShouldBeEmpty();
}
[Then(@"it throws an exception when calling pop")]
public void ThenItThrowsAnExceptionWhenCallingPop()
{
page.Pop();
page.Error.ShouldExist();
}
[Then(@"it throws an exception when calling peek")]
public void ThenItThrowsAnExceptionWhenCallingPeek()
{
page.Peek();
page.Error.ShouldExist();
}
// Not empty
[Given(@"a non empty stack")]
public void GivenANonEmptyStack()
{
page = new StackPage();
page.Visit();
page.Clear();
page.Push("1");
page.Push("2");
page.Push("3");
}
[When(@"calling peek")]
public void WhenCallingPeek()
{
result = page.Peek().Text;
}
[Then(@"it returns the top element")]
public void ThenItReturnsTheTopElement()
{
result.ShouldEqual("3");
}
[Then(@"it does not remove the top element")]
public void ThenItDoesNotRemoveTheTopElement()
{
page.ToArray().ShouldContain("3");
}
[When(@"calling pop")]
public void WhenCallingPop()
{
result = page.Pop().Text;
}
[Then(@"it removes the top element")]
public void ThenItRemovesTheTopElement()
{
page.ToArray().ShouldNotContain("3");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment