diff --git a/pom.sln b/pom.sln
new file mode 100644
index 0000000..31cafef
--- /dev/null
+++ b/pom.sln
@@ -0,0 +1,17 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pom", "pom\pom.csproj", "{EC01B297-C25B-446E-96A4-E2153A5305CC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EC01B297-C25B-446E-96A4-E2153A5305CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC01B297-C25B-446E-96A4-E2153A5305CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC01B297-C25B-446E-96A4-E2153A5305CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC01B297-C25B-446E-96A4-E2153A5305CC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/pom/.DS_Store b/pom/.DS_Store
new file mode 100644
index 0000000..06b90bd
Binary files /dev/null and b/pom/.DS_Store differ
diff --git a/pom/Components/LandingComponent.cs b/pom/Components/LandingComponent.cs
new file mode 100644
index 0000000..9330a4b
--- /dev/null
+++ b/pom/Components/LandingComponent.cs
@@ -0,0 +1,20 @@
+using System;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Support.UI;
+
+namespace pom.Components
+{
+ public class LandingComponent
+ {
+ private IWebDriver webDriver;
+ private WebDriverWait webDriverWait;
+ private IJavaScriptExecutor jsExecutor;
+
+ public LandingComponent(IWebDriver _webDriver)
+ {
+ webDriver = _webDriver;
+ webDriverWait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(30));
+ jsExecutor = (IJavaScriptExecutor)webDriver;
+ }
+ }
+}
\ No newline at end of file
diff --git a/pom/Components/LoginComponent.cs b/pom/Components/LoginComponent.cs
new file mode 100644
index 0000000..4e36a8d
--- /dev/null
+++ b/pom/Components/LoginComponent.cs
@@ -0,0 +1,36 @@
+using System;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Support.UI;
+
+namespace pom.Components
+{
+ public class LoginComponent
+ {
+ private IWebDriver webDriver;
+ private WebDriverWait webDriverWait;
+ private IJavaScriptExecutor jsExecutor;
+
+ public LoginComponent(IWebDriver _webDriver)
+ {
+ webDriver = _webDriver;
+ webDriverWait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(30));
+ jsExecutor = (IJavaScriptExecutor)webDriver;
+ }
+
+ public void GoToLogin()
+ {
+ webDriver.Navigate().GoToUrl("Some Site");
+ }
+
+ public void EnterUserCredentials(string username, string password)
+ {
+ webDriver.FindElement(By.Name("username")).SendKeys(username);
+ webDriver.FindElement(By.Name("password")).SendKeys(password);
+ }
+
+ public void SubmitLoginForm()
+ {
+ webDriver.FindElement(By.Name("login")).Click();
+ }
+ }
+}
\ No newline at end of file
diff --git a/pom/Components/NavigationComponent.cs b/pom/Components/NavigationComponent.cs
new file mode 100644
index 0000000..7198405
--- /dev/null
+++ b/pom/Components/NavigationComponent.cs
@@ -0,0 +1,32 @@
+using System;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Support.UI;
+
+namespace pom.Components
+{
+ public class NavigationComponent
+ {
+ private IWebDriver webDriver;
+ private WebDriverWait webDriverWait;
+
+ public NavigationComponent(IWebDriver _webDriver)
+ {
+ webDriver = _webDriver;
+ webDriverWait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(30));
+ }
+
+ public string GetNavAccountName()
+ {
+ //Example of getting an account name
+ var accountNav = webDriver.FindElement(By.Id("account-nav")).FindElements(By.TagName("span"))[1];
+ string accountNavName = accountNav.GetAttribute("innerHTML");
+
+ return (accountNavName);
+ }
+
+ public void GoToVideos()
+ {
+ //Goes to videos page
+ }
+ }
+}
diff --git a/pom/Components/VideoComponent.cs b/pom/Components/VideoComponent.cs
new file mode 100644
index 0000000..da95295
--- /dev/null
+++ b/pom/Components/VideoComponent.cs
@@ -0,0 +1,37 @@
+using System;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Support.UI;
+
+namespace pom.Components
+{
+ public class VideoComponent
+ {
+ private IWebDriver webDriver;
+ private WebDriverWait webDriverWait;
+ private IJavaScriptExecutor jsExecutor;
+
+ public VideoComponent(IWebDriver _webDriver)
+ {
+ webDriver = _webDriver;
+ webDriverWait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(30));
+ jsExecutor = (IJavaScriptExecutor)webDriver;
+ }
+
+ public void PlayVideo()
+ {
+ //Plays Video
+ }
+
+ public void PauseVideo()
+ {
+ //Pauses Video
+ }
+
+ public bool GetVideoPlayState()
+ {
+ //Get video play sate from player
+ return (false);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/pom/Components/VideosComponent.cs b/pom/Components/VideosComponent.cs
new file mode 100644
index 0000000..5c2ff56
--- /dev/null
+++ b/pom/Components/VideosComponent.cs
@@ -0,0 +1,29 @@
+using System;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Support.UI;
+
+namespace pom.Components
+{
+ public class VideosComponent
+ {
+ private IWebDriver webDriver;
+ private WebDriverWait webDriverWait;
+ private IJavaScriptExecutor jsExecutor;
+
+ public VideosComponent(IWebDriver _webDriver)
+ {
+ webDriver = _webDriver;
+ webDriverWait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(30));
+ jsExecutor = (IJavaScriptExecutor)webDriver;
+ }
+
+ public void SelectVideo()
+ {
+ webDriverWait.Until(drv => drv.FindElement(By.ClassName("video-loop-video-title")));
+
+ var videos = webDriver.FindElements(By.ClassName("video-loop-video-title"));
+ var video = videos[0];
+ video.Click();
+ }
+ }
+}
\ No newline at end of file
diff --git a/pom/Features/.DS_Store b/pom/Features/.DS_Store
new file mode 100644
index 0000000..6ed9a50
Binary files /dev/null and b/pom/Features/.DS_Store differ
diff --git a/pom/Features/Login/Login.cs b/pom/Features/Login/Login.cs
new file mode 100644
index 0000000..7f2c79f
--- /dev/null
+++ b/pom/Features/Login/Login.cs
@@ -0,0 +1,59 @@
+using FluentAssertions;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Chrome;
+using pom.Components;
+using TechTalk.SpecFlow;
+
+namespace pom.Features.Login
+{
+ [Binding]
+ public class Login
+ {
+ private IWebDriver webDriver;
+ private LoginComponent loginComponent;
+ private NavigationComponent navigationComponent;
+
+ [BeforeScenario]
+ public void SetupTest()
+ {
+ webDriver = GetWebDriver();
+
+ loginComponent = new LoginComponent(webDriver);
+ navigationComponent = new NavigationComponent(webDriver);
+ }
+
+ public IWebDriver GetWebDriver()
+ {
+ /* Yes we could put this into a factory and use DI but KISS for now. */
+ ChromeOptions options = new ChromeOptions();
+ options.AddArguments("start-maximized");
+
+ IWebDriver ChromeWebDriver = new ChromeDriver(options);
+ return ChromeWebDriver;
+ }
+
+ [Given(@"I am at the login page")]
+ public void GivenIAmAtTheLoginPage()
+ {
+ loginComponent.GoToLogin();
+ }
+
+ [Given(@"I have entered my credentials")]
+ public void AndIHaveEnteredMyCredentials()
+ {
+ loginComponent.EnterUserCredentials("Information", "Information");
+ }
+
+ [When(@"I press login")]
+ public void WhenIPressLogin()
+ {
+ loginComponent.SubmitLoginForm();
+ }
+
+ [Then(@"the I have logged into the application")]
+ public void ThenTheIHaveLoggedIntoTheApplication()
+ {
+ navigationComponent.GetNavAccountName().Should().Be("user");
+ }
+ }
+}
\ No newline at end of file
diff --git a/pom/Features/Login/Login.feature b/pom/Features/Login/Login.feature
new file mode 100644
index 0000000..14cd228
--- /dev/null
+++ b/pom/Features/Login/Login.feature
@@ -0,0 +1,10 @@
+Feature: Login
+ In order to use the application
+ As a user
+ I want to log into the application
+
+Scenario: Log into the application
+ Given I am at the login page
+ And I have entered my credentials
+ When I press login
+ Then the I have logged into the application
\ No newline at end of file
diff --git a/pom/Features/Login/Login.feature.cs b/pom/Features/Login/Login.feature.cs
new file mode 100644
index 0000000..c852109
--- /dev/null
+++ b/pom/Features/Login/Login.feature.cs
@@ -0,0 +1,121 @@
+// ------------------------------------------------------------------------------
+//
+// This code was generated by SpecFlow (https://www.specflow.org/).
+// SpecFlow Version:3.3.0.0
+// SpecFlow Generator Version:3.1.0.0
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+#region Designer generated code
+#pragma warning disable
+namespace pom.Features.Login
+{
+ using TechTalk.SpecFlow;
+ using System;
+ using System.Linq;
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.3.0.0")]
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [NUnit.Framework.TestFixtureAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Login")]
+ public partial class LoginFeature
+ {
+
+ private TechTalk.SpecFlow.ITestRunner testRunner;
+
+ private string[] _featureTags = ((string[])(null));
+
+#line 1 "Login.feature"
+#line hidden
+
+ [NUnit.Framework.OneTimeSetUpAttribute()]
+ public virtual void FeatureSetup()
+ {
+ testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
+ TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Login", "\tIn order to use the application\n\tAs a user\n\tI want to log into the application", ProgrammingLanguage.CSharp, ((string[])(null)));
+ testRunner.OnFeatureStart(featureInfo);
+ }
+
+ [NUnit.Framework.OneTimeTearDownAttribute()]
+ public virtual void FeatureTearDown()
+ {
+ testRunner.OnFeatureEnd();
+ testRunner = null;
+ }
+
+ [NUnit.Framework.SetUpAttribute()]
+ public virtual void TestInitialize()
+ {
+ }
+
+ [NUnit.Framework.TearDownAttribute()]
+ public virtual void TestTearDown()
+ {
+ testRunner.OnScenarioEnd();
+ }
+
+ public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
+ {
+ testRunner.OnScenarioInitialize(scenarioInfo);
+ testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext);
+ }
+
+ public virtual void ScenarioStart()
+ {
+ testRunner.OnScenarioStart();
+ }
+
+ public virtual void ScenarioCleanup()
+ {
+ testRunner.CollectScenarioErrors();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Log into the application")]
+ public virtual void LogIntoTheApplication()
+ {
+ string[] tagsOfScenario = ((string[])(null));
+ System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary();
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Log into the application", null, tagsOfScenario, argumentsOfScenario);
+#line 6
+this.ScenarioInitialize(scenarioInfo);
+#line hidden
+ bool isScenarioIgnored = default(bool);
+ bool isFeatureIgnored = default(bool);
+ if ((tagsOfScenario != null))
+ {
+ isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any();
+ }
+ if ((this._featureTags != null))
+ {
+ isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any();
+ }
+ if ((isScenarioIgnored || isFeatureIgnored))
+ {
+ testRunner.SkipScenario();
+ }
+ else
+ {
+ this.ScenarioStart();
+#line 7
+ testRunner.Given("I am at the login page", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
+#line hidden
+#line 8
+ testRunner.And("I have entered my credentials", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
+#line hidden
+#line 9
+ testRunner.When("I press login", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
+#line hidden
+#line 10
+ testRunner.Then("the I have logged into the application", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
+#line hidden
+ }
+ this.ScenarioCleanup();
+ }
+ }
+}
+#pragma warning restore
+#endregion
diff --git a/pom/Features/Videos/.DS_Store b/pom/Features/Videos/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/pom/Features/Videos/.DS_Store differ
diff --git a/pom/Features/Videos/Videos.cs b/pom/Features/Videos/Videos.cs
new file mode 100644
index 0000000..423c78f
--- /dev/null
+++ b/pom/Features/Videos/Videos.cs
@@ -0,0 +1,68 @@
+using FluentAssertions;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Chrome;
+using pom.Components;
+using TechTalk.SpecFlow;
+
+namespace pom.Features.Videos
+{
+ [Binding]
+ public class Videos
+ {
+ private IWebDriver webDriver;
+ private LoginComponent loginComponent;
+ private NavigationComponent navigationComponent;
+ private VideosComponent videosComponent;
+ private VideoComponent videoComponent;
+
+ [BeforeScenario]
+ public void setupTest()
+ {
+ webDriver = GetWebDriver();
+
+ loginComponent = new LoginComponent(webDriver);
+ navigationComponent = new NavigationComponent(webDriver);
+ videosComponent = new VideosComponent(webDriver);
+ videoComponent = new VideoComponent(webDriver);
+ }
+
+ public IWebDriver GetWebDriver()
+ {
+ /* Yes we could put this into a factory and use DI but KISS for now. */
+ ChromeOptions options = new ChromeOptions();
+ options.AddArguments("start-maximized");
+
+ IWebDriver ChromeWebDriver = new ChromeDriver(options);
+ return ChromeWebDriver;
+ }
+
+ [Given(@"I have logged into the application")]
+ public void GivenIHaveLoggedIntoTheApplication()
+ {
+ loginComponent.GoToLogin();
+ loginComponent.EnterUserCredentials("", "");
+ loginComponent.SubmitLoginForm();
+ }
+
+ [Given(@"I have started playing a video")]
+ public void AndIHaveStartedPlayingAVideo()
+ {
+ navigationComponent.GoToVideos();
+ videosComponent.SelectVideo();
+ videoComponent.PlayVideo();
+ }
+
+ [When(@"I press pause")]
+ public void WhenIPressPause()
+ {
+ videoComponent.PauseVideo();
+ videoComponent.GetVideoPlayState().Should().Be(true);
+ }
+
+ [Then(@"the video should be paused")]
+ public void ThenTheVideoShouldBePaused()
+ {
+ videoComponent.GetVideoPlayState().Should().Be(true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/pom/Features/Videos/Videos.feature b/pom/Features/Videos/Videos.feature
new file mode 100644
index 0000000..c391f3e
--- /dev/null
+++ b/pom/Features/Videos/Videos.feature
@@ -0,0 +1,10 @@
+Feature: Video Controls
+ In order to control a video
+ As a user
+ I want to manipulate video controls
+
+Scenario: Pause video playback
+ Given I have logged into the application
+ And I have started playing a video
+ When I press pause
+ Then the video should be paused
\ No newline at end of file
diff --git a/pom/Features/Videos/Videos.feature.cs b/pom/Features/Videos/Videos.feature.cs
new file mode 100644
index 0000000..3c16910
--- /dev/null
+++ b/pom/Features/Videos/Videos.feature.cs
@@ -0,0 +1,121 @@
+// ------------------------------------------------------------------------------
+//
+// This code was generated by SpecFlow (https://www.specflow.org/).
+// SpecFlow Version:3.3.0.0
+// SpecFlow Generator Version:3.1.0.0
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+#region Designer generated code
+#pragma warning disable
+namespace pom.Features.Videos
+{
+ using TechTalk.SpecFlow;
+ using System;
+ using System.Linq;
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.3.0.0")]
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [NUnit.Framework.TestFixtureAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Video Controls")]
+ public partial class VideoControlsFeature
+ {
+
+ private TechTalk.SpecFlow.ITestRunner testRunner;
+
+ private string[] _featureTags = ((string[])(null));
+
+#line 1 "Videos.feature"
+#line hidden
+
+ [NUnit.Framework.OneTimeSetUpAttribute()]
+ public virtual void FeatureSetup()
+ {
+ testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
+ TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Video Controls", "\tIn order to control a video\n\tAs a user\n\tI want to manipulate video controls", ProgrammingLanguage.CSharp, ((string[])(null)));
+ testRunner.OnFeatureStart(featureInfo);
+ }
+
+ [NUnit.Framework.OneTimeTearDownAttribute()]
+ public virtual void FeatureTearDown()
+ {
+ testRunner.OnFeatureEnd();
+ testRunner = null;
+ }
+
+ [NUnit.Framework.SetUpAttribute()]
+ public virtual void TestInitialize()
+ {
+ }
+
+ [NUnit.Framework.TearDownAttribute()]
+ public virtual void TestTearDown()
+ {
+ testRunner.OnScenarioEnd();
+ }
+
+ public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
+ {
+ testRunner.OnScenarioInitialize(scenarioInfo);
+ testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext);
+ }
+
+ public virtual void ScenarioStart()
+ {
+ testRunner.OnScenarioStart();
+ }
+
+ public virtual void ScenarioCleanup()
+ {
+ testRunner.CollectScenarioErrors();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Pause video playback")]
+ public virtual void PauseVideoPlayback()
+ {
+ string[] tagsOfScenario = ((string[])(null));
+ System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary();
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Pause video playback", null, tagsOfScenario, argumentsOfScenario);
+#line 6
+this.ScenarioInitialize(scenarioInfo);
+#line hidden
+ bool isScenarioIgnored = default(bool);
+ bool isFeatureIgnored = default(bool);
+ if ((tagsOfScenario != null))
+ {
+ isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any();
+ }
+ if ((this._featureTags != null))
+ {
+ isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any();
+ }
+ if ((isScenarioIgnored || isFeatureIgnored))
+ {
+ testRunner.SkipScenario();
+ }
+ else
+ {
+ this.ScenarioStart();
+#line 7
+ testRunner.Given("I have logged into the application", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
+#line hidden
+#line 8
+ testRunner.And("I have started playing a video", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
+#line hidden
+#line 9
+ testRunner.When("I press pause", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
+#line hidden
+#line 10
+ testRunner.Then("the video should be paused", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
+#line hidden
+ }
+ this.ScenarioCleanup();
+ }
+ }
+}
+#pragma warning restore
+#endregion
diff --git a/pom/pom.csproj b/pom/pom.csproj
new file mode 100644
index 0000000..667900b
--- /dev/null
+++ b/pom/pom.csproj
@@ -0,0 +1,51 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Login.feature
+
+
+ Videos.feature
+
+
+
+
+ False
+ SpecFlowSingleFileGenerator
+ Login.feature.cs
+
+
+ False
+ SpecFlowSingleFileGenerator
+ Landing.feature.cs
+
+
+ False
+ SpecFlowSingleFileGenerator
+ Videos.feature.cs
+
+
+