btcpayserver/BTCPayServer.Tests/SeleniumTests.cs

1654 lines
84 KiB
C#
Raw Normal View History

2020-06-29 04:44:35 +02:00
using System;
using System.Collections.ObjectModel;
2020-06-28 10:55:27 +02:00
using System.Globalization;
2019-05-12 10:13:26 +02:00
using System.Linq;
2021-10-26 13:55:13 +02:00
using System.Net.Http;
using System.Net.Security;
using System.Security.Authentication;
2020-11-06 12:42:26 +01:00
using System.Text;
2019-10-12 13:35:30 +02:00
using System.Text.RegularExpressions;
using System.Threading;
2020-06-28 10:55:27 +02:00
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Models;
2020-11-06 12:42:26 +01:00
using BTCPayServer.Client.Models;
2020-03-25 07:59:30 +01:00
using BTCPayServer.Data;
using BTCPayServer.Lightning;
using BTCPayServer.Lightning.Charge;
2021-10-26 13:55:13 +02:00
using BTCPayServer.Lightning.CLightning;
using BTCPayServer.Lightning.LND;
using BTCPayServer.Payments;
using BTCPayServer.Services;
2021-10-26 13:55:13 +02:00
using BTCPayServer.Services.Invoices;
2020-03-25 07:59:30 +01:00
using BTCPayServer.Services.Wallets;
2020-06-28 10:55:27 +02:00
using BTCPayServer.Tests.Logging;
using BTCPayServer.Views.Manage;
2020-09-16 08:54:09 +02:00
using BTCPayServer.Views.Server;
using BTCPayServer.Views.Stores;
using BTCPayServer.Views.Wallets;
2021-10-26 13:55:13 +02:00
using LNURL;
using Microsoft.AspNetCore.Identity;
2020-06-24 03:34:09 +02:00
using Microsoft.EntityFrameworkCore;
2020-06-28 10:55:27 +02:00
using NBitcoin;
2020-11-06 12:42:26 +01:00
using NBitcoin.DataEncoders;
2020-06-28 10:55:27 +02:00
using NBitcoin.Payment;
2020-11-06 12:42:26 +01:00
using Newtonsoft.Json.Linq;
2020-06-28 10:55:27 +02:00
using OpenQA.Selenium;
2020-11-06 12:42:26 +01:00
using OpenQA.Selenium.Support.Extensions;
using OpenQA.Selenium.Support.UI;
using Renci.SshNet.Security.Cryptography;
2020-06-28 10:55:27 +02:00
using Xunit;
using Xunit.Abstractions;
2021-11-26 07:07:54 +01:00
using Xunit.Sdk;
using CreateInvoiceRequest = BTCPayServer.Lightning.Charge.CreateInvoiceRequest;
2019-05-12 10:13:26 +02:00
namespace BTCPayServer.Tests
{
[Trait("Selenium", "Selenium")]
2021-11-23 05:57:45 +01:00
[Collection(nameof(NonParallelizableCollectionDefinition))]
2021-11-22 09:16:08 +01:00
public class ChromeTests : UnitTestBase
2019-05-12 10:13:26 +02:00
{
private const int TestTimeout = TestUtils.TestTimeout;
2021-11-22 09:16:08 +01:00
public ChromeTests(ITestOutputHelper helper) : base(helper)
2019-05-12 10:13:26 +02:00
{
}
[Fact(Timeout = TestTimeout)]
2019-10-07 09:04:25 +02:00
public async Task CanNavigateServerSettings()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
s.RegisterNewUser(true);
s.Driver.FindElement(By.Id("ServerSettings")).Click();
s.Driver.AssertNoError();
s.ClickOnAllSideMenus();
s.Driver.FindElement(By.LinkText("Services")).Click();
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Let's check if we can access the logs");
s.Driver.FindElement(By.LinkText("Logs")).Click();
s.Driver.FindElement(By.PartialLinkText(".log")).Click();
Assert.Contains("Starting listening NBXplorer", s.Driver.PageSource);
s.Driver.Quit();
}
}
[Fact(Timeout = TestTimeout)]
[Trait("Lightning", "Lightning")]
public async Task CanUseLndSeedBackup()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
s.Server.ActivateLightning();
await s.StartAsync();
s.RegisterNewUser(true);
s.Driver.FindElement(By.Id("ServerSettings")).Click();
s.Driver.AssertNoError();
s.Driver.FindElement(By.LinkText("Services")).Click();
2021-11-22 09:16:08 +01:00
TestLogs.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();
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
var seedEl = s.Driver.FindElement(By.Id("Seed"));
Assert.True(seedEl.Displayed);
Assert.Contains("about over million", seedEl.Text, StringComparison.OrdinalIgnoreCase);
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
var passEl = s.Driver.FindElement(By.Id("WalletPassword"));
Assert.True(passEl.Displayed);
Assert.Contains(passEl.Text, "hellorockstar", StringComparison.OrdinalIgnoreCase);
s.Driver.FindElement(By.Id("delete")).Click();
s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DELETE");
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
s.FindAlertMessage();
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
seedEl = s.Driver.FindElement(By.Id("Seed"));
Assert.Contains("Seed removed", seedEl.Text, StringComparison.OrdinalIgnoreCase);
}
}
[Fact(Timeout = TestTimeout)]
[Trait("Selenium", "Selenium")]
public async Task CanChangeUserMail()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
await s.StartAsync();
var tester = s.Server;
var u1 = tester.NewAccount();
await u1.GrantAccessAsync();
await u1.MakeAdmin(false);
var u2 = tester.NewAccount();
await u2.GrantAccessAsync();
await u2.MakeAdmin(false);
s.GoToLogin();
s.Login(u1.RegisterDetails.Email, u1.RegisterDetails.Password);
s.GoToProfile();
s.Driver.FindElement(By.Id("Email")).Clear();
s.Driver.FindElement(By.Id("Email")).SendKeys(u2.RegisterDetails.Email);
s.Driver.FindElement(By.Id("save")).Click();
Assert.Contains("The email address is already in use with an other account.",
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Error).Text);
s.GoToProfile();
s.Driver.FindElement(By.Id("Email")).Clear();
var changedEmail = Guid.NewGuid() + "@lol.com";
s.Driver.FindElement(By.Id("Email")).SendKeys(changedEmail);
s.Driver.FindElement(By.Id("save")).Click();
s.FindAlertMessage();
var manager = tester.PayTester.GetService<UserManager<ApplicationUser>>();
Assert.NotNull(await manager.FindByNameAsync(changedEmail));
Assert.NotNull(await manager.FindByEmailAsync(changedEmail));
}
}
[Fact(Timeout = TestTimeout)]
2019-10-07 09:04:25 +02:00
public async Task NewUserLogin()
2019-05-12 10:13:26 +02:00
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
//Register & Log Out
var email = s.RegisterNewUser();
2020-09-16 08:54:09 +02:00
s.Logout();
s.Driver.AssertNoError();
Assert.Contains("/login", s.Driver.Url);
s.Driver.Navigate().GoToUrl(s.Link("/invoices"));
Assert.Contains("ReturnUrl=%2Finvoices", s.Driver.Url);
// 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();
// We should be redirected to invoice
Assert.EndsWith("/invoices", s.Driver.Url);
// Should not be able to reach server settings
s.Driver.Navigate().GoToUrl(s.Link("/server/users"));
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.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();
Assert.True(s.Driver.PageSource.Contains("Stores"), "Can't Access Stores");
s.Driver.FindElement(By.Id("MySettings")).Click();
s.ClickOnAllSideMenus();
2020-09-16 08:54:09 +02:00
//let's test invite link
s.Logout();
s.GoToRegister();
2021-01-25 14:10:19 +01:00
s.RegisterNewUser(true);
2020-09-16 08:54:09 +02:00
s.GoToServer(ServerNavPages.Users);
s.Driver.FindElement(By.Id("CreateUser")).Click();
2020-11-06 12:42:26 +01:00
2020-09-16 08:54:09 +02:00
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();
var url = s.FindAlertMessage().FindElement(By.TagName("a")).Text;
2021-01-25 14:10:19 +01:00
2020-09-16 08:54:09 +02:00
s.Logout();
s.Driver.Navigate().GoToUrl(url);
2020-11-06 12:42:26 +01:00
Assert.Equal("hidden", s.Driver.FindElement(By.Id("Email")).GetAttribute("type"));
Assert.Equal(usr, s.Driver.FindElement(By.Id("Email")).GetAttribute("value"));
2020-09-16 08:54:09 +02:00
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();
2020-09-16 08:54:09 +02:00
s.Driver.FindElement(By.Id("Email")).SendKeys(usr);
s.Driver.FindElement(By.Id("Password")).SendKeys("123456");
s.Driver.FindElement(By.Id("LoginButton")).Click();
// We should be logged in now
s.Driver.FindElement(By.Id("mainNav"));
//let's test delete user quickly while we're at it
s.GoToProfile();
s.Driver.FindElement(By.Id("delete-user")).Click();
s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DELETE");
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
Assert.Contains("/login", s.Driver.Url);
}
2019-05-12 10:13:26 +02:00
}
2019-05-14 16:33:46 +02:00
[Fact(Timeout = TestTimeout)]
public async Task CanUseSSHService()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
var settings = s.Server.PayTester.GetService<SettingsRepository>();
var policies = await settings.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
policies.DisableSSHService = false;
await settings.UpdateSetting(policies);
2021-01-25 14:10:19 +01:00
s.RegisterNewUser(isAdmin: true);
s.Driver.Navigate().GoToUrl(s.Link("/server/services"));
Assert.Contains("server/services/ssh", s.Driver.PageSource);
using (var client = await s.Server.PayTester.GetService<Configuration.BTCPayServerOptions>().SSHSettings
.ConnectAsync())
{
var result = await client.RunBash("echo hello");
Assert.Equal(string.Empty, result.Error);
Assert.Equal("hello\n", result.Output);
Assert.Equal(0, result.ExitStatus);
}
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.AssertNoError();
var text = s.Driver.FindElement(By.Id("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));
2019-09-20 12:41:59 +02:00
s.Driver.FindElement(By.Id("SSHKeyFileContent")).Clear();
s.Driver.FindElement(By.Id("submit")).Click();
2019-09-20 12:41:59 +02:00
text = s.Driver.FindElement(By.Id("SSHKeyFileContent")).Text;
Assert.DoesNotContain("test2", text);
// Let's try to disable it now
s.Driver.FindElement(By.Id("disable")).Click();
s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DISABLE");
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
s.Driver.Navigate().GoToUrl(s.Link("/server/services/ssh"));
Assert.True(s.Driver.PageSource.Contains("404 - Page not found", StringComparison.OrdinalIgnoreCase));
policies = await settings.GetSettingAsync<PoliciesSettings>();
Assert.True(policies.DisableSSHService);
policies.DisableSSHService = false;
await settings.UpdateSetting(policies);
}
}
2020-10-05 09:39:49 +02:00
[Fact(Timeout = TestTimeout)]
public async Task CanSetupEmailServer()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
2020-10-05 09:39:49 +02:00
{
await s.StartAsync();
2021-01-25 14:10:19 +01:00
s.RegisterNewUser(isAdmin: true);
2020-10-05 09:39:49 +02:00
s.Driver.Navigate().GoToUrl(s.Link("/server/emails"));
if (s.Driver.PageSource.Contains("Configured"))
{
s.Driver.FindElement(By.CssSelector("button[value=\"ResetPassword\"]")).Submit();
s.FindAlertMessage();
2020-10-05 09:39:49 +02:00
}
2020-10-05 09:39:49 +02:00
CanSetupEmailCore(s);
s.CreateNewStore();
s.GoToUrl($"stores/{s.StoreId}/emails");
CanSetupEmailCore(s);
}
}
[Fact(Timeout = TestTimeout)]
2019-10-07 09:04:25 +02:00
public async Task CanUseDynamicDns()
2019-07-25 12:07:56 +02:00
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
2019-07-25 12:07:56 +02:00
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
2021-01-25 14:10:19 +01:00
s.RegisterNewUser(isAdmin: true);
s.Driver.Navigate().GoToUrl(s.Link("/server/services"));
Assert.Contains("Dynamic DNS", s.Driver.PageSource);
s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns"));
s.Driver.AssertNoError();
if (s.Driver.PageSource.Contains("pouet.hello.com"))
{
// Cleanup old test run
s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns/pouet.hello.com/delete"));
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
}
s.Driver.FindElement(By.Id("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.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.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.AssertNoError();
Assert.Contains("This hostname already exists", s.Driver.PageSource);
// Delete it
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("ConfirmContinue")).Click();
s.Driver.AssertNoError();
Assert.DoesNotContain("/server/services/dynamic-dns/pouet.hello.com/delete", s.Driver.PageSource);
2019-07-25 12:07:56 +02:00
}
}
2019-05-12 10:13:26 +02:00
[Fact(Timeout = TestTimeout)]
[Trait("Lightning", "Lightning")]
2019-10-07 09:04:25 +02:00
public async Task CanCreateStores()
2019-05-12 10:13:26 +02:00
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
s.Server.ActivateLightning();
2019-10-07 09:04:25 +02:00
await s.StartAsync();
var alice = s.RegisterNewUser(true);
var (storeName, storeId) = s.CreateNewStore();
var onchainHint = "Set up your wallet to receive payments at your store.";
2020-11-06 11:14:00 +01:00
var offchainHint = "A connection to a Lightning node is required to receive Lightning payments.";
2020-10-23 17:15:07 +02:00
2020-10-17 22:03:28 +02:00
// verify that hints are displayed on the store page
2020-10-23 17:15:07 +02:00
Assert.True(s.Driver.PageSource.Contains(onchainHint), "Wallet hint not present");
Assert.True(s.Driver.PageSource.Contains(offchainHint), "Lightning hint not present");
2020-10-17 22:03:28 +02:00
s.GoToStores();
Assert.True(s.Driver.PageSource.Contains($"warninghint_{storeId}"), "Warning hint on list not present");
s.GoToStore(storeId);
Assert.Contains(storeName, s.Driver.PageSource);
Assert.True(s.Driver.PageSource.Contains(onchainHint), "Wallet hint should be present at this point");
Assert.True(s.Driver.PageSource.Contains(offchainHint),
"Lightning hint should be present at this point");
// setup onchain wallet
s.GoToStore(storeId);
s.AddDerivationScheme();
s.Driver.AssertNoError();
Assert.False(s.Driver.PageSource.Contains(onchainHint),
"Wallet hint not dismissed on derivation scheme add");
// setup offchain wallet
s.GoToStore(storeId);
s.AddLightningNode();
s.Driver.AssertNoError();
var successAlert = s.FindAlertMessage();
2021-04-20 09:09:32 +02:00
Assert.Contains("BTC Lightning node updated.", successAlert.Text);
Assert.False(s.Driver.PageSource.Contains(offchainHint),
"Lightning hint should be dismissed at this point");
2020-10-17 22:03:28 +02:00
var storeUrl = s.Driver.Url;
s.ClickOnAllSideMenus();
s.GoToInvoices();
var invoiceId = s.CreateInvoice(storeName);
s.FindAlertMessage();
s.Driver.FindElement(By.ClassName("invoice-details-link")).Click();
var invoiceUrl = s.Driver.Url;
2020-06-24 03:34:09 +02:00
2020-05-09 15:03:46 +02:00
//let's test archiving an invoice
2020-06-24 03:34:09 +02:00
Assert.DoesNotContain("Archived", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
2020-05-09 15:03:46 +02:00
s.Driver.FindElement(By.Id("btn-archive-toggle")).Click();
Assert.Contains("Unarchive", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
2020-05-09 15:03:46 +02:00
//check that it no longer appears in list
s.GoToInvoices();
2020-05-09 15:03:46 +02:00
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("Unarchive", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
2020-05-09 15:03:46 +02:00
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.Navigate().GoToUrl(storeUrl);
Assert.Contains("ReturnUrl", s.Driver.Url);
s.Driver.Navigate().GoToUrl(invoiceUrl);
Assert.Contains("ReturnUrl", s.Driver.Url);
s.GoToRegister();
// When logged we should not be able to access store and invoice details
var bob = s.RegisterNewUser();
s.Driver.Navigate().GoToUrl(storeUrl);
Assert.Contains("ReturnUrl", s.Driver.Url);
s.Driver.Navigate().GoToUrl(invoiceUrl);
s.AssertNotFound();
s.GoToHome();
s.Logout();
// 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);
Assert.Contains("User added successfully", s.Driver.PageSource);
s.Logout();
// Bob should not have access to store, but should have access to invoice
s.LogIn(bob);
s.Driver.Navigate().GoToUrl(storeUrl);
Assert.Contains("ReturnUrl", s.Driver.Url);
s.Driver.Navigate().GoToUrl(invoiceUrl);
s.Driver.AssertNoError();
2019-10-26 16:35:55 +02:00
// Alice should be able to delete the store
s.Logout();
s.LogIn(alice);
2019-10-26 16:35:55 +02:00
s.Driver.FindElement(By.Id("Stores")).Click();
s.Driver.FindElement(By.LinkText("Delete")).Click();
s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DELETE");
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
2019-10-26 16:35:55 +02:00
s.Driver.FindElement(By.Id("Stores")).Click();
s.Driver.Navigate().GoToUrl(storeUrl);
Assert.Contains("ReturnUrl", s.Driver.Url);
}
}
2019-10-12 13:35:30 +02:00
[Fact(Timeout = TestTimeout)]
public async Task CanUsePairing()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
2019-10-12 13:35:30 +02:00
{
await s.StartAsync();
s.Driver.Navigate().GoToUrl(s.Link("/api-access-request"));
Assert.Contains("ReturnUrl", s.Driver.Url);
s.GoToRegister();
2021-01-25 14:10:19 +01:00
s.RegisterNewUser();
s.CreateNewStore();
2019-10-12 13:35:30 +02:00
s.AddDerivationScheme();
s.Driver.FindElement(By.Id("Nav-Tokens")).Click();
2019-10-12 13:35:30 +02:00
s.Driver.FindElement(By.Id("CreateNewToken")).Click();
s.Driver.FindElement(By.Id("RequestPairing")).Click();
2021-01-25 14:10:19 +01:00
var pairingCode = AssertUrlHasPairingCode(s);
2019-10-12 13:35:30 +02:00
s.Driver.FindElement(By.Id("ApprovePairing")).Click();
s.FindAlertMessage();
2019-10-12 13:35:30 +02:00
Assert.Contains(pairingCode, s.Driver.PageSource);
var client = new NBitpayClient.Bitpay(new Key(), s.ServerUri);
2019-10-12 13:35:30 +02:00
await client.AuthorizeClient(new NBitpayClient.PairingCode(pairingCode));
await client.CreateInvoiceAsync(
new NBitpayClient.Invoice() { Price = 1.000000012m, Currency = "USD", FullNotifications = true },
NBitpayClient.Facade.Merchant);
2019-10-12 13:35:30 +02:00
client = new NBitpayClient.Bitpay(new Key(), s.ServerUri);
2019-10-12 13:35:30 +02:00
var code = await client.RequestClientAuthorizationAsync("hehe", NBitpayClient.Facade.Merchant);
s.Driver.Navigate().GoToUrl(code.CreateLink(s.ServerUri));
2019-10-12 13:35:30 +02:00
s.Driver.FindElement(By.Id("ApprovePairing")).Click();
await client.CreateInvoiceAsync(
new NBitpayClient.Invoice() { Price = 1.000000012m, Currency = "USD", FullNotifications = true },
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();
AssertUrlHasPairingCode(s);
2019-10-12 13:35:30 +02:00
}
}
[Fact(Timeout = TestTimeout)]
2019-10-07 09:04:25 +02:00
public async Task CanCreateAppPoS()
2019-05-12 10:13:26 +02:00
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
s.RegisterNewUser();
var (storeName, _) = s.CreateNewStore();
s.Driver.FindElement(By.Id("Apps")).Click();
s.Driver.FindElement(By.Id("CreateNewApp")).Click();
s.Driver.FindElement(By.Name("AppName")).SendKeys("PoS" + Guid.NewGuid());
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Point of Sale");
s.Driver.FindElement(By.Id("SelectedStore")).SendKeys(storeName);
s.Driver.FindElement(By.Id("Create")).Click();
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();
var template = s.Driver.FindElement(By.Id("Template")).GetAttribute("value");
Assert.Contains("buyButtonText: Take my money", template);
s.Driver.FindElement(By.Id("DefaultView")).SendKeys("Item list and cart");
s.Driver.FindElement(By.Id("SaveSettings")).Click();
s.Driver.FindElement(By.Id("ViewApp")).Click();
2020-06-24 03:34:09 +02:00
var posBaseUrl = s.Driver.Url.Replace("/Cart", "");
Assert.True(s.Driver.PageSource.Contains("Tea shop"), "Unable to create PoS");
Assert.True(s.Driver.PageSource.Contains("Cart"), "PoS not showing correct default view");
Assert.True(s.Driver.PageSource.Contains("Take my money"), "PoS not showing correct default view");
2020-06-24 03:34:09 +02:00
s.Driver.Url = posBaseUrl + "/static";
Assert.False(s.Driver.PageSource.Contains("Cart"), "Static PoS not showing correct view");
2020-06-24 03:34:09 +02:00
s.Driver.Url = posBaseUrl + "/cart";
Assert.True(s.Driver.PageSource.Contains("Cart"), "Cart PoS not showing correct view");
}
2019-05-12 10:13:26 +02:00
}
[Fact(Timeout = TestTimeout)]
2021-01-25 14:10:19 +01:00
public async Task CanCreateCrowdfundingApp()
2019-05-12 10:13:26 +02:00
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
s.RegisterNewUser();
var (storeName, _) = s.CreateNewStore();
s.AddDerivationScheme();
s.Driver.FindElement(By.Id("Apps")).Click();
s.Driver.FindElement(By.Id("CreateNewApp")).Click();
s.Driver.FindElement(By.Name("AppName")).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(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();
Assert.Equal("currently active!",
s.Driver.FindElement(By.CssSelector("[data-test='time-state']")).Text);
2020-06-24 03:34:09 +02:00
}
2019-05-12 10:13:26 +02:00
}
[Fact(Timeout = TestTimeout)]
2019-10-07 09:04:25 +02:00
public async Task CanCreatePayRequest()
2019-05-12 10:13:26 +02:00
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
s.RegisterNewUser();
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(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);
Assert.Equal("Pay Invoice",
s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
// expire
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
s.Driver.ExecuteJavaScript("document.getElementById('ExpiryDate').value = '2021-01-21T21:00:00.000Z'");
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
s.Driver.Navigate().Refresh();
Assert.Equal("Expired", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text);
// unexpire
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
s.Driver.FindElement(By.Id("ClearExpiryDate")).Click();
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
s.Driver.Navigate().Refresh();
s.Driver.AssertElementNotFound(By.CssSelector("[data-test='status']"));
Assert.Equal("Pay Invoice",
s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
}
2019-05-12 10:13:26 +02:00
}
[Fact(Timeout = TestTimeout)]
public async Task CanUseCoinSelection()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
await s.StartAsync();
2021-01-25 14:10:19 +01:00
s.RegisterNewUser(true);
var (_, storeId) = s.CreateNewStore();
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");
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++)
{
await s.Server.ExplorerNode.SendToAddressAsync(address, Money.Coins(1.0m));
}
var targetTx = await s.Server.ExplorerNode.SendToAddressAsync(address, Money.Coins(1.2m));
var tx = await s.Server.ExplorerNode.GetRawTransactionAsync(targetTx);
var spentOutpoint = new OutPoint(targetTx,
tx.Outputs.FindIndex(txout => txout.Value == Money.Coins(1.2m)));
2020-03-25 07:59:30 +01:00
await TestUtils.EventuallyAsync(async () =>
{
var store = await s.Server.PayTester.StoreRepository.FindStore(storeId);
var x = store.GetSupportedPaymentMethods(s.Server.NetworkProvider)
.OfType<DerivationSchemeSettings>()
.Single(settings => settings.PaymentId.CryptoCode == walletId.CryptoCode);
2021-03-11 14:20:25 +01:00
var wallet = s.Server.PayTester.GetService<BTCPayWalletProvider>().GetWallet(walletId.CryptoCode);
wallet.InvalidateCache(x.AccountDerivation);
2020-03-25 07:59:30 +01:00
Assert.Contains(
2021-03-11 14:20:25 +01:00
await wallet.GetUnspentCoins(x.AccountDerivation),
2020-03-25 07:59:30 +01:00
coin => coin.OutPoint == spentOutpoint);
});
await s.Server.ExplorerNode.GenerateAsync(1);
2021-01-25 14:10:19 +01:00
s.GoToWallet(walletId);
s.Driver.WaitForAndClick(By.Id("toggleInputSelection"));
s.Driver.WaitForElement(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()));
s.Driver.FindElement(By.Id(spentOutpoint.ToString())).Click();
2020-03-24 08:36:27 +01:00
var inputSelectionSelect = s.Driver.FindElement(By.Name("SelectedInputs"));
2020-03-25 07:59:30 +01:00
Assert.Single(inputSelectionSelect.FindElements(By.CssSelector("[selected]")));
2020-03-24 08:36:27 +01:00
var bob = new Key().PubKey.Hash.GetAddress(Network.RegTest);
SetTransactionOutput(s, 0, bob, 0.3m);
s.Driver.FindElement(By.Id("SignTransaction")).Click();
s.Driver.FindElement(By.CssSelector("button[value=broadcast]")).Click();
var happyElement = s.FindAlertMessage();
var happyText = happyElement.Text;
var txid = Regex.Match(happyText, @"\((.*)\)").Groups[1].Value;
tx = await s.Server.ExplorerNode.GetRawTransactionAsync(new uint256(txid));
Assert.Single(tx.Inputs);
Assert.Equal(spentOutpoint, tx.Inputs[0].PrevOut);
}
}
2020-11-06 12:42:26 +01:00
[Fact(Timeout = TestTimeout)]
public async Task CanUseWebhooks()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
2020-11-06 12:42:26 +01:00
{
await s.StartAsync();
s.RegisterNewUser(true);
var (storeName, storeId) = s.CreateNewStore();
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
s.GoToStore(storeId, StoreNavPages.Webhooks);
2020-11-06 12:42:26 +01:00
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Let's create two webhooks");
for (var i = 0; i < 2; i++)
2020-11-06 12:42:26 +01:00
{
s.Driver.FindElement(By.Id("CreateWebhook")).Click();
s.Driver.FindElement(By.Name("PayloadUrl")).SendKeys($"http://127.0.0.1/callback{i}");
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
new SelectElement(s.Driver.FindElement(By.Id("Everything"))).SelectByValue("false");
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.Id("InvoiceCreated")).Click();
s.Driver.FindElement(By.Id("InvoiceProcessing")).Click();
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.Name("add")).Click();
}
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Let's delete one of them");
2020-11-06 12:42:26 +01:00
var deletes = s.Driver.FindElements(By.LinkText("Delete"));
Assert.Equal(2, deletes.Count);
deletes[0].Click();
s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DELETE");
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
2020-11-06 12:42:26 +01:00
deletes = s.Driver.FindElements(By.LinkText("Delete"));
Assert.Single(deletes);
s.FindAlertMessage();
2020-11-06 12:42:26 +01:00
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Let's try to update one of them");
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.LinkText("Modify")).Click();
2020-11-13 06:01:51 +01:00
using FakeServer server = new FakeServer();
await server.Start();
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.Name("PayloadUrl")).Clear();
2020-11-13 06:01:51 +01:00
s.Driver.FindElement(By.Name("PayloadUrl")).SendKeys(server.ServerUri.AbsoluteUri);
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.Name("Secret")).Clear();
s.Driver.FindElement(By.Name("Secret")).SendKeys("HelloWorld");
s.Driver.FindElement(By.Name("update")).Click();
s.FindAlertMessage();
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.LinkText("Modify")).Click();
foreach (var value in Enum.GetValues(typeof(WebhookEventType)))
{
// Here we make sure we did not forget an event type in the list
// However, maybe some event should not appear here because not at the store level.
// Fix as needed.
Assert.Contains($"value=\"{value}\"", s.Driver.PageSource);
}
2020-11-06 12:42:26 +01:00
// This one should be checked
Assert.Contains($"value=\"InvoiceProcessing\" checked", s.Driver.PageSource);
2020-11-06 12:42:26 +01:00
Assert.Contains($"value=\"InvoiceCreated\" checked", s.Driver.PageSource);
// This one never been checked
Assert.DoesNotContain($"value=\"InvoiceReceivedPayment\" checked", s.Driver.PageSource);
s.Driver.FindElement(By.Name("update")).Click();
s.FindAlertMessage();
2020-11-13 06:01:51 +01:00
Assert.Contains(server.ServerUri.AbsoluteUri, s.Driver.PageSource);
2020-11-06 12:42:26 +01:00
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Let's see if we can generate an event");
s.GoToStore(storeId);
2020-11-06 12:42:26 +01:00
s.AddDerivationScheme();
s.CreateInvoice(storeName);
2020-11-06 12:42:26 +01:00
var request = await server.GetNextRequest();
2020-11-13 06:01:51 +01:00
var headers = request.Request.Headers;
2020-11-06 12:42:26 +01:00
var actualSig = headers["BTCPay-Sig"].First();
2020-11-13 06:01:51 +01:00
var bytes = await request.Request.Body.ReadBytesAsync((int)headers.ContentLength.Value);
var expectedSig =
$"sha256={Encoders.Hex.EncodeData(new HMACSHA256(Encoding.UTF8.GetBytes("HelloWorld")).ComputeHash(bytes))}";
2020-11-06 12:42:26 +01:00
Assert.Equal(expectedSig, actualSig);
2020-11-13 06:01:51 +01:00
request.Response.StatusCode = 200;
server.Done();
2020-11-06 12:42:26 +01:00
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Let's make a failed event");
s.CreateInvoice(storeName);
2020-11-06 12:42:26 +01:00
request = await server.GetNextRequest();
2020-11-13 06:01:51 +01:00
request.Response.StatusCode = 404;
server.Done();
2020-11-06 12:42:26 +01:00
// The delivery is done asynchronously, so small wait here
await Task.Delay(500);
s.GoToStore(storeId, Views.Stores.StoreNavPages.Webhooks);
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.LinkText("Modify")).Click();
var elements = s.Driver.FindElements(By.ClassName("redeliver"));
// One worked, one failed
s.Driver.FindElement(By.ClassName("fa-times"));
s.Driver.FindElement(By.ClassName("fa-check"));
elements[0].Click();
s.FindAlertMessage();
2020-11-06 12:42:26 +01:00
request = await server.GetNextRequest();
2020-11-13 06:01:51 +01:00
request.Response.StatusCode = 404;
server.Done();
2020-11-06 12:42:26 +01:00
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Can we browse the json content?");
2020-11-06 12:42:26 +01:00
CanBrowseContent(s);
s.GoToInvoices();
s.Driver.FindElement(By.LinkText("Details")).Click();
CanBrowseContent(s);
var element = s.Driver.FindElement(By.ClassName("redeliver"));
element.Click();
s.FindAlertMessage();
2020-11-06 12:42:26 +01:00
request = await server.GetNextRequest();
2020-11-13 06:01:51 +01:00
request.Response.StatusCode = 404;
server.Done();
2020-11-06 12:42:26 +01:00
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Let's see if we can delete store with some webhooks inside");
s.GoToStore(storeId, StoreNavPages.GeneralSettings);
2020-11-06 12:42:26 +01:00
s.Driver.FindElement(By.Id("delete-store")).Click();
s.Driver.WaitForElement(By.Id("ConfirmContinue")).Click();
s.FindAlertMessage();
2020-11-06 12:42:26 +01:00
}
}
[Fact(Timeout = TestTimeout)]
public async Task CanImportMnemonic()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
await s.StartAsync();
s.RegisterNewUser(true);
foreach (var isHotwallet in new[] { false, true })
{
var cryptoCode = "BTC";
var (_, storeId) = s.CreateNewStore();
s.GenerateWallet(cryptoCode, "melody lizard phrase voice unique car opinion merge degree evil swift cargo", privkeys: isHotwallet);
s.GoToWalletSettings(storeId, cryptoCode);
if (isHotwallet)
Assert.Contains("View seed", s.Driver.PageSource);
else
Assert.DoesNotContain("View seed", s.Driver.PageSource);
}
}
}
[Fact(Timeout = TestTimeout)]
2019-10-07 09:04:25 +02:00
public async Task CanManageWallet()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
2019-10-07 09:04:25 +02:00
await s.StartAsync();
2019-10-12 13:35:30 +02:00
s.RegisterNewUser(true);
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
var (storeName, storeId) = s.CreateNewStore();
var cryptoCode = "BTC";
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
// In this test, we try to spend from a manual seed. We import the xpub 49'/0'/0',
// then try to use the seed to sign the transaction
s.GenerateWallet(cryptoCode, "", true);
2020-06-24 03:34:09 +02:00
//let's test quickly the receive wallet page
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
2020-01-21 09:33:12 +01:00
s.Driver.FindElement(By.Id("WalletSend")).Click();
s.Driver.FindElement(By.Id("SignTransaction")).Click();
2021-01-25 14:10:19 +01:00
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
//you cannot use the Sign with NBX option without saving private keys when generating the wallet.
2020-01-21 09:33:12 +01:00
Assert.DoesNotContain("nbx-seed", s.Driver.PageSource);
2020-06-24 03:34:09 +02:00
s.Driver.FindElement(By.Id("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");
//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"));
2020-06-24 03:34:09 +02:00
//send money to addr and ensure it changed
var sess = await s.Server.ExplorerClient.CreateWebsocketNotificationSessionAsync();
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
await sess.ListenAllTrackedSourceAsync();
var nextEvent = sess.NextEventAsync();
await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(receiveAddr, Network.RegTest),
Money.Parse("0.1"));
await nextEvent;
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");
2020-07-20 17:46:25 +02:00
//change the wallet and ensure old address is not there and generating a new one does not result in the prev one
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
s.GoToStore(storeId);
s.GenerateWallet(cryptoCode, "", true);
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.Driver.FindElement(By.Id("WalletReceive")).Click();
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
Assert.NotEqual(receiveAddr, s.Driver.FindElement(By.Id("address")).GetAttribute("value"));
2020-06-24 03:34:09 +02:00
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
var invoiceId = s.CreateInvoice(storeName);
var invoice = await s.Server.PayTester.InvoiceRepository.GetInvoice(invoiceId);
2019-12-05 18:56:40 +01:00
var address = invoice.EntityToDTO().Addresses["BTC"];
2020-06-24 03:34:09 +02:00
2020-01-21 09:33:12 +01:00
//wallet should have been imported to bitcoin core wallet in watch only mode.
var result =
await s.Server.ExplorerNode.GetAddressInfoAsync(BitcoinAddress.Create(address, Network.RegTest));
2019-12-06 10:03:17 +01:00
Assert.True(result.IsWatchOnly);
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
s.GoToStore(storeId);
var mnemonic = s.GenerateWallet(cryptoCode, "", true, true);
2020-06-24 03:34:09 +02:00
2020-01-21 09:33:12 +01:00
//lets import and save private keys
var root = mnemonic.DeriveExtKey();
Wallet setup redesign (#2164) * Prepare existing layouts and views * Add icon view component and sprite svg * Add wallet setup basics * Add import method view basics * Use external sprite file instead of inline svg * Refactor hardware wallet setup flow * Manually enter an xpub * Prepare other views * Update views and models * Finalize wallet setup flow * Updat tests, part 1 * Update tests, part 2 * Vaul: Fix missing retry button * Add better Scan QR subtext Still tbd. * Make wallet account an advanced setting * Prevent empty xpub * Use textarea for seed input * Remove redundant error message for missing file upload * Confirm store updates after generating a new wallet * Update wording * Modify existing wallets * Fix proposed method name * Suggest using ColdCard Electrum export option only Advise the user to use the electrum export of the coldcard instead of saying either electrum or wasabi export file … the electurm one contains more info, e.g. the wasabi one doesn't include the account key path. * More concise WalletSetupMethod setting * Test fix * Update wallet removal code * Fix back navigation quirk in change wallet case * Fix behaviour on wallet enable/disable * Fix initial wallet setup * Improve modify view and messages * Test fixes * Seed import fix Uses the correct form url for confirming addresses * Quickfixes from design meeting * Add enable toggle switch on modify page * Confirm wallet removal * Update setup view * Update import view * Icon finetuning * Improve import options page * Refactor QR code scanner Allow for usage with and without modal * Update copy and instructions on import pages * Split generate options: Hot wallet and watch-only * Implement hot wallet options correctly * Minor test changes * Navbar improvements * Fix tables * Fix badge color * Routing related updates Thanks @kukks for the suggestions! * Wording updates Thanks @kukks for the suggestions! * Extend address types table for xpub import Thanks @kukks for the suggestions! * Rename controller * Unify precondition checks * Improve removal warning for hot wallets * Add tooltip on why seed import is not recommended * Add tooltip icon * Add Specter import info
2021-02-11 11:48:54 +01:00
invoiceId = s.CreateInvoice(storeName);
2020-06-24 03:34:09 +02:00
invoice = await s.Server.PayTester.InvoiceRepository.GetInvoice(invoiceId);
address = invoice.EntityToDTO().Addresses["BTC"];
result = await s.Server.ExplorerNode.GetAddressInfoAsync(
BitcoinAddress.Create(address, Network.RegTest));
2020-06-24 03:34:09 +02:00
//spendable from bitcoin core wallet!
Assert.False(result.IsWatchOnly);
var tx = s.Server.ExplorerNode.SendToAddress(BitcoinAddress.Create(address, Network.RegTest),
Money.Coins(3.0m));
2021-01-25 14:10:19 +01:00
await s.Server.ExplorerNode.GenerateAsync(1);
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.ClickOnAllSideMenus();
// Make sure wallet info is correct
s.GoToWalletSettings(storeId, cryptoCode);
Assert.Contains(mnemonic.DeriveExtKey().GetPublicKey().GetHDFingerPrint().ToString(),
s.Driver.FindElement(By.Id("AccountKeys_0__MasterFingerprint")).GetAttribute("value"));
Assert.Contains("m/84'/1'/0'",
s.Driver.FindElement(By.Id("AccountKeys_0__AccountKeyPath")).GetAttribute("value"));
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
2019-10-12 13:35:30 +02:00
// Make sure we can rescan, because we are admin!
s.Driver.FindElement(By.Id("WalletRescan")).Click();
2019-10-12 13:35:30 +02:00
Assert.Contains("The batch size make sure", s.Driver.PageSource);
// Check the tx sent earlier arrived
s.Driver.FindElement(By.Id("WalletTransactions")).Click();
var walletTransactionLink = s.Driver.Url;
Assert.Contains(tx.ToString(), s.Driver.PageSource);
// Send to bob
s.Driver.FindElement(By.Id("WalletSend")).Click();
var bob = new Key().PubKey.Hash.GetAddress(Network.RegTest);
SetTransactionOutput(s, 0, bob, 1);
s.Driver.FindElement(By.Id("SignTransaction")).Click();
// Broadcast
Assert.Contains(bob.ToString(), s.Driver.PageSource);
Assert.Contains("1.00000000", s.Driver.PageSource);
s.Driver.FindElement(By.CssSelector("button[value=broadcast]")).Click();
Assert.Equal(walletTransactionLink, s.Driver.Url);
2020-06-24 03:34:09 +02:00
2020-01-21 09:33:12 +01:00
s.Driver.FindElement(By.Id("Wallets")).Click();
s.Driver.FindElement(By.LinkText("Manage")).Click();
s.Driver.FindElement(By.Id("WalletSend")).Click();
2020-06-24 03:34:09 +02:00
2020-01-21 09:33:12 +01:00
var jack = new Key().PubKey.Hash.GetAddress(Network.RegTest);
SetTransactionOutput(s, 0, jack, 0.01m);
s.Driver.FindElement(By.Id("SignTransaction")).Click();
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
2020-01-21 09:33:12 +01:00
Assert.Contains(jack.ToString(), s.Driver.PageSource);
Assert.Contains("0.01000000", s.Driver.PageSource);
2021-07-30 19:37:54 +02:00
Assert.EndsWith("psbt/ready", s.Driver.Url);
s.Driver.FindElement(By.CssSelector("button[value=broadcast]")).Click();
2020-01-21 09:33:12 +01:00
Assert.Equal(walletTransactionLink, s.Driver.Url);
2020-06-24 03:34:09 +02:00
var bip21 = invoice.EntityToDTO().CryptoInfo.First().PaymentUrls.BIP21;
//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(By.LinkText("Manage")).Click();
s.Driver.FindElement(By.Id("WalletSend")).Click();
s.Driver.FindElement(By.Id("bip21parse")).Click();
s.Driver.SwitchTo().Alert().SendKeys(bip21);
s.Driver.SwitchTo().Alert().Accept();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Info);
Assert.Equal(parsedBip21.Amount.ToString(false),
s.Driver.FindElement(By.Id("Outputs_0__Amount")).GetAttribute("value"));
Assert.Equal(parsedBip21.Address.ToString(),
s.Driver.FindElement(By.Id("Outputs_0__DestinationAddress")).GetAttribute("value"));
2020-06-24 03:34:09 +02:00
s.GoToWalletSettings(storeId, cryptoCode);
var settingsUrl = s.Driver.Url;
s.Driver.FindElement(By.Id("ActionsDropdownToggle")).Click();
s.Driver.FindElement(By.Id("ViewSeed")).Click();
2020-07-16 20:09:28 +02:00
2020-07-15 23:58:18 +02:00
// Seed backup page
var recoveryPhrase = s.Driver.FindElements(By.Id("RecoveryPhrase")).First()
.GetAttribute("data-mnemonic");
2020-07-15 23:58:18 +02:00
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.Equal(settingsUrl, s.Driver.Url);
}
2019-05-12 10:13:26 +02:00
}
2020-06-24 03:34:09 +02:00
[Fact(Timeout = TestTimeout)]
public async Task CanImportWallet()
{
2021-11-22 09:16:08 +01:00
using (var s = CreateSeleniumTester())
{
await s.StartAsync();
s.RegisterNewUser(true);
(string _, string storeId) = s.CreateNewStore();
var cryptoCode = "BTC";
var mnemonic = s.GenerateWallet(cryptoCode, "click chunk owner kingdom faint steak safe evidence bicycle repeat bulb wheel");
// Make sure wallet info is correct
s.GoToWalletSettings(storeId, cryptoCode);
Assert.Contains(mnemonic.DeriveExtKey().GetPublicKey().GetHDFingerPrint().ToString(),
s.Driver.FindElement(By.Id("AccountKeys_0__MasterFingerprint")).GetAttribute("value"));
Assert.Contains("m/84'/1'/0'",
s.Driver.FindElement(By.Id("AccountKeys_0__AccountKeyPath")).GetAttribute("value"));
}
}
2020-06-24 03:34:09 +02:00
[Fact]
[Trait("Selenium", "Selenium")]
[Trait("Lightning", "Lightning")]
2020-06-24 03:34:09 +02:00
public async Task CanUsePullPaymentsViaUI()
{
2021-11-22 09:16:08 +01:00
using var s = CreateSeleniumTester();
s.Server.ActivateLightning(LightningConnectionType.LndREST);
await s.StartAsync();
await s.Server.EnsureChannelsSetup();
s.RegisterNewUser(true);
s.CreateNewStore();
s.GenerateWallet("BTC", "", true, true);
await s.Server.ExplorerNode.GenerateAsync(1);
await s.FundStoreWallet(denomination: 50.0m);
s.GoToStore(s.StoreId, StoreNavPages.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(By.LinkText("View")).Click();
s.GoToStore(s.StoreId, StoreNavPages.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();
// 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();
// 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.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();
Assert.Contains("Awaiting Approval", s.Driver.PageSource);
var viewPullPaymentUrl = s.Driver.Url;
// This one should have nothing
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
var payouts = s.Driver.FindElements(By.ClassName("pp-payout"));
Assert.Equal(2, payouts.Count);
payouts[1].Click();
Assert.Empty(s.Driver.FindElements(By.ClassName("payout")));
// PP2 should have payouts
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
payouts = s.Driver.FindElements(By.ClassName("pp-payout"));
payouts[0].Click();
Assert.NotEmpty(s.Driver.FindElements(By.ClassName("payout")));
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-selectAllCheckbox")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-actions")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-approve-pay")).Click();
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
s.Driver.FindElement(By.Id("SignTransaction")).Click();
s.Driver.FindElement(By.CssSelector("button[value=broadcast]")).Click();
s.FindAlertMessage();
2020-06-24 03:34:09 +02:00
TestUtils.Eventually(() =>
{
s.Driver.Navigate().Refresh();
Assert.Contains("badge transactionLabel", s.Driver.PageSource);
});
Assert.Equal("payout", s.Driver.FindElement(By.ClassName("transactionLabel")).Text);
s.GoToStore(s.StoreId, StoreNavPages.Payouts);
var x = s.Driver.PageSource;
s.Driver.FindElement(By.Id($"{PayoutState.InProgress}-view")).Click();
ReadOnlyCollection<IWebElement> txs;
TestUtils.Eventually(() =>
{
s.Driver.Navigate().Refresh();
2020-06-24 03:34:09 +02:00
txs = s.Driver.FindElements(By.ClassName("transaction-link"));
Assert.Equal(2, txs.Count);
});
2020-06-24 03:34:09 +02:00
s.Driver.Navigate().GoToUrl(viewPullPaymentUrl);
txs = s.Driver.FindElements(By.ClassName("transaction-link"));
Assert.Equal(2, txs.Count);
Assert.Contains(PayoutState.InProgress.GetStateString(), s.Driver.PageSource);
2020-06-24 03:34:09 +02:00
await s.Server.ExplorerNode.GenerateAsync(1);
2020-06-24 03:34:09 +02:00
TestUtils.Eventually(() =>
{
s.Driver.Navigate().Refresh();
Assert.Contains(PayoutState.Completed.GetStateString(), s.Driver.PageSource);
});
await s.Server.ExplorerNode.GenerateAsync(10);
var pullPaymentId = viewPullPaymentUrl.Split('/').Last();
await TestUtils.EventuallyAsync(async () =>
{
using var ctx = s.Server.PayTester.GetService<ApplicationDbContextFactory>().CreateContext();
var payoutsData = await ctx.Payouts.Where(p => p.PullPaymentDataId == pullPaymentId).ToListAsync();
Assert.True(payoutsData.All(p => p.State == PayoutState.Completed));
});
s.GoToHome();
//offline/external payout test
s.Driver.FindElement(By.Id("NotificationsDropdownToggle")).Click();
s.Driver.FindElement(By.CssSelector("#notificationsForm button")).Click();
var newStore = s.CreateNewStore();
s.GenerateWallet("BTC", "", true, true);
var newWalletId = new WalletId(newStore.storeId, "BTC");
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
s.Driver.FindElement(By.Id("Name")).SendKeys("External Test");
s.Driver.FindElement(By.Id("Amount")).Clear();
s.Driver.FindElement(By.Id("Amount")).SendKeys("0.001");
s.Driver.FindElement(By.Id("Currency")).Clear();
s.Driver.FindElement(By.Id("Currency")).SendKeys("BTC");
s.Driver.FindElement(By.Id("Create")).Click();
s.Driver.FindElement(By.LinkText("View")).Click();
address = await s.Server.ExplorerNode.GetNewAddressAsync();
s.Driver.FindElement(By.Id("Destination")).SendKeys(address.ToString());
s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys(Keys.Enter);
s.FindAlertMessage();
Assert.Contains(PayoutState.AwaitingApproval.GetStateString(), s.Driver.PageSource);
s.GoToStore(s.StoreId, StoreNavPages.Payouts);
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-view")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-selectAllCheckbox")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-actions")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-approve")).Click();
s.FindAlertMessage();
var tx = await s.Server.ExplorerNode.SendToAddressAsync(address, Money.FromUnit(0.001m, MoneyUnit.BTC));
s.GoToStore(s.StoreId, StoreNavPages.Payouts);
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-view")).Click();
Assert.Contains(PayoutState.AwaitingPayment.GetStateString(), s.Driver.PageSource);
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-selectAllCheckbox")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-actions")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-mark-paid")).Click();
s.FindAlertMessage();
s.Driver.FindElement(By.Id($"{PayoutState.InProgress}-view")).Click();
Assert.Contains(tx.ToString(), s.Driver.PageSource);
//lightning tests
// Since the merchant is sending on lightning, it needs some liquidity from the client
var payoutAmount = LightMoney.Satoshis(1000);
var minimumReserve = LightMoney.Satoshis(167773m);
var inv = await s.Server.MerchantLnd.Client.CreateInvoice(minimumReserve + payoutAmount, "Donation to merchant", TimeSpan.FromHours(1), default);
var resp = await s.Server.CustomerLightningD.Pay(inv.BOLT11);
Assert.Equal(PayResult.Ok, resp.Result);
newStore = s.CreateNewStore();
s.AddLightningNode("BTC");
//Currently an onchain wallet is required to use the Lightning payouts feature..
s.GenerateWallet("BTC", "", true, true);
s.GoToStore(newStore.storeId, StoreNavPages.PullPayments);
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
var paymentMethodOptions = s.Driver.FindElements(By.CssSelector("input[name='PaymentMethods']"));
Assert.Equal(2, paymentMethodOptions.Count);
s.Driver.FindElement(By.Id("Name")).SendKeys("Lightning Test");
s.Driver.FindElement(By.Id("Amount")).Clear();
s.Driver.FindElement(By.Id("Amount")).SendKeys(payoutAmount.ToString());
s.Driver.FindElement(By.Id("Currency")).Clear();
s.Driver.FindElement(By.Id("Currency")).SendKeys("BTC");
s.Driver.FindElement(By.Id("Create")).Click();
s.Driver.FindElement(By.LinkText("View")).Click();
var bolt = (await s.Server.CustomerLightningD.CreateInvoice(
payoutAmount,
$"LN payout test {DateTime.Now.Ticks}",
TimeSpan.FromHours(1), CancellationToken.None)).BOLT11;
s.Driver.FindElement(By.Id("Destination")).SendKeys(bolt);
s.Driver.FindElement(By.Id("SelectedPaymentMethod")).Click();
s.Driver.FindElement(By.CssSelector(
$"#SelectedPaymentMethod option[value={new PaymentMethodId("BTC", PaymentTypes.LightningLike)}]"))
.Click();
s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys(Keys.Enter);
//we do not allow short-life bolts.
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Error);
bolt = (await s.Server.CustomerLightningD.CreateInvoice(
payoutAmount,
$"LN payout test {DateTime.Now.Ticks}",
TimeSpan.FromDays(31), CancellationToken.None)).BOLT11;
s.Driver.FindElement(By.Id("Destination")).Clear();
s.Driver.FindElement(By.Id("Destination")).SendKeys(bolt);
s.Driver.FindElement(By.Id("SelectedPaymentMethod")).Click();
s.Driver.FindElement(By.CssSelector(
$"#SelectedPaymentMethod option[value={new PaymentMethodId("BTC", PaymentTypes.LightningLike)}]"))
.Click();
s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys(Keys.Enter);
s.FindAlertMessage();
Assert.Contains(PayoutState.AwaitingApproval.GetStateString(), s.Driver.PageSource);
s.GoToStore(newStore.storeId, StoreNavPages.Payouts);
s.Driver.FindElement(By.Id($"{new PaymentMethodId("BTC", PaymentTypes.LightningLike)}-view")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-view")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-selectAllCheckbox")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-actions")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-approve-pay")).Click();
Assert.Contains(bolt, s.Driver.PageSource);
Assert.Contains($"{payoutAmount.ToString()} BTC", s.Driver.PageSource);
s.Driver.FindElement(By.CssSelector("#pay-invoices-form")).Submit();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
s.GoToStore(newStore.storeId, StoreNavPages.Payouts);
s.Driver.FindElement(By.Id($"{new PaymentMethodId("BTC", PaymentTypes.LightningLike)}-view")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.Completed}-view")).Click();
if (!s.Driver.PageSource.Contains(bolt))
{
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-view")).Click();
Assert.Contains(bolt, s.Driver.PageSource);
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-selectAllCheckbox")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-actions")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingPayment}-mark-paid")).Click();
s.Driver.FindElement(By.Id($"{new PaymentMethodId("BTC", PaymentTypes.LightningLike)}-view")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.Completed}-view")).Click();
Assert.Contains(bolt, s.Driver.PageSource);
}
2021-10-26 13:55:13 +02:00
}
2021-10-29 10:27:33 +02:00
[Fact]
[Trait("Selenium", "Selenium")]
[Trait("Lightning", "Lightning")]
public async Task CanUsePOSPrint()
{
2021-11-22 09:16:08 +01:00
using var s = CreateSeleniumTester();
2021-10-29 10:27:33 +02:00
s.Server.ActivateLightning();
await s.StartAsync();
await s.Server.EnsureChannelsSetup();
s.RegisterNewUser(true);
var cryptoCode = "BTC";
(_, string storeId) = s.CreateNewStore();
var network = s.Server.NetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode).NBitcoinNetwork;
s.GoToStore(storeId);
s.AddLightningNode(cryptoCode, LightningConnectionType.CLightning, false);
s.GoToLightningSettings(storeId, cryptoCode);
2021-10-29 10:27:33 +02:00
s.Driver.SetCheckbox(By.Id("LNURLEnabled"), true);
s.GoToApps();
s.Driver.FindElement(By.Id("CreateNewApp")).Click();
s.Driver.FindElement(By.Id("SelectedAppType")).Click();
s.Driver.FindElement(By.CssSelector("option[value='PointOfSale']")).Click();
2021-10-29 16:09:19 +02:00
s.Driver.FindElement(By.Id("AppName")).SendKeys(Guid.NewGuid().ToString());
2021-10-29 10:27:33 +02:00
s.Driver.FindElement(By.Id("Create")).Click();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
s.Driver.FindElement(By.Id("DefaultView")).Click();
s.Driver.FindElement(By.CssSelector("option[value='3']")).Click();
s.Driver.FindElement(By.Id("SaveSettings")).Click();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
s.Driver.FindElement(By.Id("ViewApp")).Click();
var btns = s.Driver.FindElements(By.ClassName("lnurl"));
foreach (IWebElement webElement in btns)
{
var choice = webElement.GetAttribute("data-choice");
var lnurl = webElement.GetAttribute("href");
var parsed = LNURL.LNURL.Parse(lnurl, out _);
2021-10-29 14:51:41 +02:00
Assert.EndsWith(choice, parsed.ToString());
2021-10-29 10:27:33 +02:00
Assert.IsType<LNURLPayRequest>(await LNURL.LNURL.FetchInformation(parsed, new HttpClient()));
}
}
[Fact]
2021-10-26 13:55:13 +02:00
[Trait("Selenium", "Selenium")]
[Trait("Lightning", "Lightning")]
public async Task CanUseLNURL()
{
2021-11-22 09:16:08 +01:00
using var s = CreateSeleniumTester();
2021-10-26 13:55:13 +02:00
s.Server.ActivateLightning();
await s.StartAsync();
await s.Server.EnsureChannelsSetup();
var cryptoCode = "BTC";
await Lightning.Tests.ConnectChannels.ConnectAll(s.Server.ExplorerNode,
2021-10-26 13:55:13 +02:00
new[] { s.Server.MerchantLightningD },
new[] { s.Server.MerchantLnd.Client });
s.RegisterNewUser(true);
(string storeName, string storeId) = s.CreateNewStore();
var network = s.Server.NetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode).NBitcoinNetwork;
s.GoToStore(storeId);
s.AddLightningNode(cryptoCode, LightningConnectionType.CLightning, false);
s.GoToLightningSettings(storeId, cryptoCode);
// LNURL is false by default
Assert.False(s.Driver.FindElement(By.Id("LNURLEnabled")).Selected);
// LNURL settings are not expanded when LNURL is disabled
Assert.DoesNotContain("show", s.Driver.FindElement(By.Id("LNURLSettings")).GetAttribute("class"));
s.Driver.SetCheckbox(By.Id("LNURLEnabled"), true);
2021-11-26 07:07:54 +01:00
SudoForceSaveLightningSettingsRightNowAndFast(s, cryptoCode);
// Topup Invoice test
var i = s.CreateInvoice(storeName, null, cryptoCode);
2021-10-26 13:55:13 +02:00
s.GoToInvoiceCheckout(i);
s.Driver.FindElement(By.Id("copy-tab")).Click();
var lnurl = s.Driver.FindElement(By.CssSelector("input.checkoutTextbox")).GetAttribute("value");
var parsed = LNURL.LNURL.Parse(lnurl, out var tag);
var fetchedReuqest =
Assert.IsType<LNURL.LNURLPayRequest>(await LNURL.LNURL.FetchInformation(parsed, new HttpClient()));
2021-10-26 13:55:13 +02:00
Assert.Equal(1m, fetchedReuqest.MinSendable.ToDecimal(LightMoneyUnit.Satoshi));
Assert.NotEqual(1m, fetchedReuqest.MaxSendable.ToDecimal(LightMoneyUnit.Satoshi));
var lnurlResponse = await fetchedReuqest.SendRequest(new LightMoney(0.000001m, LightMoneyUnit.BTC),
network, new HttpClient());
Assert.Equal(new LightMoney(0.000001m, LightMoneyUnit.BTC),
lnurlResponse.GetPaymentRequest(network).MinimumAmount);
2021-10-26 13:55:13 +02:00
var lnurlResponse2 = await fetchedReuqest.SendRequest(new LightMoney(0.000002m, LightMoneyUnit.BTC),
network, new HttpClient());
Assert.Equal(new LightMoney(0.000002m, LightMoneyUnit.BTC), lnurlResponse2.GetPaymentRequest(network).MinimumAmount);
await Assert.ThrowsAnyAsync<LightningRPCException>(async () =>
2021-10-26 13:55:13 +02:00
{
// Initial bolt was cancelled
2021-10-26 13:55:13 +02:00
await s.Server.CustomerLightningD.Pay(lnurlResponse.Pr);
});
await s.Server.CustomerLightningD.Pay(lnurlResponse2.Pr);
2021-10-26 13:55:13 +02:00
await TestUtils.EventuallyAsync(async () =>
{
var inv = await s.Server.PayTester.InvoiceRepository.GetInvoice(i);
Assert.Equal(InvoiceStatusLegacy.Complete, inv.Status);
});
// Standard invoice test
2021-10-26 13:55:13 +02:00
s.GoToHome();
i = s.CreateInvoice(storeName, 0.0000001m, cryptoCode);
2021-10-26 13:55:13 +02:00
s.GoToInvoiceCheckout(i);
s.Driver.FindElement(By.ClassName("payment__currencies")).Click();
// BOLT11 is also available for standard invoices
2021-10-26 13:55:13 +02:00
Assert.Equal(2, s.Driver.FindElements(By.CssSelector(".vex.vex-theme-btcpay .vex-content .vexmenu li.vexmenuitem")).Count);
s.Driver.FindElement(By.CssSelector(".vex.vex-theme-btcpay .vex-content .vexmenu li.vexmenuitem")).Click();
s.Driver.FindElement(By.Id("copy-tab")).Click();
lnurl = s.Driver.FindElement(By.CssSelector("input.checkoutTextbox")).GetAttribute("value");
parsed = LNURL.LNURL.Parse(lnurl, out tag);
fetchedReuqest = Assert.IsType<LNURLPayRequest>(await LNURL.LNURL.FetchInformation(parsed, new HttpClient()));
2021-10-26 13:55:13 +02:00
Assert.Equal(0.0000001m, fetchedReuqest.MaxSendable.ToDecimal(LightMoneyUnit.BTC));
Assert.Equal(0.0000001m, fetchedReuqest.MinSendable.ToDecimal(LightMoneyUnit.BTC));
await Assert.ThrowsAsync<HttpRequestException>(async () =>
{
await fetchedReuqest.SendRequest(new LightMoney(0.0000002m, LightMoneyUnit.BTC),
network, new HttpClient());
});
await Assert.ThrowsAsync<HttpRequestException>(async () =>
{
await fetchedReuqest.SendRequest(new LightMoney(0.00000005m, LightMoneyUnit.BTC),
network, new HttpClient());
});
2021-10-26 13:55:13 +02:00
lnurlResponse = await fetchedReuqest.SendRequest(new LightMoney(0.0000001m, LightMoneyUnit.BTC),
network, new HttpClient());
lnurlResponse2 = await fetchedReuqest.SendRequest(new LightMoney(0.0000001m, LightMoneyUnit.BTC),
network, new HttpClient());
//invoice amounts do no change so the paymnet request is not regenerated
Assert.Equal(lnurlResponse.Pr, lnurlResponse2.Pr);
2021-10-26 13:55:13 +02:00
await s.Server.CustomerLightningD.Pay(lnurlResponse.Pr);
Assert.Equal(new LightMoney(0.0000001m, LightMoneyUnit.BTC),
lnurlResponse2.GetPaymentRequest(network).MinimumAmount);
s.GoToLightningSettings(s.StoreId, cryptoCode);
// LNURL is enabled and settings are expanded
Assert.True(s.Driver.FindElement(By.Id("LNURLEnabled")).Selected);
Assert.Contains("show", s.Driver.FindElement(By.Id("LNURLSettings")).GetAttribute("class"));
s.Driver.SetCheckbox(By.Id("LNURLStandardInvoiceEnabled"), false);
s.Driver.FindElement(By.Id("save")).Click();
Assert.Contains($"{cryptoCode} Lightning settings successfully updated", s.FindAlertMessage().Text);
i = s.CreateInvoice(storeName, 0.000001m, cryptoCode);
2021-10-26 13:55:13 +02:00
s.GoToInvoiceCheckout(i);
s.Driver.FindElement(By.ClassName("payment__currencies_noborder"));
s.GoToHome();
i = s.CreateInvoice(storeName, null, cryptoCode);
2021-10-26 13:55:13 +02:00
s.GoToInvoiceCheckout(i);
s.Driver.FindElement(By.ClassName("payment__currencies_noborder"));
s.GoToLightningSettings(s.StoreId, cryptoCode);
s.Driver.SetCheckbox(By.Id("LNURLBech32Mode"), false);
s.Driver.SetCheckbox(By.Id("LNURLStandardInvoiceEnabled"), false);
s.Driver.SetCheckbox(By.Id("DisableBolt11PaymentMethod"), true);
s.Driver.FindElement(By.Id("save")).Click();
Assert.Contains($"{cryptoCode} Lightning settings successfully updated", s.FindAlertMessage().Text);
2021-10-26 13:55:13 +02:00
// Ensure the toggles are set correctly
s.GoToLightningSettings(s.StoreId, cryptoCode);
2021-10-29 16:09:19 +02:00
//TODO: DisableBolt11PaymentMethod is actually disabled because LNURLStandardInvoiceEnabled is disabled
// checkboxes is not good choice here, in next release we should have multi choice instead
Assert.False(s.Driver.FindElement(By.Id("LNURLBech32Mode")).Selected);
Assert.False(s.Driver.FindElement(By.Id("LNURLStandardInvoiceEnabled")).Selected);
//even though we set DisableBolt11PaymentMethod to true, logic when saving it turns it back off as otherwise no lightning option is available at all!
Assert.False(s.Driver.FindElement(By.Id("DisableBolt11PaymentMethod")).Selected);
// Invoice creation should fail, because it is a standard invoice with amount, but DisableBolt11PaymentMethod = true and LNURLStandardInvoiceEnabled = false
s.CreateInvoice(storeName, 0.0000001m, cryptoCode,"",null, expectedSeverity: StatusMessageModel.StatusSeverity.Success);
i = s.CreateInvoice(storeName, null, cryptoCode);
2021-10-26 13:55:13 +02:00
s.GoToInvoiceCheckout(i);
s.Driver.FindElement(By.ClassName("payment__currencies_noborder"));
s.Driver.FindElement(By.Id("copy-tab")).Click();
lnurl = s.Driver.FindElement(By.CssSelector("input.checkoutTextbox")).GetAttribute("value");
Assert.StartsWith("lnurlp", lnurl);
LNURL.LNURL.Parse(lnurl, out tag);
2021-10-26 13:55:13 +02:00
s.GoToHome();
var newStore = s.CreateNewStore(false);
s.AddLightningNode(cryptoCode, LightningConnectionType.LndREST, false);
s.GoToLightningSettings(newStore.storeId, cryptoCode);
s.Driver.SetCheckbox(By.Id("LNURLEnabled"), true);
s.Driver.SetCheckbox(By.Id("DisableBolt11PaymentMethod"), true);
s.Driver.FindElement(By.Id("save")).Click();
Assert.Contains($"{cryptoCode} Lightning settings successfully updated", s.FindAlertMessage().Text);
var invForPP = s.CreateInvoice(newStore.storeName, 0.0000001m, cryptoCode);
2021-10-26 13:55:13 +02:00
s.GoToInvoiceCheckout(invForPP);
s.Driver.FindElement(By.Id("copy-tab")).Click();
lnurl = s.Driver.FindElement(By.CssSelector("input.checkoutTextbox")).GetAttribute("value");
parsed = LNURL.LNURL.Parse(lnurl, out tag);
// Check that pull payment has lightning option
2021-10-26 13:55:13 +02:00
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
Assert.Equal(new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike),PaymentMethodId.Parse(Assert.Single(s.Driver.FindElements(By.CssSelector("input[name='PaymentMethods']"))).GetAttribute("value")));
2021-10-26 13:55:13 +02:00
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
s.Driver.FindElement(By.Id("Amount")).Clear();
s.Driver.FindElement(By.Id("Amount")).SendKeys("0.0000001");
2021-10-26 13:55:13 +02:00
s.Driver.FindElement(By.Id("Create")).Click();
s.Driver.FindElement(By.LinkText("View")).Click();
s.Driver.FindElement(By.Id("Destination")).SendKeys(lnurl);
2021-10-26 13:55:13 +02:00
var pullPaymentId = s.Driver.Url.Split('/').Last();
s.Driver.FindElement(By.Id("ClaimedAmount")).Clear();
s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys("0.0000001" + Keys.Enter);
s.FindAlertMessage();
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
var payouts = s.Driver.FindElements(By.ClassName("pp-payout"));
payouts[0].Click();
s.Driver.FindElement(By.Id("BTC_LightningLike-view")).Click();
2021-10-26 13:55:13 +02:00
Assert.NotEmpty(s.Driver.FindElements(By.ClassName("payout")));
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-selectAllCheckbox")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-actions")).Click();
s.Driver.FindElement(By.Id($"{PayoutState.AwaitingApproval}-approve-pay")).Click();
Assert.Contains(lnurl, s.Driver.PageSource);
2021-10-26 13:55:13 +02:00
s.Driver.FindElement(By.Id("pay-invoices-form")).Submit();
2021-10-26 13:55:13 +02:00
await TestUtils.EventuallyAsync(async () =>
{
var inv = await s.Server.PayTester.InvoiceRepository.GetInvoice(invForPP);
Assert.Equal(InvoiceStatusLegacy.Complete, inv.Status);
await using var ctx = s.Server.PayTester.GetService<ApplicationDbContextFactory>().CreateContext();
var payoutsData = await ctx.Payouts.Where(p => p.PullPaymentDataId == pullPaymentId).ToListAsync();
Assert.True(payoutsData.All(p => p.State == PayoutState.Completed));
});
2020-06-24 03:34:09 +02:00
}
[Fact]
[Trait("Selenium", "Selenium")]
[Trait("Lightning", "Lightning")]
public async Task CanUseLNAddress()
{
2021-11-22 09:16:08 +01:00
using var s = CreateSeleniumTester();
s.Server.ActivateLightning();
await s.StartAsync();
await s.Server.EnsureChannelsSetup();
var cryptoCode = "BTC";
s.RegisterNewUser(true);
//ln address tests
s.CreateNewStore();
s.GoToStore(s.StoreId, StoreNavPages.Integrations);
//ensure ln address is not available as Lightning is not enable
s.Driver.FindElement(By.Id("lightning-address-option"))
.FindElement(By.LinkText("You need to setup Lightning first"));
s.GoToStore(s.StoreId);
s.AddLightningNode("BTC", LightningConnectionType.LndREST, false);
s.GoToStore(s.StoreId, StoreNavPages.Integrations);
//ensure ln address is not available as lnurl is not configured
s.Driver.FindElement(By.Id("lightning-address-option"))
.FindElement(By.LinkText("You need LNURL configured first"));
s.GoToLightningSettings(s.StoreId, cryptoCode);
s.Driver.SetCheckbox(By.Id("LNURLEnabled"), true);
2021-11-26 07:07:54 +01:00
SudoForceSaveLightningSettingsRightNowAndFast(s, cryptoCode);
s.GoToStore(s.StoreId, StoreNavPages.Integrations);
s.Driver.FindElement(By.Id("lightning-address-option"))
.FindElement(By.Id("lightning-address-setup-link")).Click();
s.Driver.ToggleCollapse("AddAddress");
var lnaddress1 = Guid.NewGuid().ToString();
s.Driver.FindElement(By.Id("Add_Username")).SendKeys(lnaddress1);
s.Driver.FindElement(By.CssSelector("button[value='add']")).Click();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
s.Driver.ToggleCollapse("AddAddress");
s.Driver.FindElement(By.Id("Add_Username")).SendKeys(lnaddress1);
s.Driver.FindElement(By.CssSelector("button[value='add']")).Click();
s.Driver.FindElement(By.ClassName("text-danger"));
s.Driver.FindElement(By.Id("Add_Username")).Clear();
var lnaddress2 = "EUR" + Guid.NewGuid().ToString();
s.Driver.FindElement(By.Id("Add_Username")).SendKeys(lnaddress2);
s.Driver.ToggleCollapse("AdvancedSettings");
s.Driver.FindElement(By.Id("Add_CurrencyCode")).SendKeys("EUR");
s.Driver.FindElement(By.Id("Add_Min")).SendKeys("2");
s.Driver.FindElement(By.Id("Add_Max")).SendKeys("10");
s.Driver.FindElement(By.CssSelector("button[value='add']")).Click();
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
var addresses = s.Driver.FindElements(By.ClassName("lightning-address-value"));
Assert.Equal(2, addresses.Count);
foreach (IWebElement webElement in addresses)
{
var value = webElement.GetAttribute("value");
//cannot test this directly as https is not supported on our e2e tests
// var request = await LNURL.LNURL.FetchPayRequestViaInternetIdentifier(value, new HttpClient());
var lnurl = new Uri(LNURL.LNURL.ExtractUriFromInternetIdentifier(value).ToString()
.Replace("https", "http"));
var request =(LNURL.LNURLPayRequest) await LNURL.LNURL.FetchInformation(lnurl, new HttpClient());
switch (value)
{
case { } v when v.StartsWith(lnaddress2):
Assert.Equal(2, request.MinSendable.ToDecimal(LightMoneyUnit.Satoshi));
Assert.Equal(10, request.MaxSendable.ToDecimal(LightMoneyUnit.Satoshi));
break;
case { } v when v.StartsWith(lnaddress1):
Assert.Equal(1, request.MinSendable.ToDecimal(LightMoneyUnit.Satoshi));
Assert.Equal(6.12m, request.MaxSendable.ToDecimal(LightMoneyUnit.BTC));
break;
}
}
}
2021-11-26 07:07:54 +01:00
// For god know why, selenium have problems clicking on the save button, resulting in ultimate hacks
// to make it works.
private void SudoForceSaveLightningSettingsRightNowAndFast(SeleniumTester s, string cryptoCode)
{
retry:
int maxAttempts = 5;
s.Driver.WaitForAndClick(By.Id("save"));
try
{
Assert.Contains($"{cryptoCode} Lightning settings successfully updated", s.FindAlertMessage().Text);
}
catch (NoSuchElementException) when (maxAttempts > 0)
{
maxAttempts--;
goto retry;
}
}
private static void CanBrowseContent(SeleniumTester s)
{
s.Driver.FindElement(By.ClassName("delivery-content")).Click();
var windows = s.Driver.WindowHandles;
Assert.Equal(2, windows.Count);
s.Driver.SwitchTo().Window(windows[1]);
JObject.Parse(s.Driver.FindElement(By.TagName("body")).Text);
s.Driver.Close();
s.Driver.SwitchTo().Window(windows[0]);
}
private static void CanSetupEmailCore(SeleniumTester s)
{
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
s.Driver.FindElement(By.Id("QuickFillDropdownToggle")).Click();
s.Driver.FindElement(By.ClassName("dropdown-item")).Click();
Bootstrap v5 migration (#2490) * Swap bootstrap asset files * Update themes and color definitions * Move general bootstrap customizations * Theme updates Theme updates * Remove BuildBundlerMinifier This lead to an error, because BuildBundlerMinifier and BundlerMinifier.Core seem to conflict here. Details: https://stackoverflow.com/a/61119586 * Rewplace btn-block class with w-100 * Update badge classes * Remove old font family head variable * Update margin classes * Cleanups * Update float classes * Update text classes * Update padding classes * Update border classes * UPdate dropdown classes * Update select classes * Update neutral custom props * Update bootstrap and customizations * Update ChromeDriver; disable smooth scroll https://github.com/SeleniumHQ/selenium/issues/8295 * Improve alert messages * Improve bootstrap customizations * Disable reduced motion See also 7358282f * Update Bootstrap data attributes * Update file inputs * Update input groups * Replace deprecated jumbotron class * Update variables; re-add negative margin util classes * Update cards * Update form labels * Debug alerts * Fix aria-labelledby associations * Dropdown-related test fixes * Fix CanUseWebhooks test * Test fixes * Nav updates * Fix nav usage in wallet send and payouts * Update alert and modal close buttons * Re-add backdrop properties * Upgrade Bootstrap to v5 final * Update screen reader classes * Update font-weight classes * Update monospace font classes * Update accordians * Update close icon usage * Cleanup * Update scripts and style integrations * Update input group texts * Update LN node setup page * Update more form control classes * Update inline forms * Add js specific test * Upgrade Vue.js * Remove unused JS * Upgrade Bootstrap to v5.0.1 * Try container related test updates * Separate jQuery bundle * Remove jQuery from LND seed backup page * Remove unused code * Refactor email autofill js * Refactor camera scanner JS * Re-add tests * Re-add BuildBundlerMinifier * Do not minify bundles containing Bootstrap Details https://github.com/madskristensen/BundlerMinifier/issues/558 * Update bundles * Cleanup JS test * Cleanup tests involving dropdowns * Cleanup tests involving collapses * Cleanup locale additions in ConfigureCore * Cleanup bundles * Remove duplicate status message * Cleanup formatting * Fix missing validation scripts * Remove unused unminified Bootstrap js files * Fix classic theme * Fix Casa theme * Fix PoS validation
2021-05-19 04:39:27 +02:00
s.Driver.FindElement(By.Id("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");
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(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();
Assert.DoesNotContain("Configured", s.Driver.PageSource);
Assert.Contains("test_fix", s.Driver.PageSource);
}
private static string AssertUrlHasPairingCode(SeleniumTester s)
{
var regex = Regex.Match(new Uri(s.Driver.Url, UriKind.Absolute).Query, "pairingCode=([^&]*)");
Assert.True(regex.Success, $"{s.Driver.Url} does not match expected regex");
var pairingCode = regex.Groups[1].Value;
return pairingCode;
}
private void SetTransactionOutput(SeleniumTester s, int index, BitcoinAddress dest, decimal amount, bool subtract = false)
{
s.Driver.FindElement(By.Id($"Outputs_{index}__DestinationAddress")).SendKeys(dest.ToString());
var amountElement = s.Driver.FindElement(By.Id($"Outputs_{index}__Amount"));
amountElement.Clear();
amountElement.SendKeys(amount.ToString(CultureInfo.InvariantCulture));
var checkboxElement = s.Driver.FindElement(By.Id($"Outputs_{index}__SubtractFeesFromOutput"));
if (checkboxElement.Selected != subtract)
{
checkboxElement.Click();
}
}
2019-05-12 10:13:26 +02:00
}
}