Compare commits

...

1 Commits

Author SHA1 Message Date
198fe9843e wip test rewrite 2021-05-12 11:14:23 +02:00
9 changed files with 404 additions and 396 deletions

View File

@ -23,7 +23,6 @@ using NBitpayClient;
using NBXplorer.DerivationStrategy;
using NBXplorer.Models;
using Newtonsoft.Json.Linq;
using OpenQA.Selenium;
using Xunit;
using Xunit.Abstractions;
@ -386,17 +385,17 @@ namespace BTCPayServer.Tests
// BTC crash by 50%
s.Server.PayTester.ChangeRate("BTC_USD", new Rating.BidAsk(5000.0m / 2.0m, 5100.0m / 2.0m));
s.GoToInvoice(invoice.Id);
s.Driver.FindElement(By.Id("refundlink")).Click();
s.Driver.FindElement("#refundlink")).Click();
if (multiCurrency)
{
s.Driver.FindElement(By.Id("SelectedPaymentMethod")).SendKeys("BTC" + Keys.Enter);
s.Driver.FindElement(By.Id("ok")).Click();
s.Driver.FindElement("#SelectedPaymentMethod")).SendKeys("BTC" + Keys.Enter);
s.Driver.FindElement("#ok")).Click();
}
Assert.Contains("$5,500.00", s.Driver.PageSource); // Should propose reimburse in fiat
Assert.Contains("1.10000000 ₿", s.Driver.PageSource); // Should propose reimburse in BTC at the rate of before
Assert.Contains("2.20000000 ₿", s.Driver.PageSource); // Should propose reimburse in BTC at the current rate
s.Driver.FindElement(By.Id(rateSelection)).Click();
s.Driver.FindElement(By.Id("ok")).Click();
s.Driver.FindElement("#ok")).Click();
Assert.Contains("pull-payments", s.Driver.Url);
if (rateSelection == "FiatText")
Assert.Contains("$5,500.00", s.Driver.PageSource);
@ -407,7 +406,7 @@ namespace BTCPayServer.Tests
s.GoToHome();
s.GoToInvoices();
s.GoToInvoice(invoice.Id);
s.Driver.FindElement(By.Id("refundlink")).Click();
s.Driver.FindElement("#refundlink")).Click();
Assert.Contains("pull-payments", s.Driver.Url);
}
@ -421,15 +420,15 @@ namespace BTCPayServer.Tests
s.Server.ActivateLTC();
s.Server.ActivateLightning();
await s.StartAsync();
s.GoToRegister();
s.RegisterNewUser();
await s.GoToRegister();
await s.RegisterNewUser();
var store = s.CreateNewStore();
s.AddDerivationScheme("BTC");
//check that there is no dropdown since only one payment method is set
var invoiceId = s.CreateInvoice(store.storeName, 10, "USD", "a@g.com");
s.GoToInvoiceCheckout(invoiceId);
s.Driver.FindElement(By.ClassName("payment__currencies_noborder"));
Assert.NotNull(await s.Driver.QuerySelectorAsync(".payment__currencies_noborder"));
s.GoToHome();
s.GoToStore(store.storeId);
s.AddDerivationScheme("LTC");

View File

@ -7,7 +7,7 @@ using BTCPayServer.Tests.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Memory;
using NBitcoin;
using OpenQA.Selenium;
using PlaywrightSharp;
using Xunit;
using Xunit.Abstractions;
@ -48,47 +48,48 @@ namespace BTCPayServer.Tests
using var s = SeleniumTester.Create("ETHEREUM", true);
s.Server.ActivateETH();
await s.StartAsync();
s.RegisterNewUser(true);
await s.RegisterNewUser(true);
IWebElement syncSummary = null;
TestUtils.Eventually(() =>
IElementHandle syncSummary = null;
await TestUtils.EventuallyAsync(async () =>
{
syncSummary = s.Driver.FindElement(By.Id("modalDialog"));
Assert.True(syncSummary.Displayed);
syncSummary = await s.Driver.QuerySelectorAsync("#modalDialog");
Assert.NotNull(syncSummary);
Assert.False(await syncSummary.IsHiddenAsync());
});
var web3Link = syncSummary.FindElement(By.LinkText("Configure Web3"));
web3Link.Click();
s.Driver.FindElement(By.Id("Web3ProviderUrl")).SendKeys("https://ropsten-rpc.linkpool.io");
s.Driver.FindElement(By.Id("saveButton")).Click();
s.FindAlertMessage();
s.Driver.FindElement("#Web3ProviderUrl")).SendKeys("https://ropsten-rpc.linkpool.io");
s.Driver.FindElement("#saveButton")).Click();
await s.FindAlertMessage();
TestUtils.Eventually(() =>
{
s.Driver.Navigate().Refresh();
s.Driver.AssertElementNotFound(By.Id("modalDialog"));
s.Driver.AssertElementNotFound("#modalDialog"));
});
var store = s.CreateNewStore();
s.Driver.FindElement(By.LinkText("Ethereum")).Click();
var seed = new Mnemonic(Wordlist.English);
s.Driver.FindElement(By.Id("ModifyETH")).Click();
s.Driver.FindElement(By.Id("Seed")).SendKeys(seed.ToString());
s.Driver.SetCheckbox(By.Id("StoreSeed"), true);
s.Driver.SetCheckbox(By.Id("Enabled"), true);
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.FindAlertMessage();
s.Driver.FindElement(By.Id("ModifyUSDT20")).Click();
s.Driver.FindElement(By.Id("Seed")).SendKeys(seed.ToString());
s.Driver.SetCheckbox(By.Id("StoreSeed"), true);
s.Driver.SetCheckbox(By.Id("Enabled"), true);
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.FindAlertMessage();
s.Driver.FindElement("#ModifyETH")).Click();
s.Driver.FindElement("#Seed")).SendKeys(seed.ToString());
s.Driver.SetCheckbox("#StoreSeed"), true);
s.Driver.SetCheckbox("#Enabled"), true);
s.Driver.FindElement("#SaveButton")).Click();
await s.FindAlertMessage();
s.Driver.FindElement("#ModifyUSDT20")).Click();
s.Driver.FindElement("#Seed")).SendKeys(seed.ToString());
s.Driver.SetCheckbox("#StoreSeed"), true);
s.Driver.SetCheckbox("#Enabled"), true);
s.Driver.FindElement("#SaveButton")).Click();
await s.FindAlertMessage();
var invoiceId = s.CreateInvoice(store.storeName, 10);
s.GoToInvoiceCheckout(invoiceId);
var currencyDropdownButton = s.Driver.FindElement(By.ClassName("payment__currencies"));
Assert.Contains("ETH", currencyDropdownButton.Text);
s.Driver.FindElement(By.Id("copy-tab")).Click();
s.Driver.FindElement("#copy-tab")).Click();
var ethAddress = s.Driver.FindElements(By.ClassName("copySectionBox"))
.Single(element => element.FindElement(By.TagName("label")).Text
@ -99,7 +100,7 @@ namespace BTCPayServer.Tests
Assert.Equal(2, elements.Count);
elements.Single(element => element.Text.Contains("USDT20")).Click();
s.Driver.FindElement(By.Id("copy-tab")).Click();
s.Driver.FindElement("#copy-tab")).Click();
var usdtAddress = s.Driver.FindElements(By.ClassName("copySectionBox"))
.Single(element => element.FindElement(By.TagName("label")).Text
.Contains("Address", StringComparison.InvariantCultureIgnoreCase)).FindElement(By.TagName("input"))

View File

