From 9a334565862467350f25321bfac97c5a6554db17 Mon Sep 17 00:00:00 2001 From: Mathias Johansson Date: Sat, 20 Jan 2018 09:30:16 +0100 Subject: [PATCH] Added UI tests for admin and normal user + some ui tst refactoring --- .../Helpers/TestDataManager.cs | 20 +++++++ .../Helpers/Extensions/WebDriverExtensions.cs | 53 +++++++++---------- .../Pages/Account/ActivationRequestedPage.cs | 2 +- .../Pages/Account/LoginPage.cs | 10 ++-- .../Pages/Account/LogoutPage.cs | 2 +- .../Pages/Account/RegisterPage.cs | 2 +- .../Pages/ApplicationPage.cs | 29 ++++++++++ .../Coderr.Server.Web.Tests/Pages/BasePage.cs | 4 +- .../Coderr.Server.Web.Tests/Pages/IPage.cs | 8 +++ .../Pages/PageHelper.cs | 25 +++++++++ .../Tests/AdminUserTests.cs | 35 ++++++++++++ .../Tests/ConfigureApplicationPageTests.cs | 23 ++++---- .../Tests/HomePageTests.cs | 19 ++++--- .../Tests/IncidentsPageTests.cs | 16 ++++-- .../Tests/LoggedInTest.cs | 13 ++--- .../Tests/LoginPageTests.cs | 4 +- .../Tests/UserTests.cs | 50 +++++++++++++++++ .../codeRR.Server.Web.Tests.csproj | 2 +- 18 files changed, 250 insertions(+), 67 deletions(-) create mode 100644 src/Server/Coderr.Server.Web.Tests/Pages/ApplicationPage.cs create mode 100644 src/Server/Coderr.Server.Web.Tests/Pages/IPage.cs create mode 100644 src/Server/Coderr.Server.Web.Tests/Pages/PageHelper.cs create mode 100644 src/Server/Coderr.Server.Web.Tests/Tests/AdminUserTests.cs create mode 100644 src/Server/Coderr.Server.Web.Tests/Tests/UserTests.cs diff --git a/src/Server/Coderr.Server.SqlServer.Tests/Helpers/TestDataManager.cs b/src/Server/Coderr.Server.SqlServer.Tests/Helpers/TestDataManager.cs index f89c1c07..1d85e571 100644 --- a/src/Server/Coderr.Server.SqlServer.Tests/Helpers/TestDataManager.cs +++ b/src/Server/Coderr.Server.SqlServer.Tests/Helpers/TestDataManager.cs @@ -109,6 +109,26 @@ public void CreateUserAndApplication(out int accountId, out int applicationId) } } + public void CreateUser(TestUser testUser, int applicationId) + { + using (var uow = CreateUnitOfWork()) + { + var accountRepos = new AccountRepository(uow); + var account = new Account(testUser.Username, testUser.Password) { Email = testUser.Email }; + account.Activate(); + accountRepos.Create(account); + var userRepos = new UserRepository(uow); + var user = new User(account.Id, testUser.Username) { EmailAddress = testUser.Email }; + userRepos.CreateAsync(user).GetAwaiter().GetResult(); + + var appRepos = new ApplicationRepository(uow); + var member = new ApplicationTeamMember(applicationId, account.Id, "Admin"); + appRepos.CreateAsync(member).GetAwaiter().GetResult(); + + uow.SaveChanges(); + } + } + private void EnsureServerSettings(string baseUrl) { using (var con = _connectionFactory()) diff --git a/src/Server/Coderr.Server.Web.Tests/Helpers/Extensions/WebDriverExtensions.cs b/src/Server/Coderr.Server.Web.Tests/Helpers/Extensions/WebDriverExtensions.cs index f749751c..8bc6221a 100644 --- a/src/Server/Coderr.Server.Web.Tests/Helpers/Extensions/WebDriverExtensions.cs +++ b/src/Server/Coderr.Server.Web.Tests/Helpers/Extensions/WebDriverExtensions.cs @@ -1,38 +1,11 @@ using System; using OpenQA.Selenium; using OpenQA.Selenium.Support.UI; -using Xunit.Sdk; namespace codeRR.Server.Web.Tests.Helpers.Extensions { public static class WebDriverExtensions { - public static bool ElementIsPresent(this IWebDriver driver, By by) - { - var present = false; - try - { - present = driver.FindElement(by).Displayed; - } - catch (NoSuchElementException) - { - } - return present; - } - - public static bool ElementIsPresent(this IWebDriver driver, IWebElement element) - { - var present = false; - try - { - present = element.Displayed; - } - catch (NoSuchElementException) - { - } - return present; - } - public static bool WaitUntilElementIsPresent(this IWebDriver driver, By by, int timeout = 5) { var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)); @@ -59,5 +32,31 @@ public static string WaitUntilTitleEquals(this IWebDriver driver, string title, return driver.Title; } + + private static bool ElementIsPresent(this IWebDriver driver, By by) + { + var present = false; + try + { + present = driver.FindElement(by).Displayed; + } + catch (NoSuchElementException) + { + } + return present; + } + + private static bool ElementIsPresent(this IWebDriver driver, IWebElement element) + { + var present = false; + try + { + present = element.Displayed; + } + catch (NoSuchElementException) + { + } + return present; + } } } diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/Account/ActivationRequestedPage.cs b/src/Server/Coderr.Server.Web.Tests/Pages/Account/ActivationRequestedPage.cs index 7d3e506c..b3405055 100644 --- a/src/Server/Coderr.Server.Web.Tests/Pages/Account/ActivationRequestedPage.cs +++ b/src/Server/Coderr.Server.Web.Tests/Pages/Account/ActivationRequestedPage.cs @@ -5,7 +5,7 @@ namespace codeRR.Server.Web.Tests.Pages.Account { public class ActivationRequestedPage : BasePage { - public ActivationRequestedPage(IWebDriver webDriver) : base(webDriver, (string) "Account/ActivationRequested", (string) "Account registered - codeRR") + public ActivationRequestedPage(IWebDriver webDriver) : base(webDriver, "Account/ActivationRequested", "Account registered - codeRR") { } diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/Account/LoginPage.cs b/src/Server/Coderr.Server.Web.Tests/Pages/Account/LoginPage.cs index 2a803b4a..b7ce807b 100644 --- a/src/Server/Coderr.Server.Web.Tests/Pages/Account/LoginPage.cs +++ b/src/Server/Coderr.Server.Web.Tests/Pages/Account/LoginPage.cs @@ -6,7 +6,7 @@ namespace codeRR.Server.Web.Tests.Pages.Account { public class LoginPage : BasePage { - public LoginPage(IWebDriver webDriver) : base(webDriver, (string) "Account/Login", (string) "Login - codeRR") + public LoginPage(IWebDriver webDriver) : base(webDriver, "Account/Login", "Login - codeRR") { } @@ -19,19 +19,19 @@ public LoginPage(IWebDriver webDriver) : base(webDriver, (string) "Account/Login [FindsBy(How = How.Id, Using = "Password")] public IWebElement PasswordField { get; set; } - public HomePage LoginWithValidCredentials() + public IPage LoginWithValidCredentials(string userName, string password) { NavigateToPage(); UserNameField.Clear(); - UserNameField.SendKeys(TestUser.Username); + UserNameField.SendKeys(userName); PasswordField.Clear(); - PasswordField.SendKeys(TestUser.Password); + PasswordField.SendKeys(password); SignInButton.Click(); - return new HomePage(WebDriver); + return PageHelper.ResolvePage(WebDriver); } public LoginPage LoginWithNonExistingUserWithoutPasswordSpecified() diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/Account/LogoutPage.cs b/src/Server/Coderr.Server.Web.Tests/Pages/Account/LogoutPage.cs index 7504d5a0..732e0066 100644 --- a/src/Server/Coderr.Server.Web.Tests/Pages/Account/LogoutPage.cs +++ b/src/Server/Coderr.Server.Web.Tests/Pages/Account/LogoutPage.cs @@ -4,7 +4,7 @@ namespace codeRR.Server.Web.Tests.Pages.Account { public class LogoutPage : BasePage { - public LogoutPage(IWebDriver webDriver) : base(webDriver, (string) "Account/Logout", (string) "") + public LogoutPage(IWebDriver webDriver) : base(webDriver, "Account/Logout", "") { } diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/Account/RegisterPage.cs b/src/Server/Coderr.Server.Web.Tests/Pages/Account/RegisterPage.cs index b61746ff..a1ba49ad 100644 --- a/src/Server/Coderr.Server.Web.Tests/Pages/Account/RegisterPage.cs +++ b/src/Server/Coderr.Server.Web.Tests/Pages/Account/RegisterPage.cs @@ -7,7 +7,7 @@ namespace codeRR.Server.Web.Tests.Pages.Account { public class RegisterPage : BasePage { - public RegisterPage(IWebDriver webDriver) : base(webDriver, (string) "Account/Register", (string) "Register account - codeRR") + public RegisterPage(IWebDriver webDriver) : base(webDriver, "Account/Register", "Register account - codeRR") { } diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/ApplicationPage.cs b/src/Server/Coderr.Server.Web.Tests/Pages/ApplicationPage.cs new file mode 100644 index 00000000..ca6ea3e5 --- /dev/null +++ b/src/Server/Coderr.Server.Web.Tests/Pages/ApplicationPage.cs @@ -0,0 +1,29 @@ +using OpenQA.Selenium; +using OpenQA.Selenium.Support.PageObjects; +using OpenQA.Selenium.Support.UI; + +namespace codeRR.Server.Web.Tests.Pages +{ + public class ApplicationPage : BasePage + { + public ApplicationPage(IWebDriver webDriver, int id) : base(webDriver, "#/application/{id}", "") + { + Url = Url.Replace("{id}", id.ToString()); + } + + [FindsBy(How = How.Id, Using = "pageTitle")] + public IWebElement PageTitle { get; set; } + + public void VerifyIsCurrentPage() + { + Wait.Until(ExpectedConditions.TitleIs(Title)); + } + + public void VerifyIncidentReported() + { + var by = By.PartialLinkText("Value cannot be null"); + //var element = WebDriver.FindElement(by); + Wait.Until(ExpectedConditions.ElementExists(by)); + } + } +} diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/BasePage.cs b/src/Server/Coderr.Server.Web.Tests/Pages/BasePage.cs index 3fb0fa89..27d7f3be 100644 --- a/src/Server/Coderr.Server.Web.Tests/Pages/BasePage.cs +++ b/src/Server/Coderr.Server.Web.Tests/Pages/BasePage.cs @@ -6,12 +6,12 @@ namespace codeRR.Server.Web.Tests.Pages { - public class BasePage + public class BasePage : IPage { protected IWebDriver WebDriver; protected WebDriverWait Wait; protected string BaseUrl { get; } - protected string Url { get; set; } + public string Url { get; set; } public string Title { get; } protected readonly TestUser TestUser = WebTest.TestUser; diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/IPage.cs b/src/Server/Coderr.Server.Web.Tests/Pages/IPage.cs new file mode 100644 index 00000000..e7e7ba73 --- /dev/null +++ b/src/Server/Coderr.Server.Web.Tests/Pages/IPage.cs @@ -0,0 +1,8 @@ +namespace codeRR.Server.Web.Tests.Pages +{ + public interface IPage + { + string Url { get; set; } + string Title { get; } + } +} diff --git a/src/Server/Coderr.Server.Web.Tests/Pages/PageHelper.cs b/src/Server/Coderr.Server.Web.Tests/Pages/PageHelper.cs new file mode 100644 index 00000000..05b8b79a --- /dev/null +++ b/src/Server/Coderr.Server.Web.Tests/Pages/PageHelper.cs @@ -0,0 +1,25 @@ +using System; +using System.Text.RegularExpressions; +using codeRR.Server.Web.Tests.Pages.Account; +using OpenQA.Selenium; + +namespace codeRR.Server.Web.Tests.Pages +{ + public class PageHelper + { + public static IPage ResolvePage(IWebDriver webDriver) + { + var match = Regex.Match(webDriver.Url, @"/#/$", RegexOptions.IgnoreCase); + if (match.Success) + return new HomePage(webDriver); + match = Regex.Match(webDriver.Url, @"/Account/Login", RegexOptions.IgnoreCase); + if (match.Success) + return new LoginPage(webDriver); + match = Regex.Match(webDriver.Url, @"/#/application/(\d+)", RegexOptions.IgnoreCase); + if(match.Success) + return new ApplicationPage(webDriver, Convert.ToInt16(match.Groups[1].Value)); + + throw new ArgumentOutOfRangeException($"Url: {webDriver.Url}, Title: {webDriver.Title}"); + } + } +} diff --git a/src/Server/Coderr.Server.Web.Tests/Tests/AdminUserTests.cs b/src/Server/Coderr.Server.Web.Tests/Tests/AdminUserTests.cs new file mode 100644 index 00000000..972dffa9 --- /dev/null +++ b/src/Server/Coderr.Server.Web.Tests/Tests/AdminUserTests.cs @@ -0,0 +1,35 @@ +using System; +using codeRR.Server.Web.Tests.Helpers.Extensions; +using codeRR.Server.Web.Tests.Pages; +using OpenQA.Selenium; +using Xunit; + +namespace codeRR.Server.Web.Tests.Tests +{ + [Trait("Category", "Integration")] + public class AdminUserTests : LoggedInTest, IDisposable + { + private readonly IPage _homePage; + + public AdminUserTests() + { + _homePage = Login(); + } + + [Fact] + public void Admin_Should_have_create_new_application_menu_item() + { + UITest(() => + { + Assert.IsType(_homePage); + Assert.Equal("Overview", WebDriver.WaitUntilTitleEquals(_homePage.Title)); + Assert.NotNull(WebDriver.FindElement(By.XPath("//a/span[.='Create new application']"))); + }); + } + + public void Dispose() + { + Logout(); + } + } +} diff --git a/src/Server/Coderr.Server.Web.Tests/Tests/ConfigureApplicationPageTests.cs b/src/Server/Coderr.Server.Web.Tests/Tests/ConfigureApplicationPageTests.cs index 1b0f966f..e9481110 100644 --- a/src/Server/Coderr.Server.Web.Tests/Tests/ConfigureApplicationPageTests.cs +++ b/src/Server/Coderr.Server.Web.Tests/Tests/ConfigureApplicationPageTests.cs @@ -1,25 +1,27 @@ -using codeRR.Server.Web.Tests.Pages; +using System; +using codeRR.Server.Web.Tests.Pages; using Xunit; namespace codeRR.Server.Web.Tests.Tests { [Trait("Category", "Integration")] - public class ConfigureApplicationPageTests : LoggedInTest + public class ConfigureApplicationPageTests : LoggedInTest, IDisposable { + public ConfigureApplicationPageTests() + { + Login(); + } + [Fact] public void Should_not_be_able_to_create_application_without_name_specified() { UITest(() => { - Login(); - var sut = new ConfigureApplicationPage(WebDriver) .CreateApplication(string.Empty); //TODO: Verify error message sut.VerifyIsCurrentPage(); - - Logout(); }); } @@ -28,8 +30,6 @@ public void Should_be_able_to_create_application() { UITest(() => { - Login(); - var applicationName = "TestApplication"; var sut = new ConfigureApplicationPage(WebDriver) @@ -42,9 +42,12 @@ public void Should_be_able_to_create_application() homePage.VerifyIsCurrentPage(); homePage.HasApplicationInNavigation(applicationName); - - Logout(); }); } + + public void Dispose() + { + Logout(); + } } } diff --git a/src/Server/Coderr.Server.Web.Tests/Tests/HomePageTests.cs b/src/Server/Coderr.Server.Web.Tests/Tests/HomePageTests.cs index bc631ca6..0a3de5f5 100644 --- a/src/Server/Coderr.Server.Web.Tests/Tests/HomePageTests.cs +++ b/src/Server/Coderr.Server.Web.Tests/Tests/HomePageTests.cs @@ -1,27 +1,34 @@ -using codeRR.Server.Web.Tests.Pages; +using System; +using codeRR.Server.Web.Tests.Pages; using Xunit; namespace codeRR.Server.Web.Tests.Tests { [Trait("Category", "Integration")] - public class HomePageTests : LoggedInTest + public class HomePageTests : LoggedInTest, IDisposable { + public HomePageTests() + { + Login(); + } + [Fact] public void Should_be_able_to_navigate_to_myfirstapp_application() { UITest(() => { - Login(); - var sut = new HomePage(WebDriver); sut.NavigateToPage(); sut.NavigationMyTestApp.Click(); sut.VerifyNavigatedToMyTestApp(); - - Logout(); }); } + + public void Dispose() + { + Logout(); + } } } diff --git a/src/Server/Coderr.Server.Web.Tests/Tests/IncidentsPageTests.cs b/src/Server/Coderr.Server.Web.Tests/Tests/IncidentsPageTests.cs index 0e89dcf9..972ffc9c 100644 --- a/src/Server/Coderr.Server.Web.Tests/Tests/IncidentsPageTests.cs +++ b/src/Server/Coderr.Server.Web.Tests/Tests/IncidentsPageTests.cs @@ -7,15 +7,18 @@ namespace codeRR.Server.Web.Tests.Tests { [Trait("Category", "Integration")] - public class IncidentsPageTests : LoggedInTest + public class IncidentsPageTests : LoggedInTest, IDisposable { + public IncidentsPageTests() + { + Login(); + } + [Fact] public void Should_be_able_to_report_error_with_client_lib_and_error_shows_up_in_incidents() { UITest(() => { - Login(); - var url = new Uri(ServerUrl); Err.Configuration.Credentials(url, TestData.Application.AppKey, TestData.Application.SharedSecret); Err.Report(new ArgumentNullException("id"), new { SampleData = "Context example" }); @@ -27,9 +30,12 @@ public void Should_be_able_to_report_error_with_client_lib_and_error_shows_up_in sut.NavigateToPage(); sut.VerifyIncidentReported(); - - Logout(); }); } + + public void Dispose() + { + Logout(); + } } } diff --git a/src/Server/Coderr.Server.Web.Tests/Tests/LoggedInTest.cs b/src/Server/Coderr.Server.Web.Tests/Tests/LoggedInTest.cs index bcde6f9c..45e3b540 100644 --- a/src/Server/Coderr.Server.Web.Tests/Tests/LoggedInTest.cs +++ b/src/Server/Coderr.Server.Web.Tests/Tests/LoggedInTest.cs @@ -6,14 +6,15 @@ namespace codeRR.Server.Web.Tests.Tests { public class LoggedInTest : WebTest { - public HomePage Login() + public IPage Login() { - var page = new LoginPage(WebDriver) - .LoginWithValidCredentials(); - - Assert.IsType(page); + return Login(TestData.TestUser.Username, TestData.TestUser.Password); + } - page.VerifyIsCurrentPage(); + public IPage Login(string userName, string password) + { + var page = new LoginPage(WebDriver) + .LoginWithValidCredentials(userName, password); return page; } diff --git a/src/Server/Coderr.Server.Web.Tests/Tests/LoginPageTests.cs b/src/Server/Coderr.Server.Web.Tests/Tests/LoginPageTests.cs index 958f5c51..ba0b1bfa 100644 --- a/src/Server/Coderr.Server.Web.Tests/Tests/LoginPageTests.cs +++ b/src/Server/Coderr.Server.Web.Tests/Tests/LoginPageTests.cs @@ -91,10 +91,10 @@ public void Should_be_able_to_login_with_valid_credentials() UITest(() => { var sut = new LoginPage(WebDriver) - .LoginWithValidCredentials(); + .LoginWithValidCredentials(TestData.TestUser.Username, TestData.TestUser.Password); Assert.IsType(sut); - sut.VerifyIsCurrentPage(); + ((HomePage)sut).VerifyIsCurrentPage(); Logout(); }); diff --git a/src/Server/Coderr.Server.Web.Tests/Tests/UserTests.cs b/src/Server/Coderr.Server.Web.Tests/Tests/UserTests.cs new file mode 100644 index 00000000..a06fe7a6 --- /dev/null +++ b/src/Server/Coderr.Server.Web.Tests/Tests/UserTests.cs @@ -0,0 +1,50 @@ +using System; +using codeRR.Server.SqlServer.Tests.Models; +using codeRR.Server.Web.Tests.Helpers.Extensions; +using codeRR.Server.Web.Tests.Pages; +using OpenQA.Selenium; +using Xunit; + +namespace codeRR.Server.Web.Tests.Tests +{ + [Trait("Category", "Integration")] + public class UserTests : LoggedInTest, IDisposable + { + private readonly IPage _homePage; + private readonly TestUser _testUser; + + public UserTests() + { + _testUser = new TestUser { Username = "TestNormalUser", Password = "123456", Email = "TestNormalUser@coderrapp.com" }; + TestData.CreateUser(_testUser, TestData.ApplicationId); + + _homePage = Login(_testUser.Username, _testUser.Password); + } + + [Fact] + public void NormalUser_Should_not_have_create_new_application_menu_item() + { + UITest(() => + { + Assert.IsType(_homePage); + Assert.Equal("MyTestApp", WebDriver.WaitUntilTitleEquals("MyTestApp")); + Assert.Throws(() => WebDriver.FindElement(By.XPath("//a/span[.='Create new application']"))); + }); + } + + [Fact] + public void NormalUser_Should_see_homepage_after_login() + { + UITest(() => + { + Assert.IsType(_homePage); + Assert.Equal("MyTestApp", WebDriver.WaitUntilTitleEquals("MyTestApp")); + }); + } + + public void Dispose() + { + Logout(); + } + } +} diff --git a/src/Server/Coderr.Server.Web.Tests/codeRR.Server.Web.Tests.csproj b/src/Server/Coderr.Server.Web.Tests/codeRR.Server.Web.Tests.csproj index f3c07885..1d396765 100644 --- a/src/Server/Coderr.Server.Web.Tests/codeRR.Server.Web.Tests.csproj +++ b/src/Server/Coderr.Server.Web.Tests/codeRR.Server.Web.Tests.csproj @@ -10,7 +10,7 @@ - +