Last active
January 29, 2017 18:30
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Coypu; | |
using Should; | |
namespace ConductOfCode.Specs | |
{ | |
public static class PageShouldExtensions | |
{ | |
public static void ShouldExist(this ElementScope element) | |
{ | |
element.Exists().ShouldBeTrue(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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