@ -48,7 +48,7 @@ namespace BTCPayServer.Tests
s.GoToLogin();
s.Login(user.RegisterDetails.Email, user.RegisterDetails.Password);
s.GoToProfile(ManageNavPages.APIKeys);
s.Driver.FindElement(By.Id("AddApiKey")).Click();
s.Driver.FindElement("#AddApiKey")).Click();
//not an admin, so this permission should not show
Assert.DoesNotContain("btcpay.server.canmodifyserversettings", s.Driver.PageSource);
@ -57,49 +57,49 @@ namespace BTCPayServer.Tests
s.GoToLogin();
s.Login(user.RegisterDetails.Email, user.RegisterDetails.Password);
s.GoToProfile(ManageNavPages.APIKeys);
s.Driver.FindElement(By.Id("AddApiKey")).Click();
s.Driver.FindElement("#AddApiKey")).Click();
Assert.Contains("btcpay.server.canmodifyserversettings", s.Driver.PageSource);
//server management should show now
s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true);
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
s.Driver.SetCheckbox(By.Id("btcpay.user.canviewprofile"), true);
s.Driver.FindElement(By.Id("Generate")).Click();
s.Driver.SetCheckbox("#btcpay.server.canmodifyserversettings"), true);
s.Driver.SetCheckbox("#btcpay.store.canmodifystoresettings"), true);
s.Driver.SetCheckbox("#btcpay.user.canviewprofile"), true);
s.Driver.FindElement("#Generate")).Click();
var superApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
//this api key has access to everything
await TestApiAgainstAccessToken(superApiKey, tester, user, Policies.CanModifyServerSettings, Policies.CanModifyStoreSettings, Policies.CanViewProfile);
s.Driver.FindElement(By.Id("AddApiKey")).Click();
s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true);
s.Driver.FindElement(By.Id("Generate")).Click();
s.Driver.FindElement("#AddApiKey")).Click();
s.Driver.SetCheckbox("#btcpay.server.canmodifyserversettings"), true);
s.Driver.FindElement("#Generate")).Click();
var serverOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
await TestApiAgainstAccessToken(serverOnlyApiKey, tester, user,
Policies.CanModifyServerSettings);
s.Driver.FindElement(By.Id("AddApiKey")).Click();
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
s.Driver.FindElement(By.Id("Generate")).Click();
s.Driver.FindElement("#AddApiKey")).Click();
s.Driver.SetCheckbox("#btcpay.store.canmodifystoresettings"), true);
s.Driver.FindElement("#Generate")).Click();
var allStoreOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
await TestApiAgainstAccessToken(allStoreOnlyApiKey, tester, user,
Policies.CanModifyStoreSettings);
s.Driver.FindElement(By.Id("AddApiKey")).Click();
s.Driver.FindElement("#AddApiKey")).Click();
s.Driver.FindElement(By.CssSelector("button[value='btcpay.store.canmodifystoresettings:change-store-mode']")).Click();
//there should be a store already by default in the dropdown
var dropdown = s.Driver.FindElement(By.Name("PermissionValues[4].SpecificStores[0]"));
var option = dropdown.FindElement(By.TagName("option"));
var storeId = option.GetAttribute("value");
option.Click();
s.Driver.FindElement(By.Id("Generate")).Click();
s.Driver.FindElement("#Generate")).Click();
var selectiveStoreApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
await TestApiAgainstAccessToken(selectiveStoreApiKey, tester, user,
Permission.Create(Policies.CanModifyStoreSettings, storeId).ToString());
s.Driver.FindElement(By.Id("AddApiKey")).Click();
s.Driver.FindElement(By.Id("Generate")).Click();
s.Driver.FindElement("#AddApiKey")).Click();
s.Driver.FindElement("#Generate")).Click();
var noPermissionsApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
await TestApiAgainstAccessToken(noPermissionsApiKey, tester, user);
@ -124,12 +124,12 @@ namespace BTCPayServer.Tests
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
s.Driver.Navigate().GoToUrl(authUrl);
Assert.Contains(appidentifier, s.Driver.PageSource);
Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant());
Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant());
Assert.Equal("hidden", s.Driver.FindElement("#btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement("#btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant());
Assert.Equal("hidden", s.Driver.FindElement("#btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement("#btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant());
Assert.DoesNotContain("change-store-mode", s.Driver.PageSource);
s.Driver.FindElement(By.Id("consent-yes")).Click();
s.Driver.FindElement("#consent-yes")).Click();
Assert.Equal(callbackUrl, s.Driver.Url);
var apiKeyRepo = s.Server.PayTester.GetService<APIKeyRepository>();
@ -144,14 +144,14 @@ namespace BTCPayServer.Tests
s.Driver.Navigate().GoToUrl(authUrl);
Assert.DoesNotContain("kukksappname", s.Driver.PageSource);
Assert.Equal("checkbox", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant());
Assert.Equal("checkbox", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant());
Assert.Equal("checkbox", s.Driver.FindElement("#btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement("#btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant());
Assert.Equal("checkbox", s.Driver.FindElement("#btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant());
Assert.Equal("true", s.Driver.FindElement("#btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant());
s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), false);
s.Driver.SetCheckbox("#btcpay.server.canmodifyserversettings"), false);
Assert.Contains("change-store-mode", s.Driver.PageSource);
s.Driver.FindElement(By.Id("consent-yes")).Click();
s.Driver.FindElement("#consent-yes")).Click();
Assert.Equal(callbackUrl, s.Driver.Url);
accessToken = GetAccessTokenFromCallbackResult(s.Driver);
@ -164,7 +164,7 @@ namespace BTCPayServer.Tests
//if it's the same, go to the confirm page
s.Driver.Navigate().GoToUrl(authUrl);
s.Driver.FindElement(By.Id("continue")).Click();
s.Driver.FindElement("#continue")).Click();
Assert.Equal(callbackUrl, s.Driver.Url);
//same app but different redirect = nono
@ -180,14 +180,14 @@ namespace BTCPayServer.Tests
s.GoToLogin();
s.Login(user.RegisterDetails.Email, user.RegisterDetails.Password);
s.GoToProfile(ManageNavPages.APIKeys);
s.Driver.FindElement(By.Id("AddApiKey")).Click();
s.Driver.FindElement("#AddApiKey")).Click();
int checkedPermissionCount = 0;
foreach (var checkbox in s.Driver.FindElements(By.ClassName("form-check-input")))
{
checkedPermissionCount++;
checkbox.Click();
}
s.Driver.FindElement(By.Id("Generate")).Click();
s.Driver.FindElement("#Generate")).Click();
var allAPIKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
var apikeydata = await TestApiAgainstAccessToken<ApiKeyData>(allAPIKey, $"api/v1/api-keys/current", tester.PayTester.HttpClient);
Assert.Equal(checkedPermissionCount, apikeydata.Permissions.Length);

View File

@ -21,9 +21,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.13" />
<PackageReference Include="Selenium.Support" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="88.0.4324.9600" />
<PackageReference Include="PlaywrightSharp" Version="0.192.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.2">
<PrivateAssets>all</PrivateAssets>

View File

@ -32,31 +32,31 @@ namespace BTCPayServer.Tests
var store = s.CreateNewStore();
s.AddDerivationScheme("BTC");
s.GoToStore(store.storeId, StoreNavPages.Checkout);
s.Driver.FindElement(By.Id("RequiresRefundEmail")).Click();
s.Driver.FindElement("#RequiresRefundEmail")).Click();
s.Driver.FindElement(By.Name("command")).Click();
var emailAlreadyThereInvoiceId = s.CreateInvoice(store.storeName, 100, "USD", "a@g.com");
s.GoToInvoiceCheckout(emailAlreadyThereInvoiceId);
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.Driver.AssertElementNotFound("#emailAddressFormInput"));
s.GoToHome();
var invoiceId = s.CreateInvoice(store.storeName);
s.Driver.FindElement(By.ClassName("invoice-details-link")).Click();
s.Driver.AssertNoError();
s.Driver.Navigate().Back();
s.Driver.FindElement(By.ClassName("invoice-checkout-link")).Click();
Assert.NotEmpty(s.Driver.FindElements(By.Id("checkoutCtrl")));
Assert.NotEmpty(s.Driver.FindElements("#checkoutCtrl")));
Assert.True(s.Driver.FindElement(By.Id("emailAddressFormInput")).Displayed);
s.Driver.FindElement(By.Id("emailAddressFormInput")).SendKeys("xxx");
s.Driver.FindElement(By.Id("emailAddressForm")).FindElement(By.CssSelector("button.action-button"))
Assert.True(s.Driver.FindElement("#emailAddressFormInput")).Displayed);
s.Driver.FindElement("#emailAddressFormInput")).SendKeys("xxx");
s.Driver.FindElement("#emailAddressForm")).FindElement(By.CssSelector("button.action-button"))
.Click();
var formInput = s.Driver.FindElement(By.Id("emailAddressFormInput"));
var formInput = s.Driver.FindElement("#emailAddressFormInput"));
Assert.True(formInput.Displayed);
Assert.Contains("form-input-invalid", formInput.GetAttribute("class"));
formInput = s.Driver.FindElement(By.Id("emailAddressFormInput"));
formInput = s.Driver.FindElement("#emailAddressFormInput"));
formInput.SendKeys("@g.com");
var actionButton = s.Driver.FindElement(By.Id("emailAddressForm")).FindElement(By.CssSelector("button.action-button"));
var actionButton = s.Driver.FindElement("#emailAddressForm")).FindElement(By.CssSelector("button.action-button"));
actionButton.Click();
try // Sometimes the click only take the focus, without actually really clicking on it...
{
@ -64,9 +64,9 @@ namespace BTCPayServer.Tests
}
catch { }
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.Driver.AssertElementNotFound("#emailAddressFormInput"));
s.Driver.Navigate().Refresh();
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.Driver.AssertElementNotFound("#emailAddressFormInput"));
}
}
@ -83,18 +83,18 @@ namespace BTCPayServer.Tests
var invoiceId = s.CreateInvoice(store.storeName);
s.GoToInvoiceCheckout(invoiceId);
Assert.True(s.Driver.FindElement(By.Id("DefaultLang")).FindElements(By.TagName("option")).Count > 1);
var payWithTextEnglish = s.Driver.FindElement(By.Id("pay-with-text")).Text;
Assert.True(s.Driver.FindElement("#DefaultLang")).FindElements(By.TagName("option")).Count > 1);
var payWithTextEnglish = s.Driver.FindElement("#pay-with-text")).Text;
var prettyDropdown = s.Driver.FindElement(By.Id("prettydropdown-DefaultLang"));
var prettyDropdown = s.Driver.FindElement("#prettydropdown-DefaultLang"));
prettyDropdown.Click();
await Task.Delay(200);
prettyDropdown.FindElement(By.CssSelector("[data-value=\"da-DK\"]")).Click();
await Task.Delay(1000);
Assert.NotEqual(payWithTextEnglish, s.Driver.FindElement(By.Id("pay-with-text")).Text);
Assert.NotEqual(payWithTextEnglish, s.Driver.FindElement("#pay-with-text")).Text);
s.Driver.Navigate().GoToUrl(s.Driver.Url + "?lang=da-DK");
Assert.NotEqual(payWithTextEnglish, s.Driver.FindElement(By.Id("pay-with-text")).Text);
Assert.NotEqual(payWithTextEnglish, s.Driver.FindElement("#pay-with-text")).Text);
s.Driver.Quit();
}
@ -113,7 +113,7 @@ namespace BTCPayServer.Tests
var store = s.CreateNewStore();
s.AddLightningNode();
s.GoToStore(store.storeId, StoreNavPages.Checkout);
s.Driver.SetCheckbox(By.Id("LightningAmountInSatoshi"), true);
s.Driver.SetCheckbox("#LightningAmountInSatoshi"), true);
var command = s.Driver.FindElement(By.Name("command"));
command.Click();
@ -148,7 +148,7 @@ namespace BTCPayServer.Tests
.GetPaymentMethodDetails().GetPaymentDestination(), Network.RegTest),
new Money(0.001m, MoneyUnit.BTC));
IWebElement closebutton = null;
IElementHandle closebutton = null;
TestUtils.Eventually(() =>
{
var frameElement = s.Driver.FindElement(By.Name("btcpay"));

View File

@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -6,8 +7,7 @@ using BTCPayServer.Tests.Logging;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using PlaywrightSharp;
using Xunit;
namespace BTCPayServer.Tests
@ -17,23 +17,24 @@ namespace BTCPayServer.Tests
private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
public static string ToJson(this object o) => JsonConvert.SerializeObject(o, Formatting.None, JsonSettings);
public static void LogIn(this SeleniumTester s, string email)
public static async Task LogIn(this SeleniumTester s, string email)
{
s.Driver.FindElement(By.Id("Email")).SendKeys(email);
s.Driver.FindElement(By.Id("Password")).SendKeys("123456");
s.Driver.FindElement(By.Id("LoginButton")).Click();
s.Driver.AssertNoError();
await s.Driver.TypeAsync("#Email", email);
await s.Driver.TypeAsync("#Password", "123456");
await s.Driver.ClickAsync("#LoginButton");
await s.AssertNoError();
}
public static void AssertNoError(this IWebDriver driver)
public static async Task AssertNoError(this SeleniumTester tester)
{
try
{
Assert.NotEmpty(driver.FindElements(By.ClassName("navbar-brand")));
if (driver.PageSource.Contains("alert-danger"))
Assert.NotNull(await tester.Driver.QuerySelectorAsync(".navbar-brand"));
var dangerAlerts = await tester.Driver.QuerySelectorAllAsync(".alert-danger");
if (dangerAlerts.Any())
{
foreach (var dangerAlert in driver.FindElements(By.ClassName("alert-danger")))
Assert.False(dangerAlert.Displayed, "No alert should be displayed");
foreach (var dangerAlert in dangerAlerts)
Assert.False(await dangerAlert.IsVisibleAsync(), "No alert should be displayed");
}
}
catch
@ -44,7 +45,8 @@ namespace BTCPayServer.Tests
{
try
{
var logs = driver.Manage().Logs.GetLog(logKind);
tester.Browser.Contexts.First().
var logs = tester.Manage().Logs.GetLog(logKind);
builder.AppendLine($"Selenium [{logKind}]:");
foreach (var entry in logs)
{
@ -61,7 +63,7 @@ namespace BTCPayServer.Tests
Logs.Tester.LogInformation(builder.ToString());
builder = new StringBuilder();
builder.AppendLine("Selenium [Sources]:");
builder.AppendLine(driver.PageSource);
builder.AppendLine(tester.Browser.);
builder.AppendLine("---------");
Logs.Tester.LogInformation(builder.ToString());
throw;
@ -113,7 +115,7 @@ namespace BTCPayServer.Tests
wait.Until(d=>((IJavaScriptExecutor)d).ExecuteScript("return typeof(jQuery) === 'undefined' || jQuery.active === 0").Equals(true));
}
public static IWebElement WaitForElement(this IWebDriver driver, By selector)
public static IElementHandle WaitForElement(this IWebDriver driver, By selector)
{
var wait = new WebDriverWait(driver, SeleniumTester.ImplicitWait);
wait.UntilJsIsReady();

View File

@ -248,10 +248,10 @@ namespace BTCPayServer.Tests
s.GoToHome();
s.GoToStore(receiver.storeId);
//payjoin is not enabled by default.
Assert.False(s.Driver.FindElement(By.Id("PayJoinEnabled")).Selected);
s.Driver.SetCheckbox(By.Id("PayJoinEnabled"), true);
s.Driver.FindElement(By.Id("Save")).Click();
Assert.True(s.Driver.FindElement(By.Id("PayJoinEnabled")).Selected);
Assert.False(s.Driver.FindElement("#PayJoinEnabled")).Selected);
s.Driver.SetCheckbox("#PayJoinEnabled"), true);
s.Driver.FindElement("#Save")).Click();
Assert.True(s.Driver.FindElement("#PayJoinEnabled")).Selected);
var sender = s.CreateNewStore();
var senderSeed = s.GenerateWallet("BTC", "", true, true, format);
@ -266,12 +266,12 @@ namespace BTCPayServer.Tests
Assert.Contains($"{PayjoinClient.BIP21EndpointKey}=", bip21);
s.GoToWallet(senderWalletId, WalletsNavPages.Send);
s.Driver.FindElement(By.Id("bip21parse")).Click();
s.Driver.FindElement("#bip21parse")).Click();
s.Driver.SwitchTo().Alert().SendKeys(bip21);
s.Driver.SwitchTo().Alert().Accept();
Assert.False(string.IsNullOrEmpty(s.Driver.FindElement(By.Id("PayJoinBIP21"))
Assert.False(string.IsNullOrEmpty(s.Driver.FindElement("#PayJoinBIP21"))
.GetAttribute("value")));
s.Driver.FindElement(By.Id("SendMenu")).Click();
s.Driver.FindElement("#SendMenu")).Click();
var nbxSeedButton = s.Driver.FindElement(By.CssSelector("button[value=nbx-seed]"));
new WebDriverWait(s.Driver, SeleniumTester.ImplicitWait).Until(d=> nbxSeedButton.Enabled);
nbxSeedButton.Click();
@ -302,14 +302,14 @@ namespace BTCPayServer.Tests
Assert.Contains($"{PayjoinClient.BIP21EndpointKey}", bip21);
s.GoToWallet(senderWalletId, WalletsNavPages.Send);
s.Driver.FindElement(By.Id("bip21parse")).Click();
s.Driver.FindElement("#bip21parse")).Click();
s.Driver.SwitchTo().Alert().SendKeys(bip21);
s.Driver.SwitchTo().Alert().Accept();
Assert.False(string.IsNullOrEmpty(s.Driver.FindElement(By.Id("PayJoinBIP21"))
Assert.False(string.IsNullOrEmpty(s.Driver.FindElement("#PayJoinBIP21"))
.GetAttribute("value")));
s.Driver.FindElement(By.Id("FeeSatoshiPerByte")).Clear();
s.Driver.FindElement(By.Id("FeeSatoshiPerByte")).SendKeys("2");
s.Driver.FindElement(By.Id("SendMenu")).Click();
s.Driver.FindElement("#FeeSatoshiPerByte")).Clear();
s.Driver.FindElement("#FeeSatoshiPerByte")).SendKeys("2");
s.Driver.FindElement("#SendMenu")).Click();
s.Driver.FindElement(By.CssSelector("button[value=nbx-seed]")).Click();
var txId = await s.Server.WaitForEvent<NewOnChainTransactionEvent>(() =>
{

View File

@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Models;
using BTCPayServer.Lightning;
using BTCPayServer.Lightning.CLightning;
using BTCPayServer.Services;
using BTCPayServer.Tests.Logging;
using BTCPayServer.Views.Manage;
using BTCPayServer.Views.Server;
@ -16,16 +14,15 @@ using BTCPayServer.Views.Wallets;
using Microsoft.Extensions.Configuration;
using NBitcoin;
using BTCPayServer.BIP78.Sender;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.Extensions;
using PlaywrightSharp;
using PlaywrightSharp.Chromium;
using Xunit;
namespace BTCPayServer.Tests
{
public class SeleniumTester : IDisposable
{
public IWebDriver Driver { get; set; }
public IPage Driver { get; set; }
public ServerTester Server { get; set; }
public WalletId WalletId { get; set; }
@ -44,52 +41,55 @@ namespace BTCPayServer.Tests
var builder = new ConfigurationBuilder();
builder.AddUserSecrets("AB0AC1DD-9D26-485B-9416-56A33F268117");
var config = builder.Build();
this.PlayWright = await Playwright.CreateAsync();
// Run `dotnet user-secrets set RunSeleniumInBrowser true` to run tests in browser
var runInBrowser = config["RunSeleniumInBrowser"] == "true";
// Reset this using `dotnet user-secrets remove RunSeleniumInBrowser`
var chromeDriverPath = config["ChromeDriverDirectory"] ?? (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory());
// var chromeDriverPath = config["ChromeDriverDirectory"] ?? (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory());
var options = new ChromeOptions();
if (Server.PayTester.InContainer)
{
// this must be first option https://stackoverflow.com/questions/53073411/selenium-webdriverexceptionchrome-failed-to-start-crashed-as-google-chrome-is#comment102570662_53073789
options.AddArgument("no-sandbox");
}
if (!runInBrowser)
{
options.AddArguments("headless");
}
options.AddArguments($"window-size={windowSize.Width}x{windowSize.Height}");
options.AddArgument("shm-size=2g");
var options = new List<string>();
// options.Add($"window-size={windowSize.Width}x{windowSize.Height}");
// options.Add("shm-size=2g");
var cds = ChromeDriverService.CreateDefaultService(chromeDriverPath);
cds.Port = Utils.FreeTcpPort();
cds.HostName = "127.0.0.1";
cds.Start();
Driver = new ChromeDriver(cds, options,
// A bit less than test timeout
TimeSpan.FromSeconds(50));
if (runInBrowser)
this.Browser = await this.PlayWright.Chromium.LaunchAsync(
headless:!runInBrowser,
chromiumSandbox:!Server.PayTester.InContainer,
args:options.ToArray()
);
this.Context = await Browser.NewContextAsync(new ViewportSize()
{
// ensure maximized window size
// otherwise TESTS WILL FAIL because of different hierarchy in navigation menu
Driver.Manage().Window.Maximize();
}
Width = windowSize.Width, Height = windowSize.Height
});
Driver = await Context.NewPageAsync();
// if (runInBrowser)
// {
// // ensure maximized window size
// // otherwise TESTS WILL FAIL because of different hierarchy in navigation menu
// Browser..Window.Maximize();
// }
Logs.Tester.LogInformation($"Selenium: Using {Driver.GetType()}");
Logs.Tester.LogInformation($"Selenium: Browsing to {Server.PayTester.ServerUri}");
Logs.Tester.LogInformation($"Selenium: Resolution {Driver.Manage().Window.Size}");
GoToRegister();
Logs.Tester.LogInformation($"Selenium: Resolution {Driver.ViewportSize}");
await GoToRegister();
Driver.AssertNoError();
}
internal IWebElement FindAlertMessage(StatusMessageModel.StatusSeverity severity = StatusMessageModel.StatusSeverity.Success)
public IChromiumBrowserContext Context { get; set; }
public IChromiumBrowser Browser { get; set; }
public IPlaywright PlayWright { get; internal set; }
internal async Task<IElementHandle> FindAlertMessage(StatusMessageModel.StatusSeverity severity = StatusMessageModel.StatusSeverity.Success)
{
var className = $"alert-{StatusMessageModel.ToString(severity)}";
var el = Driver.FindElement(By.ClassName(className)) ?? Driver.WaitForElement(By.ClassName(className));
var className = $".alert-{StatusMessageModel.ToString(severity)}";
var el = await Driver.QuerySelectorAsync(className) ?? await Driver.WaitForSelectorAsync(className);
if (el is null)
throw new NoSuchElementException($"Unable to find {className}");
return el;
@ -100,33 +100,33 @@ namespace BTCPayServer.Tests
return Server.PayTester.ServerUri.AbsoluteUri.WithoutEndingSlash() + relativeLink.WithStartingSlash();
}
public void GoToRegister()
public async Task GoToRegister()
{
Driver.Navigate().GoToUrl(Link("/register"));
await Driver.GoToAsync(Link("/register"));
}
public string RegisterNewUser(bool isAdmin = false)
public async Task<string> RegisterNewUser(bool isAdmin = false)
{
var usr = RandomUtils.GetUInt256().ToString().Substring(64 - 20) + "@a.com";
Logs.Tester.LogInformation($"User: {usr} with password 123456");
Driver.FindElement(By.Id("Email")).SendKeys(usr);
Driver.FindElement(By.Id("Password")).SendKeys("123456");
Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("123456");
if (isAdmin)
Driver.FindElement(By.Id("IsAdmin")).Click();
Driver.FindElement(By.Id("RegisterButton")).Click();
await Driver.TypeAsync("#Email", usr);
await Driver.TypeAsync("#Password","123456");
await Driver.TypeAsync("#ConfirmPassword", "123456");
if (isAdmin)
await Driver.CheckAsync("#IsAdmin");
await Driver.ClickAsync("#RegisterButton");
Driver.AssertNoError();
return usr;
}
public (string storeName, string storeId) CreateNewStore()
{
Driver.WaitForElement(By.Id("Stores")).Click();
Driver.WaitForElement(By.Id("CreateStore")).Click();
Driver.WaitForElement("#Stores")).Click();
Driver.WaitForElement("#CreateStore")).Click();
var name = "Store" + RandomUtils.GetUInt64();
Driver.WaitForElement(By.Id("Name")).SendKeys(name);
Driver.WaitForElement(By.Id("Create")).Click();
StoreId = Driver.WaitForElement(By.Id("Id")).GetAttribute("value");
Driver.WaitForElement("#Name")).SendKeys(name);
Driver.WaitForElement("#Create")).Click();
StoreId = Driver.WaitForElement("#Id")).GetAttribute("value");
return (name, StoreId);
}
@ -137,46 +137,46 @@ namespace BTCPayServer.Tests
// Replace previous wallet case
if (Driver.PageSource.Contains("id=\"ChangeWalletLink\""))
{
Driver.FindElement(By.Id("ChangeWalletLink")).Click();
Driver.FindElement(By.Id("continue")).Click();
Driver.FindElement("#ChangeWalletLink")).Click();
Driver.FindElement("#continue")).Click();
}
if (string.IsNullOrEmpty(seed))
{
var option = privkeys ? "Hotwallet" : "Watchonly";
Logs.Tester.LogInformation($"Generating new seed ({option})");
Driver.FindElement(By.Id("GenerateWalletLink")).Click();
Driver.FindElement("#GenerateWalletLink")).Click();
Driver.FindElement(By.Id($"Generate{option}Link")).Click();
}
else
{
Logs.Tester.LogInformation("Progressing with existing seed");
Driver.FindElement(By.Id("ImportWalletOptionsLink")).Click();
Driver.FindElement(By.Id("ImportSeedLink")).Click();
Driver.FindElement(By.Id("ExistingMnemonic")).SendKeys(seed);
Driver.SetCheckbox(By.Id("SavePrivateKeys"), privkeys);
Driver.FindElement("#ImportWalletOptionsLink")).Click();
Driver.FindElement("#ImportSeedLink")).Click();
Driver.FindElement("#ExistingMnemonic")).SendKeys(seed);
Driver.SetCheckbox("#SavePrivateKeys"), privkeys);
}
Driver.FindElement(By.Id("ScriptPubKeyType")).Click();
Driver.FindElement("#ScriptPubKeyType")).Click();
Driver.FindElement(By.CssSelector($"#ScriptPubKeyType option[value={format}]")).Click();
// Open advanced settings via JS, because if we click the link it triggers the toggle animation.
// This leads to Selenium trying to click the button while it is moving resulting in an error.
Driver.ExecuteJavaScript("document.getElementById('AdvancedSettings').classList.add('show')");
Driver.SetCheckbox(By.Id("ImportKeysToRPC"), importkeys);
Driver.FindElement(By.Id("Continue")).Click();
Driver.SetCheckbox("#ImportKeysToRPC"), importkeys);
Driver.FindElement("#Continue")).Click();
// Seed backup page
FindAlertMessage();
if (string.IsNullOrEmpty(seed))
{
seed = Driver.FindElements(By.Id("RecoveryPhrase")).First().GetAttribute("data-mnemonic");
seed = Driver.FindElements("#RecoveryPhrase")).First().GetAttribute("data-mnemonic");
}
// Confirm seed backup
Driver.FindElement(By.Id("confirm")).Click();
Driver.FindElement(By.Id("submit")).Click();
Driver.FindElement("#confirm")).Click();
Driver.FindElement("#submit")).Click();
WalletId = new WalletId(StoreId, cryptoCode);
return new Mnemonic(seed);
@ -185,11 +185,11 @@ namespace BTCPayServer.Tests
public void AddDerivationScheme(string cryptoCode = "BTC", string derivationScheme = "xpub661MyMwAqRbcGABgHMUXDzPzH1tU7eZaAaJQXhDXsSxsqyQzQeU6kznNfSuAyqAK9UaWSaZaMFdNiY5BCF4zBPAzSnwfUAwUhwttuAKwfRX-[legacy]")
{
Driver.FindElement(By.Id($"Modify{cryptoCode}")).Click();
Driver.FindElement(By.Id("ImportWalletOptionsLink")).Click();
Driver.FindElement(By.Id("ImportXpubLink")).Click();
Driver.FindElement(By.Id("DerivationScheme")).SendKeys(derivationScheme);
Driver.FindElement(By.Id("Continue")).Click();
Driver.FindElement(By.Id("Confirm")).Click();
Driver.FindElement("#ImportWalletOptionsLink")).Click();
Driver.FindElement("#ImportXpubLink")).Click();
Driver.FindElement("#DerivationScheme")).SendKeys(derivationScheme);
Driver.FindElement("#Continue")).Click();
Driver.FindElement("#Confirm")).Click();
FindAlertMessage();
}
@ -210,19 +210,19 @@ namespace BTCPayServer.Tests
if (connectionString == null)
{
Assert.True(Driver.FindElement(By.Id("LightningNodeType-Internal")).Enabled, "Usage of the internal Lightning node is disabled.");
Assert.True(Driver.FindElement("#LightningNodeType-Internal")).Enabled, "Usage of the internal Lightning node is disabled.");
Driver.FindElement(By.CssSelector("label[for=\"LightningNodeType-Internal\"]")).Click();
}
else
{
Driver.FindElement(By.CssSelector("label[for=\"LightningNodeType-Custom\"]")).Click();
Driver.FindElement(By.Id("ConnectionString")).SendKeys(connectionString);
Driver.FindElement("#ConnectionString")).SendKeys(connectionString);
Driver.FindElement(By.Id("test")).Click();
Driver.FindElement("#test")).Click();
Assert.Contains("Connection to the Lightning node successful.", FindAlertMessage().Text);
}
Driver.FindElement(By.Id("save")).Click();
Driver.FindElement("#save")).Click();
Assert.Contains($"{cryptoCode} Lightning node updated.", FindAlertMessage().Text);
var enabled = Driver.FindElement(By.Id($"{cryptoCode}LightningEnabled"));
@ -277,24 +277,24 @@ namespace BTCPayServer.Tests
public void Logout()
{
Driver.FindElement(By.Id("Logout")).Click();
Driver.FindElement("#Logout")).Click();
}
public void Login(string user, string password)
{
Driver.FindElement(By.Id("Email")).SendKeys(user);
Driver.FindElement(By.Id("Password")).SendKeys(password);
Driver.FindElement(By.Id("LoginButton")).Click();
Driver.FindElement("#Email")).SendKeys(user);
Driver.FindElement("#Password")).SendKeys(password);
Driver.FindElement("#LoginButton")).Click();
}
public void GoToStores()
{
Driver.FindElement(By.Id("Stores")).Click();
Driver.FindElement("#Stores")).Click();
}
public void GoToStore(string storeId, StoreNavPages storeNavPage = StoreNavPages.Index)
{
Driver.FindElement(By.Id("Stores")).Click();
Driver.FindElement("#Stores")).Click();
Driver.FindElement(By.Id($"update-store-{storeId}")).Click();
if (storeNavPage != StoreNavPages.Index)
@ -305,19 +305,19 @@ namespace BTCPayServer.Tests
public void GoToInvoiceCheckout(string invoiceId)
{
Driver.FindElement(By.Id("Invoices")).Click();
Driver.FindElement("#Invoices")).Click();
Driver.FindElement(By.Id($"invoice-checkout-{invoiceId}")).Click();
CheckForJSErrors();
}
public void GoToInvoices()
{
Driver.FindElement(By.Id("Invoices")).Click();
Driver.FindElement("#Invoices")).Click();
}
public void GoToProfile(ManageNavPages navPages = ManageNavPages.Index)
{
Driver.FindElement(By.Id("MySettings")).Click();
Driver.FindElement("#MySettings")).Click();
if (navPages != ManageNavPages.Index)
{
Driver.FindElement(By.Id(navPages.ToString())).Click();
@ -332,14 +332,14 @@ namespace BTCPayServer.Tests
public string CreateInvoice(string storeName, decimal amount = 100, string currency = "USD", string refundEmail = "")
{
GoToInvoices();
Driver.FindElement(By.Id("CreateNewInvoice")).Click();
Driver.FindElement(By.Id("Amount")).SendKeys(amount.ToString(CultureInfo.InvariantCulture));
var currencyEl = Driver.FindElement(By.Id("Currency"));
Driver.FindElement("#CreateNewInvoice")).Click();
Driver.FindElement("#Amount")).SendKeys(amount.ToString(CultureInfo.InvariantCulture));
var currencyEl = Driver.FindElement("#Currency"));
currencyEl.Clear();
currencyEl.SendKeys(currency);
Driver.FindElement(By.Id("BuyerEmail")).SendKeys(refundEmail);
Driver.FindElement("#BuyerEmail")).SendKeys(refundEmail);
Driver.FindElement(By.Name("StoreId")).SendKeys(storeName);
Driver.FindElement(By.Id("Create")).Click();
Driver.FindElement("#Create")).Click();
var statusElement = FindAlertMessage();
var id = statusElement.Text.Split(" ")[1];
@ -350,8 +350,8 @@ namespace BTCPayServer.Tests
{
walletId ??= WalletId;
GoToWallet(walletId, WalletsNavPages.Receive);
Driver.FindElement(By.Id("generateButton")).Click();
var addressStr = Driver.FindElement(By.Id("address")).GetProperty("value");
Driver.FindElement("#generateButton")).Click();
var addressStr = Driver.FindElement("#address")).GetProperty("value");
var address = BitcoinAddress.Create(addressStr, ((BTCPayNetwork)Server.NetworkProvider.GetNetwork(walletId.CryptoCode)).NBitcoinNetwork);
for (var i = 0; i < coins; i++)
{
@ -367,10 +367,10 @@ namespace BTCPayServer.Tests
Assert.Contains($"{PayjoinClient.BIP21EndpointKey}", bip21);
GoToWallet(walletId);
Driver.FindElement(By.Id("bip21parse")).Click();
Driver.FindElement("#bip21parse")).Click();
Driver.SwitchTo().Alert().SendKeys(bip21);
Driver.SwitchTo().Alert().Accept();
Driver.FindElement(By.Id("SendMenu")).Click();
Driver.FindElement("#SendMenu")).Click();
Driver.FindElement(By.CssSelector("button[value=nbx-seed]")).Click();
Driver.FindElement(By.CssSelector("button[value=broadcast]")).Click();
}
@ -415,7 +415,7 @@ namespace BTCPayServer.Tests
public void GoToServer(ServerNavPages navPages = ServerNavPages.Index)
{
Driver.FindElement(By.Id("ServerSettings")).Click();
Driver.FindElement("#ServerSettings")).Click();
if (navPages != ServerNavPages.Index)
{
Driver.FindElement(By.Id($"Server-{navPages}")).Click();
@ -435,4 +435,12 @@ namespace BTCPayServer.Tests
}
}
}
public class NoSuchElementException : Exception
{
public NoSuchElementException(string message):base(message)
{
}
}
}

