From 698033b0cf2aa1b1b6189f4ed338386abf026fe3 Mon Sep 17 00:00:00 2001 From: britttttk <39231115+britttttk@users.noreply.github.com> Date: Sun, 12 May 2019 02:13:26 -0600 Subject: [PATCH] Selenium Chrome Tests --- BTCPayServer.Tests/BTCPayServer.Tests.csproj | 2 + BTCPayServer.Tests/SeleniumTests.cs | 243 ++++++++++++++++++ BTCPayServer.Tests/docker-compose.yml | 4 + BTCPayServer/Views/Account/Login.cshtml | 2 +- BTCPayServer/Views/Account/Register.cshtml | 2 +- BTCPayServer/Views/Apps/CreateApp.cshtml | 2 +- BTCPayServer/Views/Apps/ListApps.cshtml | 2 +- .../Views/Apps/UpdateCrowdfund.cshtml | 4 +- .../Views/Apps/UpdatePointOfSale.cshtml | 103 ++++---- .../Views/Invoice/CreateInvoice.cshtml | 2 +- .../Views/Invoice/ListInvoices.cshtml | 2 +- .../Views/Manage/ChangePassword.cshtml | 2 +- BTCPayServer/Views/Manage/_Nav.cshtml | 2 +- .../PaymentRequest/EditPaymentRequest.cshtml | 4 +- .../PaymentRequest/GetPaymentRequests.cshtml | 2 +- BTCPayServer/Views/Shared/_Layout.cshtml | 18 +- .../Views/Stores/AddDerivationScheme.cshtml | 4 +- BTCPayServer/Views/Stores/UpdateStore.cshtml | 4 +- .../Views/UserStores/CreateStore.cshtml | 2 +- .../Views/UserStores/ListStores.cshtml | 2 +- 20 files changed, 329 insertions(+), 79 deletions(-) create mode 100644 BTCPayServer.Tests/SeleniumTests.cs diff --git a/BTCPayServer.Tests/BTCPayServer.Tests.csproj b/BTCPayServer.Tests/BTCPayServer.Tests.csproj index 7da4b0661..3ff6e99c7 100644 --- a/BTCPayServer.Tests/BTCPayServer.Tests.csproj +++ b/BTCPayServer.Tests/BTCPayServer.Tests.csproj @@ -11,6 +11,8 @@ + + all diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs new file mode 100644 index 000000000..9375c03b8 --- /dev/null +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -0,0 +1,243 @@ +using System; +using Xunit; +using OpenQA.Selenium; +using OpenQA.Selenium.Chrome; +using BTCPayServer.Tests.Logging; +using Xunit.Abstractions; +using OpenQA.Selenium.Interactions; +using System.Linq; + +namespace BTCPayServer.Tests +{ + public class Base + { + public IWebDriver Driver { get; set; } + + public Base(ITestOutputHelper helper) + { + Logs.Tester = new XUnitLog(helper) { Name = "Tests" }; + Logs.LogProvider = new XUnitLogProvider(helper); + } + + protected void Wrap(Action func) + { + using (var tester = ServerTester.Create()) + { + tester.Start(); + func.Invoke(tester.PayTester.ServerUri.ToString()); + } + } + } + + public class Browsers : Base + { + public Browsers(ITestOutputHelper helper) : base(helper) + { + ChromeOptions options = new ChromeOptions(); + options.AddArguments("headless"); // Comment to view browser + options.AddArguments("window-size=1200x600"); // Comment to view browser + Driver = new ChromeDriver(Environment.CurrentDirectory, options); + } + + public void RegisterNewUser(string random) + { + Driver.FindElement(By.Id("Register")).Click(); + Driver.FindElement(By.Id("Email")).SendKeys(random + "@a.com"); + Driver.FindElement(By.Id("Password")).SendKeys("123456"); + Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("123456"); + Driver.FindElement(By.Id("RegisterButton")).Click(); + return; + } + + public void CreateNewStore(string random) + { + Driver.FindElement(By.Id("Stores")).Click(); + Driver.FindElement(By.Id("CreateStore")).Click(); + Driver.FindElement(By.Id("Name")).SendKeys("Store" + random); + Driver.FindElement(By.Id("Create")).Click(); + return; + } + + public void AddDerivationScheme() + { + Driver.FindElement(By.Id("ModifyBTC")).Click(); + Driver.FindElement(By.Id("DerivationScheme")).SendKeys("xpub661MyMwAqRbcGABgHMUXDzPzH1tU7eZaAaJQXhDXsSxsqyQzQeU6kznNfSuAyqAK9UaWSaZaMFdNiY5BCF4zBPAzSnwfUAwUhwttuAKwfRX-[legacy]"); + Driver.FindElement(By.Id("Continue")).Click(); + Driver.FindElement(By.Id("Confirm")).Click(); + Driver.FindElement(By.Id("Save")).Click(); + return; + } + + public void CreateInvoice(string random) + { + Driver.FindElement(By.Id("Invoices")).Click(); + Driver.FindElement(By.Id("CreateNewInvoice")).Click(); + Driver.FindElement(By.CssSelector("input#Amount.form-control")).SendKeys("100"); + Driver.FindElement(By.Name("StoreId")).SendKeys("Deriv" + random + Keys.Enter); + Driver.FindElement(By.Id("Create")).Click(); + return; + } + + } + + public class ChromeTests : Browsers + { + private string random = (new Random()).Next(1, 1000).ToString(); + [Fact] + public void AccessRequiresLogin() + { + Wrap(s => + { + Driver.Navigate().GoToUrl(s); + Assert.Contains("Login", Driver.PageSource); + Driver.Quit(); + }); + } + + [Fact] + public void NewUserLogin() + { + Wrap(s => + { + //Register & Log Out + Driver.Navigate().GoToUrl(s); + RegisterNewUser(random); + Driver.FindElement(By.Id("Logout")).Click(); + + //Same User Can Log Back In + Driver.FindElement(By.Id("Login")).Click(); + Driver.FindElement(By.Id("Email")).SendKeys(random + "@a.com"); + Driver.FindElement(By.Id("Password")).SendKeys("123456"); + Driver.FindElement(By.Id("LoginButton")).Click(); + + //Change Password & Log Out + Driver.FindElement(By.Id("MySettings")).Click(); + Driver.FindElement(By.Id("ChangePassword")).Click(); + Driver.FindElement(By.Id("OldPassword")).SendKeys("123456"); + Driver.FindElement(By.Id("NewPassword")).SendKeys("abc???"); + Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("abc???"); + Driver.FindElement(By.Id("UpdatePassword")).Click(); + Driver.FindElement(By.Id("Logout")).Click(); + + //Log In With New Password + Driver.FindElement(By.Id("Login")).Click(); + Driver.FindElement(By.Id("Email")).SendKeys(random + "@a.com"); + Driver.FindElement(By.Id("Password")).SendKeys("abc???"); + Driver.FindElement(By.Id("LoginButton")).Click(); + Assert.True(Driver.PageSource.Contains("Stores"), "Can't Access Stores"); + Driver.Quit(); + }); + } + + + [Fact] + public void CanCreateStores() + { + Wrap(s => + { + Driver.Navigate().GoToUrl(s); + RegisterNewUser(random); + CreateNewStore(random); + Assert.Contains("Store" + random, Driver.PageSource); + Driver.Quit(); + }); + } + + [Fact] + public void CanCreateInvoice() + { + Wrap(s => + { + Driver.Navigate().GoToUrl(s); + RegisterNewUser(random); + CreateNewStore(random); + AddDerivationScheme(); + + Driver.FindElement(By.Id("Invoices")).Click(); + Driver.FindElement(By.Id("CreateNewInvoice")).Click(); + Driver.FindElement(By.CssSelector("input#Amount.form-control")).SendKeys("100"); + Driver.FindElement(By.Name("StoreId")).SendKeys("Deriv" + random + Keys.Enter); + Driver.FindElement(By.Id("Create")).Click(); + Assert.True(Driver.PageSource.Contains("just created!"), "Unable to create Invoice"); + Driver.Quit(); + }); + } + + [Fact] + public void CanCreateAppPoS() + { + Wrap(s => + { + Driver.Navigate().GoToUrl(s); + RegisterNewUser(random); + CreateNewStore(random); + + Driver.FindElement(By.Id("Apps")).Click(); + Driver.FindElement(By.Id("CreateNewApp")).Click(); + Driver.FindElement(By.Name("Name")).SendKeys("PoS" + random); + Driver.FindElement(By.CssSelector("select#SelectedAppType.form-control")).SendKeys("PointOfSale" + Keys.Enter); + Driver.FindElement(By.CssSelector("select#SelectedStore.form-control")).SendKeys("Store" + random + Keys.Enter); + Driver.FindElement(By.Id("Create")).Click(); + Driver.FindElement(By.CssSelector("input#EnableShoppingCart.form-check")).Click(); + Driver.FindElement(By.Id("SaveSettings")).Click(); + Assert.True(Driver.PageSource.Contains("App updated"), "Unable to create PoS"); + Driver.Quit(); + }); + } + + [Fact] + public void CanCreateAppCF() + { + Wrap(s => + { + Driver.Navigate().GoToUrl(s); + RegisterNewUser(random); + CreateNewStore(random); + AddDerivationScheme(); + + Driver.FindElement(By.Id("Apps")).Click(); + Driver.FindElement(By.Id("CreateNewApp")).Click(); + Driver.FindElement(By.Name("Name")).SendKeys("CF" + random); + Driver.FindElement(By.CssSelector("select#SelectedAppType.form-control")).SendKeys("Crowdfund" + Keys.Enter); + Driver.FindElement(By.CssSelector("select#SelectedStore.form-control")).SendKeys("Store" + random + Keys.Enter); + Driver.FindElement(By.Id("Create")).Click(); + Driver.FindElement(By.Id("Title")).SendKeys("Kukkstarter"); + Driver.FindElement(By.CssSelector("div.note-editable.card-block")).SendKeys("1BTC = 1BTC"); + Driver.FindElement(By.Id("TargetCurrency")).SendKeys("JPY"); + Driver.FindElement(By.Id("TargetAmount")).SendKeys("700"); + Driver.FindElement(By.Id("SaveSettings")).Submit(); + Driver.FindElement(By.Id("ViewApp")).Click(); + Driver.SwitchTo().Window(Driver.WindowHandles.Last()); + Assert.True(Driver.PageSource.Contains("Currently Active!"), "Unable to create CF"); + Driver.Quit(); + }); + } + + [Fact] + public void CanCreatePayRequest() + { + Wrap(s => + { + Driver.Navigate().GoToUrl(s); + RegisterNewUser(random); + CreateNewStore(random); + AddDerivationScheme(); + + Driver.FindElement(By.Id("PaymentRequests")).Click(); + Driver.FindElement(By.Id("CreatePaymentRequest")).Click(); + Driver.FindElement(By.Id("Title")).SendKeys("Pay123"); + Driver.FindElement(By.Id("Amount")).SendKeys("700"); + Driver.FindElement(By.Id("Currency")).SendKeys("BTC"); + Driver.FindElement(By.Id("SaveButton")).Submit(); + Driver.FindElement(By.Name("ViewAppButton")).SendKeys(Keys.Return); + Driver.SwitchTo().Window(Driver.WindowHandles.Last()); + Assert.True(Driver.PageSource.Contains("Amount due"), "Unable to create Payment Request"); + Driver.Quit(); + }); + } + + public ChromeTests(ITestOutputHelper helper) : base(helper) + { + } + } +} diff --git a/BTCPayServer.Tests/docker-compose.yml b/BTCPayServer.Tests/docker-compose.yml index 13e140869..57bcf1d59 100644 --- a/BTCPayServer.Tests/docker-compose.yml +++ b/BTCPayServer.Tests/docker-compose.yml @@ -53,6 +53,7 @@ services: - lightning-charged - customer_lnd - merchant_lnd + - selenium devlnd: image: btcpayserver/bitcoin:0.18.0 @@ -285,6 +286,9 @@ services: links: - bitcoind + selenium: + image: selenium/standalone-chrome + volumes: bitcoin_datadir: customer_lightningd_datadir: diff --git a/BTCPayServer/Views/Account/Login.cshtml b/BTCPayServer/Views/Account/Login.cshtml index c9af42dde..84cf78589 100644 --- a/BTCPayServer/Views/Account/Login.cshtml +++ b/BTCPayServer/Views/Account/Login.cshtml @@ -41,7 +41,7 @@
- +

diff --git a/BTCPayServer/Views/Account/Register.cshtml b/BTCPayServer/Views/Account/Register.cshtml index 0b2c4d939..990c394f7 100644 --- a/BTCPayServer/Views/Account/Register.cshtml +++ b/BTCPayServer/Views/Account/Register.cshtml @@ -35,7 +35,7 @@

- + diff --git a/BTCPayServer/Views/Apps/CreateApp.cshtml b/BTCPayServer/Views/Apps/CreateApp.cshtml index 8cb9517cb..50bc80c55 100644 --- a/BTCPayServer/Views/Apps/CreateApp.cshtml +++ b/BTCPayServer/Views/Apps/CreateApp.cshtml @@ -28,7 +28,7 @@
- +
Back to the app list diff --git a/BTCPayServer/Views/Apps/ListApps.cshtml b/BTCPayServer/Views/Apps/ListApps.cshtml index 4bf07936e..0f1190678 100644 --- a/BTCPayServer/Views/Apps/ListApps.cshtml +++ b/BTCPayServer/Views/Apps/ListApps.cshtml @@ -23,7 +23,7 @@ diff --git a/BTCPayServer/Views/Apps/UpdateCrowdfund.cshtml b/BTCPayServer/Views/Apps/UpdateCrowdfund.cshtml index edb4b36f8..f7f991d82 100644 --- a/BTCPayServer/Views/Apps/UpdateCrowdfund.cshtml +++ b/BTCPayServer/Views/Apps/UpdateCrowdfund.cshtml @@ -211,9 +211,9 @@ diff --git a/BTCPayServer/Views/Apps/UpdatePointOfSale.cshtml b/BTCPayServer/Views/Apps/UpdatePointOfSale.cshtml index f69a1a20c..e4a52443e 100644 --- a/BTCPayServer/Views/Apps/UpdatePointOfSale.cshtml +++ b/BTCPayServer/Views/Apps/UpdatePointOfSale.cshtml @@ -6,19 +6,19 @@ @@ -119,7 +119,7 @@ { } - +
@@ -127,9 +127,9 @@
- +
- +
@@ -163,7 +163,7 @@

@@ -171,17 +171,17 @@
You can embed the POS using an iframe @{ - var iframe = $""; + var iframe = $""; }
@iframe
-
+

@@ -196,7 +196,8 @@
  • Verify that the orderId is from your backend, that the price is correct and that status is either confirmed or complete
  • You can then ship your order
  • -

    +

    + @@ -204,8 +205,8 @@ Back to the app list - - + + @@ -230,38 +231,38 @@ diff --git a/BTCPayServer/Views/Invoice/CreateInvoice.cshtml b/BTCPayServer/Views/Invoice/CreateInvoice.cshtml index e1f2a003b..0edee5a80 100644 --- a/BTCPayServer/Views/Invoice/CreateInvoice.cshtml +++ b/BTCPayServer/Views/Invoice/CreateInvoice.cshtml @@ -73,7 +73,7 @@
    - +
    Back to List diff --git a/BTCPayServer/Views/Invoice/ListInvoices.cshtml b/BTCPayServer/Views/Invoice/ListInvoices.cshtml index b89133d3e..29649c98c 100644 --- a/BTCPayServer/Views/Invoice/ListInvoices.cshtml +++ b/BTCPayServer/Views/Invoice/ListInvoices.cshtml @@ -47,7 +47,7 @@
    - + @if (!string.IsNullOrEmpty(Model.Id)) { - View + View
    diff --git a/BTCPayServer/Views/Shared/_Layout.cshtml b/BTCPayServer/Views/Shared/_Layout.cshtml index 4c984dbaf..89c8d1186 100644 --- a/BTCPayServer/Views/Shared/_Layout.cshtml +++ b/BTCPayServer/Views/Shared/_Layout.cshtml @@ -74,24 +74,24 @@ { } - - - - - + + + + + } else if (env.IsSecure) { if (themeManager.ShowRegister) { - + } - + } diff --git a/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml b/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml index 459c80bbe..3bd8c277a 100644 --- a/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml +++ b/BTCPayServer/Views/Stores/AddDerivationScheme.cshtml @@ -130,7 +130,7 @@ - + } else { @@ -175,7 +175,7 @@ - + } diff --git a/BTCPayServer/Views/Stores/UpdateStore.cshtml b/BTCPayServer/Views/Stores/UpdateStore.cshtml index 85e38da8c..1efa975f8 100644 --- a/BTCPayServer/Views/Stores/UpdateStore.cshtml +++ b/BTCPayServer/Views/Stores/UpdateStore.cshtml @@ -121,7 +121,7 @@ { Wallet - } - Modify + Modify } @@ -247,7 +247,7 @@ } - + diff --git a/BTCPayServer/Views/UserStores/CreateStore.cshtml b/BTCPayServer/Views/UserStores/CreateStore.cshtml index 795a6cdf6..d7c0edc10 100644 --- a/BTCPayServer/Views/UserStores/CreateStore.cshtml +++ b/BTCPayServer/Views/UserStores/CreateStore.cshtml @@ -20,7 +20,7 @@
    - +
    Back to List diff --git a/BTCPayServer/Views/UserStores/ListStores.cshtml b/BTCPayServer/Views/UserStores/ListStores.cshtml index 99b663957..3325b3d7c 100644 --- a/BTCPayServer/Views/UserStores/ListStores.cshtml +++ b/BTCPayServer/Views/UserStores/ListStores.cshtml @@ -21,7 +21,7 @@