btcpayserver/BTCPayServer.Tests/SeleniumTester.cs

592 lines
24 KiB
C#
Raw Normal View History

using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
2020-06-28 10:55:27 +02:00
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Models;
2021-12-31 08:59:02 +01:00
using BTCPayServer.BIP78.Sender;
using BTCPayServer.Lightning;
using BTCPayServer.Lightning.CLightning;
using BTCPayServer.Views.Manage;
2020-09-16 08:54:09 +02:00
using BTCPayServer.Views.Server;
using BTCPayServer.Views.Stores;
using BTCPayServer.Views.Wallets;
using Microsoft.Extensions.Configuration;
2020-06-28 10:55:27 +02:00
using NBitcoin;
2022-02-17 09:58:56 +01:00
using NBitcoin.RPC;
2020-06-28 10:55:27 +02:00
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
2021-12-31 08:59:02 +01:00
using Xunit;
namespace BTCPayServer.Tests
{
public class SeleniumTester : IDisposable
{
public IWebDriver Driver { get; set; }
public ServerTester Server { get; set; }
public WalletId WalletId { get; set; }
2021-01-25 14:10:19 +01:00
public string StoreId { get; set; }
public static readonly TimeSpan ImplicitWait = TimeSpan.FromSeconds(5);
2019-10-07 09:04:25 +02:00
public async Task StartAsync()
{
2021-09-09 14:51:28 +02:00
Server.PayTester.NoCSP = true;
2019-10-07 09:04:25 +02:00
await Server.StartAsync();
var windowSize = (Width: 1200, Height: 1000);
var builder = new ConfigurationBuilder();
2021-01-26 10:22:17 +01:00
builder.AddUserSecrets("AB0AC1DD-9D26-485B-9416-56A33F268117");
var config = builder.Build();
// Run `dotnet user-secrets set RunSeleniumInBrowser true` to run tests in browser
var runInBrowser = config["RunSeleniumInBrowser"] == "true";
// Reset this using `dotnet user-secrets remove RunSeleniumInBrowser`
var chromeDriverPath = config["ChromeDriverDirectory"] ?? (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory());
var options = new ChromeOptions();
if (!runInBrowser)
{
options.AddArguments("headless");
2020-01-12 05:54:06 +01:00
}
options.AddArguments($"window-size={windowSize.Width}x{windowSize.Height}");
options.AddArgument("shm-size=2g");
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
options.AddArgument("start-maximized");
if (Server.PayTester.InContainer)
{
Driver = new OpenQA.Selenium.Remote.RemoteWebDriver(new Uri("http://selenium:4444/wd/hub"), new RemoteSessionSettings(options));
var containerIp = File.ReadAllText("/etc/hosts").Split('\n', StringSplitOptions.RemoveEmptyEntries).Last()
.Split('\t', StringSplitOptions.RemoveEmptyEntries)[0].Trim();
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation($"Selenium: Container's IP {containerIp}");
ServerUri = new Uri(Server.PayTester.ServerUri.AbsoluteUri.Replace($"http://{Server.PayTester.HostName}", $"http://{containerIp}", StringComparison.OrdinalIgnoreCase), UriKind.Absolute);
}
else
{
var cds = ChromeDriverService.CreateDefaultService(chromeDriverPath);
cds.EnableVerboseLogging = true;
cds.Port = Utils.FreeTcpPort();
cds.HostName = "127.0.0.1";
cds.Start();
Driver = new ChromeDriver(cds, options,
// A bit less than test timeout
TimeSpan.FromSeconds(50));
ServerUri = Server.PayTester.ServerUri;
}
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
Driver.Manage().Window.Maximize();
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation($"Selenium: Using {Driver.GetType()}");
TestLogs.LogInformation($"Selenium: Browsing to {ServerUri}");
TestLogs.LogInformation($"Selenium: Resolution {Driver.Manage().Window.Size}");
GoToRegister();
Driver.AssertNoError();
}
2021-12-31 08:59:02 +01:00
public void PayInvoice()
{
Driver.FindElement(By.Id("FakePayment")).Click();
}
/// <summary>
/// Use this ServerUri when trying to browse with selenium
/// Because for some reason, the selenium container can't resolve the tests container domain name
/// </summary>
public Uri ServerUri;
internal IWebElement FindAlertMessage(StatusMessageModel.StatusSeverity severity = StatusMessageModel.StatusSeverity.Success)
{
2021-12-31 08:59:02 +01:00
return FindAlertMessage(new[] { severity });
}
internal IWebElement FindAlertMessage(params StatusMessageModel.StatusSeverity[] severity)
{
var className = string.Join(", ", severity.Select(statusSeverity => $".alert-{StatusMessageModel.ToString(statusSeverity)}"));
2021-11-24 12:25:14 +01:00
IWebElement el;
try
{
var elements = Driver.FindElements(By.CssSelector(className));
el = elements.FirstOrDefault(e => e.Displayed);
if (el is null)
el = elements.FirstOrDefault();
if (el is null)
el = Driver.WaitForElement(By.CssSelector(className));
2021-11-24 12:25:14 +01:00
}
catch (NoSuchElementException)
{
el = Driver.WaitForElement(By.CssSelector(className));
}
if (el is null)
throw new NoSuchElementException($"Unable to find {className}");
if (!el.Displayed)
throw new ElementNotVisibleException($"{className} is present, but not displayed: {el.GetAttribute("id")} - Text: {el.Text}");
return el;
}
2019-05-14 16:33:46 +02:00
public string Link(string relativeLink)
{
return ServerUri.AbsoluteUri.WithoutEndingSlash() + relativeLink.WithStartingSlash();
2019-05-14 16:33:46 +02:00
}
public void GoToRegister()
{
Driver.Navigate().GoToUrl(Link("/register"));
}
public string RegisterNewUser(bool isAdmin = false)
{
var usr = RandomUtils.GetUInt256().ToString().Substring(64 - 20) + "@a.com";
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation($"User: {usr} with password 123456");
Driver.FindElement(By.Id("Email")).SendKeys(usr);
Driver.FindElement(By.Id("Password")).SendKeys("123456");
Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("123456");
2019-05-14 16:33:46 +02:00
if (isAdmin)
Driver.FindElement(By.Id("IsAdmin")).Click();
Driver.FindElement(By.Id("RegisterButton")).Click();
Driver.AssertNoError();
return usr;
}
2021-10-26 13:55:13 +02:00
public (string storeName, string storeId) CreateNewStore(bool keepId = true)
{
// If there's no store yet, there is no dropdown toggle
if (Driver.PageSource.Contains("id=\"StoreSelectorToggle\""))
{
Driver.FindElement(By.Id("StoreSelectorToggle")).Click();
}
Driver.WaitForElement(By.Id("StoreSelectorCreate")).Click();
var name = "Store" + RandomUtils.GetUInt64();
TestLogs.LogInformation($"Created store {name}");
Driver.WaitForElement(By.Id("Name")).SendKeys(name);
Driver.WaitForElement(By.Id("Create")).Click();
Driver.FindElement(By.Id("StoreNav-StoreSettings")).Click();
Driver.FindElement(By.Id($"SectionNav-{StoreNavPages.General.ToString()}")).Click();
2021-10-26 13:55:13 +02:00
var storeId = Driver.WaitForElement(By.Id("Id")).GetAttribute("value");
if (keepId)
StoreId = storeId;
return (name, storeId);
}
public Mnemonic GenerateWallet(string cryptoCode = "BTC", string seed = "", bool? importkeys = null, bool isHotWallet = false, ScriptPubKeyType format = ScriptPubKeyType.Segwit)
2019-12-05 18:56:40 +01:00
{
var isImport = !string.IsNullOrEmpty(seed);
GoToWalletSettings(cryptoCode);
2021-03-02 11:06:04 +01:00
// Replace previous wallet case
if (Driver.PageSource.Contains("id=\"ChangeWalletLink\""))
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
{
Driver.FindElement(By.Id("ActionsDropdownToggle")).Click();
Driver.WaitForElement(By.Id("ChangeWalletLink")).Click();
Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("REPLACE");
Driver.FindElement(By.Id("ConfirmContinue")).Click();
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
}
if (isImport)
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
{
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation("Progressing with existing seed");
Driver.FindElement(By.Id("ImportWalletOptionsLink")).Click();
Driver.FindElement(By.Id("ImportSeedLink")).Click();
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
Driver.FindElement(By.Id("ExistingMnemonic")).SendKeys(seed);
Driver.SetCheckbox(By.Id("SavePrivateKeys"), isHotWallet);
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
}
else
{
var option = isHotWallet ? "Hotwallet" : "Watchonly";
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation($"Generating new seed ({option})");
Driver.FindElement(By.Id("GenerateWalletLink")).Click();
Driver.FindElement(By.Id($"Generate{option}Link")).Click();
}
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
Driver.FindElement(By.Id("ScriptPubKeyType")).Click();
Driver.FindElement(By.CssSelector($"#ScriptPubKeyType option[value={format}]")).Click();
2021-12-31 08:59:02 +01:00
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
Driver.ToggleCollapse("AdvancedSettings");
if (importkeys is bool v)
Driver.SetCheckbox(By.Id("ImportKeysToRPC"), v);
Driver.FindElement(By.Id("Continue")).Click();
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
if (isImport)
2019-12-05 18:56:40 +01:00
{
// Confirm addresses
Driver.FindElement(By.Id("Confirm")).Click();
2019-12-05 18:56:40 +01:00
}
else
{
// Seed backup
FindAlertMessage();
if (string.IsNullOrEmpty(seed))
{
seed = Driver.FindElements(By.Id("RecoveryPhrase")).First().GetAttribute("data-mnemonic");
}
// Confirm seed backup
Driver.FindElement(By.Id("confirm")).Click();
Driver.FindElement(By.Id("submit")).Click();
}
2021-12-31 08:59:02 +01:00
2020-06-24 03:34:09 +02:00
WalletId = new WalletId(StoreId, cryptoCode);
return new Mnemonic(seed);
2019-12-05 18:56:40 +01:00
}
/// <summary>
/// Assume to be in store's settings
/// </summary>
/// <param name="cryptoCode"></param>
/// <param name="derivationScheme"></param>
public void AddDerivationScheme(string cryptoCode = "BTC", string derivationScheme = "xpub661MyMwAqRbcGABgHMUXDzPzH1tU7eZaAaJQXhDXsSxsqyQzQeU6kznNfSuAyqAK9UaWSaZaMFdNiY5BCF4zBPAzSnwfUAwUhwttuAKwfRX-[legacy]")
{
if (!Driver.PageSource.Contains($"Setup {cryptoCode} Wallet"))
{
GoToWalletSettings(cryptoCode);
}
Driver.FindElement(By.Id("ImportWalletOptionsLink")).Click();
Driver.FindElement(By.Id("ImportXpubLink")).Click();
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
Driver.FindElement(By.Id("DerivationScheme")).SendKeys(derivationScheme);
Driver.FindElement(By.Id("Continue")).Click();
2021-01-25 14:10:19 +01:00
Driver.FindElement(By.Id("Confirm")).Click();
FindAlertMessage();
}
2020-01-12 05:54:06 +01:00
public void AddLightningNode()
{
AddLightningNode(null, null, true);
}
public void AddLightningNode(LightningConnectionType? connectionType = null, bool test = true)
{
AddLightningNode(null, connectionType, test);
}
public void AddLightningNode(string cryptoCode = null, LightningConnectionType? connectionType = null, bool test = true)
{
cryptoCode ??= "BTC";
if (!Driver.PageSource.Contains("Connect to a Lightning node"))
{
GoToLightningSettings();
}
var connectionString = connectionType switch
{
LightningConnectionType.Charge =>
$"type=charge;server={Server.MerchantCharge.Client.Uri.AbsoluteUri};allowinsecure=true",
LightningConnectionType.CLightning =>
2021-12-31 08:59:02 +01:00
$"type=clightning;server={((CLightningClient)Server.MerchantLightningD).Address.AbsoluteUri}",
LightningConnectionType.LndREST =>
$"type=lnd-rest;server={Server.MerchantLnd.Swagger.BaseUrl};allowinsecure=true",
_ => null
};
if (connectionString == null)
{
Assert.True(Driver.FindElement(By.Id("LightningNodeType-Internal")).Enabled, "Usage of the internal Lightning node is disabled.");
Driver.FindElement(By.CssSelector("label[for=\"LightningNodeType-Internal\"]")).Click();
}
else
{
Driver.FindElement(By.CssSelector("label[for=\"LightningNodeType-Custom\"]")).Click();
Driver.WaitForElement(By.Id("ConnectionString")).Clear();
Driver.FindElement(By.Id("ConnectionString")).SendKeys(connectionString);
2021-10-26 13:55:13 +02:00
if (test)
{
Driver.FindElement(By.Id("test")).Click();
Assert.Contains("Connection to the Lightning node successful.", FindAlertMessage().Text);
}
2021-04-19 16:21:50 +02:00
}
2021-04-20 12:23:50 +02:00
Driver.FindElement(By.Id("save")).Click();
Assert.Contains($"{cryptoCode} Lightning node updated.", FindAlertMessage().Text);
2021-04-16 15:31:09 +02:00
var enabled = Driver.FindElement(By.Id($"{cryptoCode}LightningEnabled"));
if (enabled.Text == "Enable")
{
enabled.Click();
Assert.Contains($"{cryptoCode} Lightning payments are now enabled for this store.", FindAlertMessage().Text);
}
}
2021-11-22 09:16:08 +01:00
public Logging.ILog TestLogs => Server.TestLogs;
public void ClickOnAllSectionLinks()
{
var links = Driver.FindElements(By.CssSelector("#SectionNav .nav-link")).Select(c => c.GetAttribute("href")).ToList();
Driver.AssertNoError();
foreach (var l in links)
{
2021-11-22 09:16:08 +01:00
TestLogs.LogInformation($"Checking no error on {l}");
Driver.Navigate().GoToUrl(l);
Driver.AssertNoError();
}
}
public void Dispose()
{
if (Driver != null)
{
try
{
Driver.Quit();
}
2021-01-25 14:10:19 +01:00
catch
{
// ignored
}
Driver.Dispose();
}
2021-01-25 14:10:19 +01:00
Server?.Dispose();
}
2019-05-14 16:33:46 +02:00
internal void AssertNotFound()
{
2020-02-01 09:29:08 +01:00
Assert.Contains("404 - Page not found</h1>", Driver.PageSource);
2019-05-14 16:33:46 +02:00
}
internal void AssertAccessDenied()
{
2022-01-07 13:12:31 +01:00
Assert.Contains("- Denied</h", Driver.PageSource);
}
public void GoToHome()
2019-05-14 16:33:46 +02:00
{
Driver.Navigate().GoToUrl(ServerUri);
2019-05-14 16:33:46 +02:00
}
public void Logout()
2019-05-14 16:33:46 +02:00
{
2022-01-07 17:25:28 +01:00
Driver.FindElement(By.Id("Nav-Account")).Click();
Driver.FindElement(By.Id("Nav-Logout")).Click();
2019-05-14 16:33:46 +02:00
}
public void LogIn(string user, string password)
{
Driver.FindElement(By.Id("Email")).SendKeys(user);
Driver.FindElement(By.Id("Password")).SendKeys(password);
Driver.FindElement(By.Id("LoginButton")).Click();
}
public void GoToStore(StoreNavPages storeNavPage = StoreNavPages.General)
{
GoToStore(null, storeNavPage);
}
public void GoToStore(string storeId, StoreNavPages storeNavPage = StoreNavPages.General)
{
if (storeId is not null)
{
GoToUrl($"/stores/{storeId}/");
StoreId = storeId;
2022-02-17 09:58:56 +01:00
if (WalletId != null)
WalletId = new WalletId(storeId, WalletId.CryptoCode);
}
Driver.FindElement(By.Id("StoreNav-StoreSettings")).Click();
if (storeNavPage != StoreNavPages.General)
{
switch (storeNavPage)
{
case StoreNavPages.Dashboard:
case StoreNavPages.Payouts:
case StoreNavPages.PayButton:
case StoreNavPages.PullPayments:
Driver.FindElement(By.Id($"StoreNav-{storeNavPage.ToString()}")).Click();
break;
default:
Driver.FindElement(By.Id($"SectionNav-{storeNavPage.ToString()}")).Click();
break;
}
}
}
public void GoToWalletSettings(string cryptoCode = "BTC")
{
Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
if (Driver.PageSource.Contains("id=\"WalletNav-Settings\""))
{
Driver.FindElement(By.Id("WalletNav-Settings")).Click();
}
}
public void GoToLightningSettings(string cryptoCode = "BTC")
{
Driver.FindElement(By.Id($"StoreNav-Lightning{cryptoCode}")).Click();
// if Lightning is already set up we need to navigate to the settings
if (Driver.PageSource.Contains("id=\"SectionNav-LightningSettings\""))
{
Driver.FindElement(By.Id("SectionNav-LightningSettings")).Click();
}
}
public void SelectStoreContext(string storeId)
{
Driver.FindElement(By.Id("StoreSelectorToggle")).Click();
Driver.FindElement(By.Id($"StoreSelectorMenuItem-{storeId}")).Click();
}
2022-02-17 09:58:56 +01:00
public void GoToInvoiceCheckout(string invoiceId = null)
{
invoiceId ??= InvoiceId;
Driver.FindElement(By.Id("StoreNav-Invoices")).Click();
Driver.FindElement(By.Id($"invoice-checkout-{invoiceId}")).Click();
CheckForJSErrors();
}
2020-01-12 05:54:06 +01:00
public void GoToInvoice(string id)
{
GoToUrl($"/invoices/{id}/");
}
public void GoToInvoices(string storeId = null)
{
if (storeId is null)
{
Driver.FindElement(By.Id("StoreNav-Invoices")).Click();
}
else
{
GoToUrl(storeId == null ? "/invoices/" : $"/stores/{storeId}/invoices/");
StoreId = storeId;
}
}
2020-06-28 10:55:27 +02:00
public void GoToProfile(ManageNavPages navPages = ManageNavPages.Index)
{
Driver.FindElement(By.Id("Nav-Account")).Click();
2022-01-07 17:25:28 +01:00
Driver.FindElement(By.Id("Nav-ManageAccount")).Click();
if (navPages != ManageNavPages.Index)
{
Driver.FindElement(By.Id($"SectionNav-{navPages.ToString()}")).Click();
}
}
public void GoToLogin()
{
GoToUrl("/login");
}
public string CreateInvoice(decimal? amount = 100,
string currency = "USD",
string refundEmail = "",
string defaultPaymentMethod = null,
bool? requiresRefundEmail = null,
StatusMessageModel.StatusSeverity expectedSeverity = StatusMessageModel.StatusSeverity.Success
)
{
return CreateInvoice(null, amount, currency, refundEmail, defaultPaymentMethod, requiresRefundEmail, expectedSeverity);
}
2021-09-01 05:21:44 +02:00
public string CreateInvoice(
2021-12-31 08:59:02 +01:00
string storeId,
decimal? amount = 100,
string currency = "USD",
2021-09-01 05:21:44 +02:00
string refundEmail = "",
2021-10-26 13:55:13 +02:00
string defaultPaymentMethod = null,
bool? requiresRefundEmail = null,
2021-10-26 13:55:13 +02:00
StatusMessageModel.StatusSeverity expectedSeverity = StatusMessageModel.StatusSeverity.Success
2021-09-01 05:21:44 +02:00
)
{
GoToInvoices(storeId);
Driver.FindElement(By.Id("CreateNewInvoice")).Click();
2021-08-03 10:03:00 +02:00
if (amount is decimal v)
Driver.FindElement(By.Id("Amount")).SendKeys(v.ToString(CultureInfo.InvariantCulture));
var currencyEl = Driver.FindElement(By.Id("Currency"));
currencyEl.Clear();
currencyEl.SendKeys(currency);
Driver.FindElement(By.Id("BuyerEmail")).SendKeys(refundEmail);
2022-01-14 09:48:15 +01:00
if (defaultPaymentMethod is not null)
new SelectElement(Driver.FindElement(By.Name("DefaultPaymentMethod"))).SelectByValue(defaultPaymentMethod);
if (requiresRefundEmail is bool)
new SelectElement(Driver.FindElement(By.Name("RequiresRefundEmail"))).SelectByValue(requiresRefundEmail == true ? "1" : "2");
Driver.FindElement(By.Id("Create")).Click();
2021-10-26 13:55:13 +02:00
var statusElement = FindAlertMessage(expectedSeverity);
var inv = expectedSeverity == StatusMessageModel.StatusSeverity.Success ? statusElement.Text.Split(" ")[1] : null;
InvoiceId = inv;
TestLogs.LogInformation($"Created invoice {inv}");
return inv;
}
string InvoiceId;
2022-02-17 09:58:56 +01:00
public async Task<string> FundStoreWallet(WalletId walletId = null, int coins = 1, decimal denomination = 1m)
{
2020-06-24 03:34:09 +02:00
walletId ??= WalletId;
GoToWallet(walletId, WalletsNavPages.Receive);
Driver.FindElement(By.Id("generateButton")).Click();
var addressStr = Driver.FindElement(By.Id("address")).GetProperty("value");
var address = BitcoinAddress.Create(addressStr, ((BTCPayNetwork)Server.NetworkProvider.GetNetwork(walletId.CryptoCode)).NBitcoinNetwork);
for (var i = 0; i < coins; i++)
{
2022-02-17 09:58:56 +01:00
bool mined = false;
retry:
try
{
await Server.ExplorerNode.SendToAddressAsync(address, Money.Coins(denomination));
}
catch (RPCException) when (!mined)
{
mined = true;
await Server.ExplorerNode.GenerateAsync(1);
goto retry;
}
}
2022-02-17 09:58:56 +01:00
Driver.Navigate().Refresh();
return addressStr;
}
2020-06-28 10:55:27 +02:00
private void CheckForJSErrors()
{
//wait for seleniun update: https://stackoverflow.com/questions/57520296/selenium-webdriver-3-141-0-driver-manage-logs-availablelogtypes-throwing-syste
2021-04-19 16:21:50 +02:00
// var errorStrings = new List<string>
// {
// "SyntaxError",
// "EvalError",
// "ReferenceError",
// "RangeError",
// "TypeError",
// "URIError"
2020-01-12 05:54:06 +01:00
// };
//
// var jsErrors = Driver.Manage().Logs.GetLog(LogType.Browser).Where(x => errorStrings.Any(e => x.Message.Contains(e)));
//
// if (jsErrors.Any())
// {
2021-11-22 09:16:08 +01:00
// TestLogs.LogInformation("JavaScript error(s):" + Environment.NewLine + jsErrors.Aggregate("", (s, entry) => s + entry.Message + Environment.NewLine));
2020-01-12 05:54:06 +01:00
// }
// Assert.Empty(jsErrors);
}
2020-06-24 03:34:09 +02:00
public void GoToWallet(WalletId walletId = null, WalletsNavPages navPages = WalletsNavPages.Send)
{
2020-06-24 03:34:09 +02:00
walletId ??= WalletId;
Driver.Navigate().GoToUrl(new Uri(ServerUri, $"wallets/{walletId}"));
2022-02-18 02:55:54 +01:00
if (navPages == WalletsNavPages.PSBT)
{
Driver.FindElement(By.Id("WalletNav-Send")).Click();
Driver.FindElement(By.Id("PSBT")).Click();
}
else if (navPages != WalletsNavPages.Transactions)
{
Driver.FindElement(By.Id($"WalletNav-{navPages}")).Click();
}
}
2020-10-05 09:39:49 +02:00
public void GoToUrl(string relativeUrl)
{
Driver.Navigate().GoToUrl(new Uri(ServerUri, relativeUrl));
2020-10-05 09:39:49 +02:00
}
2021-04-19 16:21:50 +02:00
2020-09-16 08:54:09 +02:00
public void GoToServer(ServerNavPages navPages = ServerNavPages.Index)
{
Driver.FindElement(By.Id("Nav-ServerSettings")).Click();
2020-09-16 08:54:09 +02:00
if (navPages != ServerNavPages.Index)
{
Driver.FindElement(By.Id($"SectionNav-{navPages}")).Click();
2020-09-16 08:54:09 +02:00
}
}
}
}