View File

@ -48,7 +48,7 @@ namespace BTCPayServer.Tests
{
await s.StartAsync();
s.RegisterNewUser(true);
s.Driver.FindElement(By.Id("ServerSettings")).Click();
s.Driver.FindElement("#ServerSettings")).Click();
s.Driver.AssertNoError();
s.ClickOnAllSideMenus();
s.Driver.FindElement(By.LinkText("Services")).Click();
@ -70,24 +70,24 @@ namespace BTCPayServer.Tests
s.Server.ActivateLightning();
await s.StartAsync();
s.RegisterNewUser(true);
s.Driver.FindElement(By.Id("ServerSettings")).Click();
s.Driver.FindElement("#ServerSettings")).Click();
s.Driver.AssertNoError();
s.Driver.FindElement(By.LinkText("Services")).Click();
Logs.Tester.LogInformation("Let's if we can access LND's seed");
Assert.Contains("server/services/lndseedbackup/BTC", s.Driver.PageSource);
s.Driver.Navigate().GoToUrl(s.Link("/server/services/lndseedbackup/BTC"));
s.Driver.FindElement(By.Id("details")).Click();
var seedEl = s.Driver.FindElement(By.Id("SeedTextArea"));
s.Driver.FindElement("#details")).Click();
var seedEl = s.Driver.FindElement("#SeedTextArea"));
Assert.True(seedEl.Displayed);
Assert.Contains("about over million", seedEl.Text, StringComparison.OrdinalIgnoreCase);
var passEl = s.Driver.FindElement(By.Id("PasswordInput"));
var passEl = s.Driver.FindElement("#PasswordInput"));
Assert.True(passEl.Displayed);
Assert.Contains(passEl.Text, "hellorockstar", StringComparison.OrdinalIgnoreCase);
s.Driver.FindElement(By.Id("delete")).Click();
s.Driver.FindElement(By.Id("continue")).Click();
s.FindAlertMessage();
seedEl = s.Driver.FindElement(By.Id("SeedTextArea"));
s.Driver.FindElement("#delete")).Click();
s.Driver.FindElement("#continue")).Click();
await s.FindAlertMessage();
seedEl = s.Driver.FindElement("#SeedTextArea"));
Assert.Contains("Seed removed", seedEl.Text, StringComparison.OrdinalIgnoreCase);
}
}
@ -112,17 +112,17 @@ namespace BTCPayServer.Tests
s.GoToLogin();
s.Login(u1.RegisterDetails.Email, u1.RegisterDetails.Password);
s.GoToProfile(ManageNavPages.Index);
s.Driver.FindElement(By.Id("Email")).Clear();
s.Driver.FindElement(By.Id("Email")).SendKeys(u2.RegisterDetails.Email);
s.Driver.FindElement(By.Id("save")).Click();
s.Driver.FindElement("#Email")).Clear();
s.Driver.FindElement("#Email")).SendKeys(u2.RegisterDetails.Email);
s.Driver.FindElement("#save")).Click();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Error);
s.GoToProfile(ManageNavPages.Index);
s.Driver.FindElement(By.Id("Email")).Clear();
s.Driver.FindElement("#Email")).Clear();
var changedEmail = Guid.NewGuid() + "@lol.com";
s.Driver.FindElement(By.Id("Email")).SendKeys(changedEmail);
s.Driver.FindElement(By.Id("save")).Click();
s.Driver.FindElement("#Email")).SendKeys(changedEmail);
s.Driver.FindElement("#save")).Click();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
var manager = tester.PayTester.GetService<UserManager<ApplicationUser>>();
@ -148,9 +148,9 @@ namespace BTCPayServer.Tests
// We should be redirected to login
//Same User Can Log Back In
s.Driver.FindElement(By.Id("Email")).SendKeys(email);
s.Driver.FindElement(By.Id("Password")).SendKeys("123456");
s.Driver.FindElement(By.Id("LoginButton")).Click();
s.Driver.FindElement("#Email")).SendKeys(email);
s.Driver.FindElement("#Password")).SendKeys("123456");
s.Driver.FindElement("#LoginButton")).Click();
// We should be redirected to invoice
Assert.EndsWith("/invoices", s.Driver.Url);
@ -160,22 +160,22 @@ namespace BTCPayServer.Tests
Assert.Contains("ReturnUrl=%2Fserver%2Fusers", s.Driver.Url);
//Change Password & Log Out
s.Driver.FindElement(By.Id("MySettings")).Click();
s.Driver.FindElement(By.Id("ChangePassword")).Click();
s.Driver.FindElement(By.Id("OldPassword")).SendKeys("123456");
s.Driver.FindElement(By.Id("NewPassword")).SendKeys("abc???");
s.Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("abc???");
s.Driver.FindElement(By.Id("UpdatePassword")).Click();
s.Driver.FindElement(By.Id("Logout")).Click();
s.Driver.FindElement("#MySettings")).Click();
s.Driver.FindElement("#ChangePassword")).Click();
s.Driver.FindElement("#OldPassword")).SendKeys("123456");
s.Driver.FindElement("#NewPassword")).SendKeys("abc???");
s.Driver.FindElement("#ConfirmPassword")).SendKeys("abc???");
s.Driver.FindElement("#UpdatePassword")).Click();
s.Driver.FindElement("#Logout")).Click();
s.Driver.AssertNoError();
//Log In With New Password
s.Driver.FindElement(By.Id("Email")).SendKeys(email);
s.Driver.FindElement(By.Id("Password")).SendKeys("abc???");
s.Driver.FindElement(By.Id("LoginButton")).Click();
s.Driver.FindElement("#Email")).SendKeys(email);
s.Driver.FindElement("#Password")).SendKeys("abc???");
s.Driver.FindElement("#LoginButton")).Click();
Assert.True(s.Driver.PageSource.Contains("Stores"), "Can't Access Stores");
s.Driver.FindElement(By.Id("MySettings")).Click();
s.Driver.FindElement("#MySettings")).Click();
s.ClickOnAllSideMenus();
//let's test invite link
@ -183,28 +183,28 @@ namespace BTCPayServer.Tests
s.GoToRegister();
s.RegisterNewUser(true);
s.GoToServer(ServerNavPages.Users);
s.Driver.FindElement(By.Id("CreateUser")).Click();
s.Driver.FindElement("#CreateUser")).Click();
var usr = RandomUtils.GetUInt256().ToString().Substring(64 - 20) + "@a.com";
s.Driver.FindElement(By.Id("Email")).SendKeys(usr);
s.Driver.FindElement(By.Id("Save")).Click();
s.Driver.FindElement("#Email")).SendKeys(usr);
s.Driver.FindElement("#Save")).Click();
var url = s.FindAlertMessage().FindElement(By.TagName("a")).Text;
s.Logout();
s.Driver.Navigate().GoToUrl(url);
Assert.Equal("hidden", s.Driver.FindElement(By.Id("Email")).GetAttribute("type"));
Assert.Equal(usr, s.Driver.FindElement(By.Id("Email")).GetAttribute("value"));
Assert.Equal("hidden", s.Driver.FindElement("#Email")).GetAttribute("type"));
Assert.Equal(usr, s.Driver.FindElement("#Email")).GetAttribute("value"));
s.Driver.FindElement(By.Id("Password")).SendKeys("123456");
s.Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("123456");
s.Driver.FindElement(By.Id("SetPassword")).Click();
s.FindAlertMessage();
s.Driver.FindElement(By.Id("Email")).SendKeys(usr);
s.Driver.FindElement(By.Id("Password")).SendKeys("123456");
s.Driver.FindElement(By.Id("LoginButton")).Click();
s.Driver.FindElement("#Password")).SendKeys("123456");
s.Driver.FindElement("#ConfirmPassword")).SendKeys("123456");
s.Driver.FindElement("#SetPassword")).Click();
await s.FindAlertMessage();
s.Driver.FindElement("#Email")).SendKeys(usr);
s.Driver.FindElement("#Password")).SendKeys("123456");
s.Driver.FindElement("#LoginButton")).Click();
// We should be logged in now
s.Driver.FindElement(By.Id("mainNav"));
s.Driver.FindElement("#mainNav"));
}
}
@ -230,26 +230,26 @@ namespace BTCPayServer.Tests
}
s.Driver.Navigate().GoToUrl(s.Link("/server/services/ssh"));
s.Driver.AssertNoError();
s.Driver.FindElement(By.Id("SSHKeyFileContent")).Clear();
s.Driver.FindElement(By.Id("SSHKeyFileContent")).SendKeys("tes't\r\ntest2");
s.Driver.FindElement(By.Id("submit")).Click();
s.Driver.FindElement("#SSHKeyFileContent")).Clear();
s.Driver.FindElement("#SSHKeyFileContent")).SendKeys("tes't\r\ntest2");
s.Driver.FindElement("#submit")).Click();
s.Driver.AssertNoError();
var text = s.Driver.FindElement(By.Id("SSHKeyFileContent")).Text;
var text = s.Driver.FindElement("#SSHKeyFileContent")).Text;
// Browser replace \n to \r\n, so it is hard to compare exactly what we want
Assert.Contains("tes't", text);
Assert.Contains("test2", text);
Assert.True(s.Driver.PageSource.Contains("authorized_keys has been updated", StringComparison.OrdinalIgnoreCase));
s.Driver.FindElement(By.Id("SSHKeyFileContent")).Clear();
s.Driver.FindElement(By.Id("submit")).Click();
s.Driver.FindElement("#SSHKeyFileContent")).Clear();
s.Driver.FindElement("#submit")).Click();
text = s.Driver.FindElement(By.Id("SSHKeyFileContent")).Text;
text = s.Driver.FindElement("#SSHKeyFileContent")).Text;
Assert.DoesNotContain("test2", text);
// Let's try to disable it now
s.Driver.FindElement(By.Id("disable")).Click();
s.Driver.FindElement(By.Id("continue")).Click();
s.Driver.FindElement("#disable")).Click();
s.Driver.FindElement("#continue")).Click();
policies = await settings.GetSettingAsync<PoliciesSettings>();
Assert.True(policies.DisableSSHService);
@ -271,7 +271,7 @@ namespace BTCPayServer.Tests
if (s.Driver.PageSource.Contains("Configured"))
{
s.Driver.FindElement(By.CssSelector("button[value=\"ResetPassword\"]")).Submit();
s.FindAlertMessage();
await s.FindAlertMessage();
}
CanSetupEmailCore(s);
s.CreateNewStore();
@ -296,26 +296,26 @@ namespace BTCPayServer.Tests
{
// Cleanup old test run
s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns/pouet.hello.com/delete"));
s.Driver.FindElement(By.Id("continue")).Click();
s.Driver.FindElement("#continue")).Click();
}
s.Driver.FindElement(By.Id("AddDynamicDNS")).Click();
s.Driver.FindElement("#AddDynamicDNS")).Click();
s.Driver.AssertNoError();
// We will just cheat for test purposes by only querying the server
s.Driver.FindElement(By.Id("ServiceUrl")).SendKeys(s.Link("/"));
s.Driver.FindElement(By.Id("Settings_Hostname")).SendKeys("pouet.hello.com");
s.Driver.FindElement(By.Id("Settings_Login")).SendKeys("MyLog");
s.Driver.FindElement(By.Id("Settings_Password")).SendKeys("MyLog" + Keys.Enter);
s.Driver.FindElement("#ServiceUrl")).SendKeys(s.Link("/"));
s.Driver.FindElement("#Settings_Hostname")).SendKeys("pouet.hello.com");
s.Driver.FindElement("#Settings_Login")).SendKeys("MyLog");
s.Driver.FindElement("#Settings_Password")).SendKeys("MyLog" + Keys.Enter);
s.Driver.AssertNoError();
Assert.Contains("The Dynamic DNS has been successfully queried", s.Driver.PageSource);
Assert.EndsWith("/server/services/dynamic-dns", s.Driver.Url);
// Try to do the same thing should fail (hostname already exists)
s.Driver.FindElement(By.Id("AddDynamicDNS")).Click();
s.Driver.FindElement("#AddDynamicDNS")).Click();
s.Driver.AssertNoError();
s.Driver.FindElement(By.Id("ServiceUrl")).SendKeys(s.Link("/"));
s.Driver.FindElement(By.Id("Settings_Hostname")).SendKeys("pouet.hello.com");
s.Driver.FindElement(By.Id("Settings_Login")).SendKeys("MyLog");
s.Driver.FindElement(By.Id("Settings_Password")).SendKeys("MyLog" + Keys.Enter);
s.Driver.FindElement("#ServiceUrl")).SendKeys(s.Link("/"));
s.Driver.FindElement("#Settings_Hostname")).SendKeys("pouet.hello.com");
s.Driver.FindElement("#Settings_Login")).SendKeys("MyLog");
s.Driver.FindElement("#Settings_Password")).SendKeys("MyLog" + Keys.Enter);
s.Driver.AssertNoError();
Assert.Contains("This hostname already exists", s.Driver.PageSource);
@ -323,7 +323,7 @@ namespace BTCPayServer.Tests
s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns"));
Assert.Contains("/server/services/dynamic-dns/pouet.hello.com/delete", s.Driver.PageSource);
s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns/pouet.hello.com/delete"));
s.Driver.FindElement(By.Id("continue")).Click();
s.Driver.FindElement("#continue")).Click();
s.Driver.AssertNoError();
Assert.DoesNotContain("/server/services/dynamic-dns/pouet.hello.com/delete", s.Driver.PageSource);
@ -365,7 +365,7 @@ namespace BTCPayServer.Tests
s.GoToStore(storeId);
s.AddLightningNode();
s.Driver.AssertNoError();
var successAlert = s.FindAlertMessage();
var successAlert = await s.FindAlertMessage();
Assert.Contains("BTC Lightning node updated.", successAlert.Text);
Assert.False(s.Driver.PageSource.Contains(offchainHint), "Lightning hint should be dismissed at this point");
@ -373,28 +373,28 @@ namespace BTCPayServer.Tests
s.ClickOnAllSideMenus();
s.GoToInvoices();
var invoiceId = s.CreateInvoice(storeName);
s.FindAlertMessage();
await s.FindAlertMessage();
s.Driver.FindElement(By.ClassName("invoice-details-link")).Click();
var invoiceUrl = s.Driver.Url;
//let's test archiving an invoice
Assert.DoesNotContain("Archived", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
s.Driver.FindElement(By.Id("btn-archive-toggle")).Click();
Assert.Contains("Archived", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
Assert.DoesNotContain("Archived", s.Driver.FindElement("#btn-archive-toggle")).Text);
s.Driver.FindElement("#btn-archive-toggle")).Click();
Assert.Contains("Archived", s.Driver.FindElement("#btn-archive-toggle")).Text);
//check that it no longer appears in list
s.GoToInvoices();
Assert.DoesNotContain(invoiceId, s.Driver.PageSource);
//ok, let's unarchive and see that it shows again
s.Driver.Navigate().GoToUrl(invoiceUrl);
s.Driver.FindElement(By.Id("btn-archive-toggle")).Click();
s.FindAlertMessage();
Assert.DoesNotContain("Archived", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
s.Driver.FindElement("#btn-archive-toggle")).Click();
await s.FindAlertMessage();
Assert.DoesNotContain("Archived", s.Driver.FindElement("#btn-archive-toggle")).Text);
s.GoToInvoices();
Assert.Contains(invoiceId, s.Driver.PageSource);
// When logout we should not be able to access store and invoice details
s.Driver.FindElement(By.Id("Logout")).Click();
s.Driver.FindElement("#Logout")).Click();
s.Driver.Navigate().GoToUrl(storeUrl);
Assert.Contains("ReturnUrl", s.Driver.Url);
s.Driver.Navigate().GoToUrl(invoiceUrl);
@ -412,7 +412,7 @@ namespace BTCPayServer.Tests
// Let's add Bob as a guest to alice's store
s.LogIn(alice);
s.Driver.Navigate().GoToUrl(storeUrl + "/users");
s.Driver.FindElement(By.Id("Email")).SendKeys(bob + Keys.Enter);
s.Driver.FindElement("#Email")).SendKeys(bob + Keys.Enter);
Assert.Contains("User added successfully", s.Driver.PageSource);
s.Logout();
@ -426,10 +426,10 @@ namespace BTCPayServer.Tests
// Alice should be able to delete the store
s.Logout();
s.LogIn(alice);
s.Driver.FindElement(By.Id("Stores")).Click();
s.Driver.FindElement("#Stores")).Click();
s.Driver.FindElement(By.LinkText("Remove")).Click();
s.Driver.FindElement(By.Id("continue")).Click();
s.Driver.FindElement(By.Id("Stores")).Click();
s.Driver.FindElement("#continue")).Click();
s.Driver.FindElement("#Stores")).Click();
s.Driver.Navigate().GoToUrl(storeUrl);
Assert.Contains("ReturnUrl", s.Driver.Url);
}
@ -448,13 +448,13 @@ namespace BTCPayServer.Tests
s.CreateNewStore();
s.AddDerivationScheme();
s.Driver.FindElement(By.Id("Tokens")).Click();
s.Driver.FindElement(By.Id("CreateNewToken")).Click();
s.Driver.FindElement(By.Id("RequestPairing")).Click();
s.Driver.FindElement("#Tokens")).Click();
s.Driver.FindElement("#CreateNewToken")).Click();
s.Driver.FindElement("#RequestPairing")).Click();
var pairingCode = AssertUrlHasPairingCode(s);
s.Driver.FindElement(By.Id("ApprovePairing")).Click();
s.FindAlertMessage();
s.Driver.FindElement("#ApprovePairing")).Click();
await s.FindAlertMessage();
Assert.Contains(pairingCode, s.Driver.PageSource);
var client = new NBitpayClient.Bitpay(new Key(), s.Server.PayTester.ServerUri);
@ -470,7 +470,7 @@ namespace BTCPayServer.Tests
var code = await client.RequestClientAuthorizationAsync("hehe", NBitpayClient.Facade.Merchant);
s.Driver.Navigate().GoToUrl(code.CreateLink(s.Server.PayTester.ServerUri));
s.Driver.FindElement(By.Id("ApprovePairing")).Click();
s.Driver.FindElement("#ApprovePairing")).Click();
await client.CreateInvoiceAsync(new NBitpayClient.Invoice()
{
@ -480,8 +480,8 @@ namespace BTCPayServer.Tests
}, NBitpayClient.Facade.Merchant);
s.Driver.Navigate().GoToUrl(s.Link("/api-tokens"));
s.Driver.FindElement(By.Id("RequestPairing")).Click();
s.Driver.FindElement(By.Id("ApprovePairing")).Click();
s.Driver.FindElement("#RequestPairing")).Click();
s.Driver.FindElement("#ApprovePairing")).Click();
AssertUrlHasPairingCode(s);
}
}
@ -495,23 +495,23 @@ namespace BTCPayServer.Tests
s.RegisterNewUser();
var (storeName, _) = s.CreateNewStore();
s.Driver.FindElement(By.Id("Apps")).Click();
s.Driver.FindElement(By.Id("CreateNewApp")).Click();
s.Driver.FindElement("#Apps")).Click();
s.Driver.FindElement("#CreateNewApp")).Click();
s.Driver.FindElement(By.Name("Name")).SendKeys("PoS" + Guid.NewGuid());
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("PointOfSale");
s.Driver.FindElement(By.Id("SelectedStore")).SendKeys(storeName);
s.Driver.FindElement(By.Id("Create")).Click();
s.Driver.FindElement(By.Id("DefaultView")).SendKeys("Cart");
s.Driver.FindElement("#SelectedAppType")).SendKeys("PointOfSale");
s.Driver.FindElement("#SelectedStore")).SendKeys(storeName);
s.Driver.FindElement("#Create")).Click();
s.Driver.FindElement("#DefaultView")).SendKeys("Cart");
s.Driver.FindElement(By.CssSelector(".template-item:nth-of-type(1) .btn-primary")).Click();
s.Driver.FindElement(By.Id("BuyButtonText")).SendKeys("Take my money");
s.Driver.FindElement(By.Id("SaveItemChanges")).Click();
s.Driver.FindElement(By.Id("ToggleRawEditor")).Click();
s.Driver.FindElement("#BuyButtonText")).SendKeys("Take my money");
s.Driver.FindElement("#SaveItemChanges")).Click();
s.Driver.FindElement("#ToggleRawEditor")).Click();
var template = s.Driver.FindElement(By.Id("Template")).GetAttribute("value");
var template = s.Driver.FindElement("#Template")).GetAttribute("value");
Assert.Contains("buyButtonText: Take my money", template);
s.Driver.FindElement(By.Id("SaveSettings")).Click();
s.Driver.FindElement(By.Id("ViewApp")).Click();
s.Driver.FindElement("#SaveSettings")).Click();
s.Driver.FindElement("#ViewApp")).Click();
var posBaseUrl = s.Driver.Url.Replace("/Cart", "");
Assert.True(s.Driver.PageSource.Contains("Tea shop"), "Unable to create PoS");
@ -536,18 +536,18 @@ namespace BTCPayServer.Tests
var (storeName, _) = s.CreateNewStore();
s.AddDerivationScheme();
s.Driver.FindElement(By.Id("Apps")).Click();
s.Driver.FindElement(By.Id("CreateNewApp")).Click();
s.Driver.FindElement("#Apps")).Click();
s.Driver.FindElement("#CreateNewApp")).Click();
s.Driver.FindElement(By.Name("Name")).SendKeys("CF" + Guid.NewGuid());
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Crowdfund");
s.Driver.FindElement(By.Id("SelectedStore")).SendKeys(storeName);
s.Driver.FindElement(By.Id("Create")).Click();
s.Driver.FindElement(By.Id("Title")).SendKeys("Kukkstarter");
s.Driver.FindElement("#SelectedAppType")).SendKeys("Crowdfund");
s.Driver.FindElement("#SelectedStore")).SendKeys(storeName);
s.Driver.FindElement("#Create")).Click();
s.Driver.FindElement("#Title")).SendKeys("Kukkstarter");
s.Driver.FindElement(By.CssSelector("div.note-editable.card-block")).SendKeys("1BTC = 1BTC");
s.Driver.FindElement(By.Id("TargetCurrency")).SendKeys("JPY");
s.Driver.FindElement(By.Id("TargetAmount")).SendKeys("700");
s.Driver.FindElement(By.Id("SaveSettings")).Click();
s.Driver.FindElement(By.Id("ViewApp")).Click();
s.Driver.FindElement("#TargetCurrency")).SendKeys("JPY");
s.Driver.FindElement("#TargetAmount")).SendKeys("700");
s.Driver.FindElement("#SaveSettings")).Click();
s.Driver.FindElement("#ViewApp")).Click();
Assert.Equal("Currently Active!", s.Driver.FindElement(By.CssSelector(".h6.text-muted")).Text);
}
}
@ -562,12 +562,12 @@ namespace BTCPayServer.Tests
s.CreateNewStore();
s.AddDerivationScheme();
s.Driver.FindElement(By.Id("PaymentRequests")).Click();
s.Driver.FindElement(By.Id("CreatePaymentRequest")).Click();
s.Driver.FindElement(By.Id("Title")).SendKeys("Pay123");
s.Driver.FindElement(By.Id("Amount")).SendKeys("700");
s.Driver.FindElement(By.Id("Currency")).SendKeys("BTC");
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.Driver.FindElement("#PaymentRequests")).Click();
s.Driver.FindElement("#CreatePaymentRequest")).Click();
s.Driver.FindElement("#Title")).SendKeys("Pay123");
s.Driver.FindElement("#Amount")).SendKeys("700");
s.Driver.FindElement("#Currency")).SendKeys("BTC");
s.Driver.FindElement("#SaveButton")).Click();
s.Driver.FindElement(By.Name("ViewAppButton")).Click();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
Assert.Equal("Amount due", s.Driver.FindElement(By.CssSelector("[data-test='amount-due-title']")).Text);
@ -586,8 +586,8 @@ namespace BTCPayServer.Tests
s.GenerateWallet("BTC", "", false, true);
var walletId = new WalletId(storeId, "BTC");
s.GoToWallet(walletId, WalletsNavPages.Receive);
s.Driver.FindElement(By.Id("generateButton")).Click();
var addressStr = s.Driver.FindElement(By.Id("address")).GetProperty("value");
s.Driver.FindElement("#generateButton")).Click();
var addressStr = s.Driver.FindElement("#address")).GetProperty("value");
var address = BitcoinAddress.Create(addressStr, ((BTCPayNetwork)s.Server.NetworkProvider.GetNetwork("BTC")).NBitcoinNetwork);
await s.Server.ExplorerNode.GenerateAsync(1);
for (int i = 0; i < 6; i++)
@ -611,8 +611,8 @@ namespace BTCPayServer.Tests
});
await s.Server.ExplorerNode.GenerateAsync(1);
s.GoToWallet(walletId);
s.Driver.FindElement(By.Id("advancedSettings")).Click();
s.Driver.WaitForAndClick(By.Id("toggleInputSelection"));
s.Driver.FindElement("#advancedSettings")).Click();
s.Driver.WaitForAndClick("#toggleInputSelection"));
s.Driver.FindElement(By.Id(spentOutpoint.ToString()));
Assert.Equal("true", s.Driver.FindElement(By.Name("InputSelection")).GetAttribute("value").ToLowerInvariant());
var el = s.Driver.FindElement(By.Id(spentOutpoint.ToString()));
@ -622,10 +622,10 @@ namespace BTCPayServer.Tests
var bob = new Key().PubKey.Hash.GetAddress(Network.RegTest);
SetTransactionOutput(s, 0, bob, 0.3m);
s.Driver.FindElement(By.Id("SendMenu")).Click();
s.Driver.FindElement(By.Id("spendWithNBxplorer")).Click();
s.Driver.FindElement("#SendMenu")).Click();
s.Driver.FindElement("#spendWithNBxplorer")).Click();
s.Driver.FindElement(By.CssSelector("button[value=broadcast]")).Click();
var happyElement = s.FindAlertMessage();
var happyElement = await s.FindAlertMessage();
var happyText = happyElement.Text;
var txid = Regex.Match(happyText, @"\((.*)\)").Groups[1].Value;
@ -648,12 +648,12 @@ namespace BTCPayServer.Tests
Logs.Tester.LogInformation("Let's create two webhooks");
for (var i = 0; i < 2; i++)
{
s.Driver.FindElement(By.Id("CreateWebhook")).Click();
s.Driver.FindElement("#CreateWebhook")).Click();
s.Driver.FindElement(By.Name("PayloadUrl")).SendKeys($"http://127.0.0.1/callback{i}");
new SelectElement(s.Driver.FindElement(By.Name("Everything")))
.SelectByValue("false");
s.Driver.FindElement(By.Id("InvoiceCreated")).Click();
s.Driver.FindElement(By.Id("InvoiceProcessing")).Click();
s.Driver.FindElement("#InvoiceCreated")).Click();
s.Driver.FindElement("#InvoiceProcessing")).Click();
s.Driver.FindElement(By.Name("add")).Click();
}
@ -661,10 +661,10 @@ namespace BTCPayServer.Tests
var deletes = s.Driver.FindElements(By.LinkText("Delete"));
Assert.Equal(2, deletes.Count);
deletes[0].Click();
s.Driver.FindElement(By.Id("continue")).Click();
s.Driver.FindElement("#continue")).Click();
deletes = s.Driver.FindElements(By.LinkText("Delete"));
Assert.Single(deletes);
s.FindAlertMessage();
await s.FindAlertMessage();
Logs.Tester.LogInformation("Let's try to update one of them");
s.Driver.FindElement(By.LinkText("Modify")).Click();
@ -676,7 +676,7 @@ namespace BTCPayServer.Tests
s.Driver.FindElement(By.Name("Secret")).Clear();
s.Driver.FindElement(By.Name("Secret")).SendKeys("HelloWorld");
s.Driver.FindElement(By.Name("update")).Click();
s.FindAlertMessage();
await s.FindAlertMessage();
s.Driver.FindElement(By.LinkText("Modify")).Click();
foreach (var value in Enum.GetValues(typeof(WebhookEventType)))
{
@ -692,7 +692,7 @@ namespace BTCPayServer.Tests
Assert.DoesNotContain($"value=\"InvoiceReceivedPayment\" checked", s.Driver.PageSource);
s.Driver.FindElement(By.Name("update")).Click();
s.FindAlertMessage();
await s.FindAlertMessage();
Assert.Contains(server.ServerUri.AbsoluteUri, s.Driver.PageSource);
Logs.Tester.LogInformation("Let's see if we can generate an event");
@ -724,7 +724,7 @@ namespace BTCPayServer.Tests
s.Driver.FindElement(By.ClassName("fa-check"));
elements[0].Click();
s.FindAlertMessage();
await s.FindAlertMessage();
request = await server.GetNextRequest();
request.Response.StatusCode = 404;
server.Done();
@ -738,7 +738,7 @@ namespace BTCPayServer.Tests
var element = s.Driver.FindElement(By.ClassName("redeliver"));
element.Click();
s.FindAlertMessage();
await s.FindAlertMessage();
request = await server.GetNextRequest();
request.Response.StatusCode = 404;
server.Done();
@ -748,9 +748,9 @@ namespace BTCPayServer.Tests
// Open danger zone via JS, because if we click the link it triggers the toggle animation.
// This leads to Selenium trying to click the button while it is moving resulting in an error.
s.Driver.ExecuteJavaScript("document.getElementById('danger-zone').classList.add('show')");
s.Driver.FindElement(By.Id("delete-store")).Click();
s.Driver.FindElement(By.Id("continue")).Click();
s.FindAlertMessage();
s.Driver.FindElement("#delete-store")).Click();
s.Driver.FindElement("#continue")).Click();
await s.FindAlertMessage();
}
}
@ -768,25 +768,25 @@ namespace BTCPayServer.Tests
s.GenerateWallet("BTC", "", true);
//let's test quickly the receive wallet page
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement("#Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.Driver.FindElement(By.Id("WalletSend")).Click();
s.Driver.FindElement(By.Id("SendMenu")).Click();
s.Driver.FindElement("#WalletSend")).Click();
s.Driver.FindElement("#SendMenu")).Click();
//you cannot use the Sign with NBX option without saving private keys when generating the wallet.
Assert.DoesNotContain("nbx-seed", s.Driver.PageSource);
s.Driver.FindElement(By.Id("WalletReceive")).Click();
s.Driver.FindElement("#WalletReceive")).Click();
//generate a receiving address
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
Assert.True(s.Driver.FindElement(By.ClassName("qr-container")).Displayed);
var receiveAddr = s.Driver.FindElement(By.Id("address")).GetAttribute("value");
var receiveAddr = s.Driver.FindElement("#address")).GetAttribute("value");
//unreserve
s.Driver.FindElement(By.CssSelector("button[value=unreserve-current-address]")).Click();
//generate it again, should be the same one as before as nothing got used in the meantime
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
Assert.True(s.Driver.FindElement(By.ClassName("qr-container")).Displayed);
Assert.Equal(receiveAddr, s.Driver.FindElement(By.Id("address")).GetAttribute("value"));
Assert.Equal(receiveAddr, s.Driver.FindElement("#address")).GetAttribute("value"));
//send money to addr and ensure it changed
var sess = await s.Server.ExplorerClient.CreateWebsocketNotificationSessionAsync();
@ -797,18 +797,18 @@ namespace BTCPayServer.Tests
await Task.Delay(200);
s.Driver.Navigate().Refresh();
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
Assert.NotEqual(receiveAddr, s.Driver.FindElement(By.Id("address")).GetAttribute("value"));
receiveAddr = s.Driver.FindElement(By.Id("address")).GetAttribute("value");
Assert.NotEqual(receiveAddr, s.Driver.FindElement("#address")).GetAttribute("value"));
receiveAddr = s.Driver.FindElement("#address")).GetAttribute("value");
//change the wallet and ensure old address is not there and generating a new one does not result in the prev one
s.GoToStore(storeId);
s.GenerateWallet("BTC", "", true);
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement("#Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.Driver.FindElement(By.Id("WalletReceive")).Click();
s.Driver.FindElement("#WalletReceive")).Click();
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
Assert.NotEqual(receiveAddr, s.Driver.FindElement(By.Id("address")).GetAttribute("value"));
Assert.NotEqual(receiveAddr, s.Driver.FindElement("#address")).GetAttribute("value"));
var invoiceId = s.CreateInvoice(storeName);
var invoice = await s.Server.PayTester.InvoiceRepository.GetInvoice(invoiceId);
@ -831,22 +831,22 @@ namespace BTCPayServer.Tests
var tx = s.Server.ExplorerNode.SendToAddress(BitcoinAddress.Create(address, Network.RegTest), Money.Coins(3.0m));
await s.Server.ExplorerNode.GenerateAsync(1);
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement("#Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.ClickOnAllSideMenus();
// Make sure we can rescan, because we are admin!
s.Driver.FindElement(By.Id("WalletRescan")).Click();
s.Driver.FindElement("#WalletRescan")).Click();
Assert.Contains("The batch size make sure", s.Driver.PageSource);
// We setup the fingerprint and the account key path
s.Driver.FindElement(By.Id("WalletSettings")).Click();
// s.Driver.FindElement(By.Id("AccountKeys_0__MasterFingerprint")).SendKeys("8bafd160");
// s.Driver.FindElement(By.Id("AccountKeys_0__AccountKeyPath")).SendKeys("m/49'/0'/0'" + Keys.Enter);
s.Driver.FindElement("#WalletSettings")).Click();
// s.Driver.FindElement("#AccountKeys_0__MasterFingerprint")).SendKeys("8bafd160");
// s.Driver.FindElement("#AccountKeys_0__AccountKeyPath")).SendKeys("m/49'/0'/0'" + Keys.Enter);
// Check the tx sent earlier arrived
s.Driver.FindElement(By.Id("WalletTransactions")).Click();
s.Driver.FindElement("#WalletTransactions")).Click();
var walletTransactionLink = s.Driver.Url;
Assert.Contains(tx.ToString(), s.Driver.PageSource);
@ -855,14 +855,14 @@ namespace BTCPayServer.Tests
void SignWith(Mnemonic signingSource)
{
// Send to bob
s.Driver.FindElement(By.Id("WalletSend")).Click();
s.Driver.FindElement("#WalletSend")).Click();
var bob = new Key().PubKey.Hash.GetAddress(Network.RegTest);
SetTransactionOutput(s, 0, bob, 1);
s.Driver.FindElement(By.Id("SendMenu")).Click();
s.Driver.FindElement("#SendMenu")).Click();
s.Driver.FindElement(By.CssSelector("button[value=seed]")).Click();
// Input the seed
s.Driver.FindElement(By.Id("SeedOrKey")).SendKeys(signingSource + Keys.Enter);
s.Driver.FindElement("#SeedOrKey")).SendKeys(signingSource + Keys.Enter);
// Broadcast
Assert.Contains(bob.ToString(), s.Driver.PageSource);
@ -873,13 +873,13 @@ namespace BTCPayServer.Tests
SignWith(mnemonic);
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement("#Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.Driver.FindElement(By.Id("WalletSend")).Click();
s.Driver.FindElement("#WalletSend")).Click();
var jack = new Key().PubKey.Hash.GetAddress(Network.RegTest);
SetTransactionOutput(s, 0, jack, 0.01m);
s.Driver.FindElement(By.Id("SendMenu")).Click();
s.Driver.FindElement("#SendMenu")).Click();
s.Driver.FindElement(By.CssSelector("button[value=nbx-seed]")).Click();
Assert.Contains(jack.ToString(), s.Driver.PageSource);
@ -896,10 +896,10 @@ namespace BTCPayServer.Tests
//let's make bip21 more interesting
bip21 += "&label=Solid Snake&message=Snake? Snake? SNAAAAKE!";
var parsedBip21 = new BitcoinUrlBuilder(bip21, Network.RegTest);
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement("#Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.Driver.FindElement(By.Id("WalletSend")).Click();
s.Driver.FindElement(By.Id("bip21parse")).Click();
s.Driver.FindElement("#WalletSend")).Click();
s.Driver.FindElement("#bip21parse")).Click();
s.Driver.SwitchTo().Alert().SendKeys(bip21);
s.Driver.SwitchTo().Alert().Accept();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Info);
@ -909,17 +909,17 @@ namespace BTCPayServer.Tests
s.GoToWallet(new WalletId(storeId, "BTC"), WalletsNavPages.Settings);
var walletUrl = s.Driver.Url;
s.Driver.FindElement(By.Id("SettingsMenu")).Click();
s.Driver.FindElement("#SettingsMenu")).Click();
s.Driver.FindElement(By.CssSelector("button[value=view-seed]")).Click();
// Seed backup page
var recoveryPhrase = s.Driver.FindElements(By.Id("RecoveryPhrase")).First().GetAttribute("data-mnemonic");
var recoveryPhrase = s.Driver.FindElements("#RecoveryPhrase")).First().GetAttribute("data-mnemonic");
Assert.Equal(mnemonic.ToString(), recoveryPhrase);
Assert.Contains("The recovery phrase will also be stored on the server as a hot wallet.", s.Driver.PageSource);
// No confirmation, just a link to return to the wallet
Assert.Empty(s.Driver.FindElements(By.Id("confirm")));
s.Driver.FindElement(By.Id("proceed")).Click();
Assert.Empty(s.Driver.FindElements("#confirm")));
s.Driver.FindElement("#proceed")).Click();
Assert.Equal(walletUrl, s.Driver.Url);
}
}
@ -938,41 +938,41 @@ namespace BTCPayServer.Tests
await s.Server.ExplorerNode.GenerateAsync(1);
await s.FundStoreWallet(denomination: 50.0m);
s.GoToWallet(navPages: WalletsNavPages.PullPayments);
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
s.Driver.FindElement(By.Id("Amount")).Clear();
s.Driver.FindElement(By.Id("Amount")).SendKeys("99.0");;
s.Driver.FindElement(By.Id("Create")).Click();
s.Driver.FindElement("#NewPullPayment")).Click();
s.Driver.FindElement("#Name")).SendKeys("PP1");
s.Driver.FindElement("#Amount")).Clear();
s.Driver.FindElement("#Amount")).SendKeys("99.0");;
s.Driver.FindElement("#Create")).Click();
s.Driver.FindElement(By.LinkText("View")).Click();
s.GoToWallet(navPages: WalletsNavPages.PullPayments);
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
s.Driver.FindElement(By.Id("Name")).SendKeys("PP2");
s.Driver.FindElement(By.Id("Amount")).Clear();
s.Driver.FindElement(By.Id("Amount")).SendKeys("100.0");
s.Driver.FindElement(By.Id("Create")).Click();
s.Driver.FindElement("#NewPullPayment")).Click();
s.Driver.FindElement("#Name")).SendKeys("PP2");
s.Driver.FindElement("#Amount")).Clear();
s.Driver.FindElement("#Amount")).SendKeys("100.0");
s.Driver.FindElement("#Create")).Click();
// This should select the first View, ie, the last one PP2
s.Driver.FindElement(By.LinkText("View")).Click();
var address = await s.Server.ExplorerNode.GetNewAddressAsync();
s.Driver.FindElement(By.Id("Destination")).SendKeys(address.ToString());
s.Driver.FindElement(By.Id("ClaimedAmount")).Clear();
s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys("15" + Keys.Enter);
s.FindAlertMessage();
s.Driver.FindElement("#Destination")).SendKeys(address.ToString());
s.Driver.FindElement("#ClaimedAmount")).Clear();
s.Driver.FindElement("#ClaimedAmount")).SendKeys("15" + Keys.Enter);
await s.FindAlertMessage();
// We should not be able to use an address already used
s.Driver.FindElement(By.Id("Destination")).SendKeys(address.ToString());
s.Driver.FindElement(By.Id("ClaimedAmount")).Clear();
s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys("20" + Keys.Enter);
s.Driver.FindElement("#Destination")).SendKeys(address.ToString());
s.Driver.FindElement("#ClaimedAmount")).Clear();
s.Driver.FindElement("#ClaimedAmount")).SendKeys("20" + Keys.Enter);
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Error);
address = await s.Server.ExplorerNode.GetNewAddressAsync();
s.Driver.FindElement(By.Id("Destination")).Clear();
s.Driver.FindElement(By.Id("Destination")).SendKeys(address.ToString());
s.Driver.FindElement(By.Id("ClaimedAmount")).Clear();
s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys("20" + Keys.Enter);
s.FindAlertMessage();
s.Driver.FindElement("#Destination")).Clear();
s.Driver.FindElement("#Destination")).SendKeys(address.ToString());
s.Driver.FindElement("#ClaimedAmount")).Clear();
s.Driver.FindElement("#ClaimedAmount")).SendKeys("20" + Keys.Enter);
await s.FindAlertMessage();
Assert.Contains("Awaiting Approval", s.Driver.PageSource);
var viewPullPaymentUrl = s.Driver.Url;
@ -993,11 +993,11 @@ namespace BTCPayServer.Tests
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-actions")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-approve-pay")).Click();
s.Driver.FindElement(By.Id("SendMenu")).Click();
s.Driver.FindElement("#SendMenu")).Click();
s.Driver.FindElement(By.CssSelector("button[value=nbx-seed]")).Click();
s.Driver.FindElement(By.CssSelector("button[value=broadcast]")).Click();
s.FindAlertMessage();
await s.FindAlertMessage();
TestUtils.Eventually(() =>
{
@ -1007,7 +1007,7 @@ namespace BTCPayServer.Tests
Assert.Equal("payout", s.Driver.FindElement(By.ClassName("transactionLabel")).Text);
s.GoToWallet(navPages: WalletsNavPages.Payouts);
ReadOnlyCollection<IWebElement> txs;
ReadOnlyCollection<IElementHandle> txs;
TestUtils.Eventually(() =>
{
s.Driver.Navigate().Refresh();
@ -1055,18 +1055,18 @@ namespace BTCPayServer.Tests
{
s.Driver.FindElement(By.ClassName("dropdown-toggle")).Click();
s.Driver.FindElement(By.ClassName("dropdown-item")).Click();
s.Driver.FindElement(By.Id("Settings_Login")).SendKeys("test@gmail.com");
s.Driver.FindElement("#Settings_Login")).SendKeys("test@gmail.com");
s.Driver.FindElement(By.CssSelector("button[value=\"Save\"]")).Submit();
s.FindAlertMessage();
s.Driver.FindElement(By.Id("Settings_Password")).SendKeys("mypassword");
await s.FindAlertMessage();
s.Driver.FindElement("#Settings_Password")).SendKeys("mypassword");
s.Driver.FindElement(By.CssSelector("button[value=\"Save\"]")).Submit();
Assert.Contains("Configured", s.Driver.PageSource);
s.Driver.FindElement(By.Id("Settings_Login")).SendKeys("test_fix@gmail.com");
s.Driver.FindElement("#Settings_Login")).SendKeys("test_fix@gmail.com");
s.Driver.FindElement(By.CssSelector("button[value=\"Save\"]")).Submit();
Assert.Contains("Configured", s.Driver.PageSource);
Assert.Contains("test_fix", s.Driver.PageSource);
s.Driver.FindElement(By.CssSelector("button[value=\"ResetPassword\"]")).Submit();
s.FindAlertMessage();
await s.FindAlertMessage();
Assert.DoesNotContain("Configured", s.Driver.PageSource);
Assert.Contains("test_fix", s.Driver.PageSource);
}