btcpayserver/BTCPayServer.Tests/CheckoutUITests.cs

232 lines
9.7 KiB
C#
Raw Normal View History

using System;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
2020-02-19 09:39:14 +01:00
using BTCPayServer.Payments;
using BTCPayServer.Tests.Logging;
using BTCPayServer.Views.Stores;
2020-02-19 09:39:14 +01:00
using NBitcoin;
using OpenQA.Selenium;
using Xunit;
using Xunit.Abstractions;
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 CheckoutUITests : UnitTestBase
{
public const int TestTimeout = TestUtils.TestTimeout;
2021-11-22 09:16:08 +01:00
public CheckoutUITests(ITestOutputHelper helper) : base(helper)
{
}
2019-10-12 13:35:30 +02:00
[Fact(Timeout = TestTimeout)]
public async Task CanHandleRefundEmailForm()
{
2022-01-14 09:50:29 +01:00
using var s = CreateSeleniumTester();
await s.StartAsync();
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddDerivationScheme();
2022-01-14 09:50:29 +01:00
s.GoToStore(StoreNavPages.CheckoutAppearance);
s.Driver.FindElement(By.Id("RequiresRefundEmail")).Click();
Checkout v2 finetuning (#4276) * Indent all JSON files with two spaces * Upgrade Vue.js * Cheat mode improvements * Show payment details in case of expired invoice * Add logo size recommendation * Show clipboard copy hint cursor * Improve info area and wording * Update BIP21 wording * Invoice details adjustments * Remove form; switch payment methods via AJAX * UI updates * Decrease paddings to gain space * Tighten up padding between logo mark and the store title text * Add drop-shadow to the containers * Wording * Cheating improvements * Improve footer spacing * Cheating improvements * Display addresses * More improvements * Expire invoices * Customize invoice expiry * Footer improvements * Remove theme switch * Remove non-existing sourcemap references * Move inline JS to checkout.js file * Plugin compatibility See Kukks/btcpayserver#8 * Test fix * Upgrade vue-i18next * Extract translations into a separate file * Round QR code borders * Remove "Pay with Bitcoin" title in BIP21 case * Add copy hint to payment details * Cheating: Reduce margins * Adjust dt color * Hide addresses for first iteration * Improve View Details button * Make info section collapsible * Revert original en locale file * Checkout v2 tests * Result view link fixes * Fix BIP21 + lazy payment methods case * More result page link improvements * minor visual improvements * Update clipboard code Remove fallback for old browsers. https://caniuse.com/?search=navigator.clipboard * Transition copy symbol * Update info text color * Invert dark neutral colors Simplifies the dark theme quite a bit. * copy adjustments * updates QR border-radius * Add option to remove logo * More checkout v2 test cases * JS improvements * Remove leftovers * Update test * Fix links * Update tests * Update plugins integration * Remove obsolete url code * Minor view update * Update JS to not use arrow functions * Remove FormId from Checkout Appearance settings * Add English-only hint and feedback link * Checkout Appearance: Make options clearer, remove Custom CSS for v2 * Clipboard copy full URL instead of just address/BOLT11 * Upgrade JS libs, add content checks * Add test for BIP21 setting with zero amount invoice Co-authored-by: dstrukt <gfxdsign@gmail.com>
2022-11-24 00:53:32 +01:00
s.Driver.FindElement(By.Id("Save")).Click();
2022-01-14 09:50:29 +01:00
var emailAlreadyThereInvoiceId = s.CreateInvoice(100, "USD", "a@g.com");
s.GoToInvoiceCheckout(emailAlreadyThereInvoiceId);
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.GoToHome();
s.CreateInvoice();
s.Driver.FindElement(By.ClassName("invoice-checkout-link")).Click();
Assert.NotEmpty(s.Driver.FindElements(By.Id("checkoutCtrl")));
Assert.True(s.Driver.FindElement(By.Id("emailAddressFormInput")).Displayed);
s.Driver.FindElement(By.Id("emailAddressFormInput")).SendKeys("xxx");
s.Driver.FindElement(By.Id("emailAddressForm")).FindElement(By.CssSelector("button.action-button"))
.Click();
var formInput = s.Driver.FindElement(By.Id("emailAddressFormInput"));
Assert.True(formInput.Displayed);
Assert.Contains("form-input-invalid", formInput.GetAttribute("class"));
formInput = s.Driver.FindElement(By.Id("emailAddressFormInput"));
formInput.SendKeys("@g.com");
var actionButton = s.Driver.FindElement(By.Id("emailAddressForm")).FindElement(By.CssSelector("button.action-button"));
actionButton.Click();
try // Sometimes the click only take the focus, without actually really clicking on it...
{
2019-10-12 13:35:30 +02:00
actionButton.Click();
}
2022-01-14 09:50:29 +01:00
catch { }
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.Driver.Navigate().Refresh();
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
}
[Fact(Timeout = TestTimeout)]
public async Task CanHandleRefundEmailForm2()
{
2022-01-14 09:50:29 +01:00
using var s = CreateSeleniumTester();
// Prepare user account and store
await s.StartAsync();
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddDerivationScheme();
2022-01-14 09:50:29 +01:00
// Now create an invoice that requires a refund email
var invoice = s.CreateInvoice(100, "USD", "", null, true);
s.GoToInvoiceCheckout(invoice);
2022-01-14 09:50:29 +01:00
var emailInput = s.Driver.FindElement(By.Id("emailAddressFormInput"));
Assert.True(emailInput.Displayed);
2022-01-14 09:50:29 +01:00
emailInput.SendKeys("a@g.com");
2022-01-14 09:50:29 +01:00
var actionButton = s.Driver.FindElement(By.Id("emailAddressForm")).FindElement(By.CssSelector("button.action-button"));
actionButton.Click();
try // Sometimes the click only take the focus, without actually really clicking on it...
{
actionButton.Click();
}
2022-01-14 09:50:29 +01:00
catch { }
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.Driver.Navigate().Refresh();
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.GoToHome();
// Now create an invoice that doesn't require a refund email
s.CreateInvoice(100, "USD", "", null, false);
s.Driver.FindElement(By.ClassName("invoice-checkout-link")).Click();
Assert.NotEmpty(s.Driver.FindElements(By.Id("checkoutCtrl")));
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.Driver.Navigate().Refresh();
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.GoToHome();
// Now create an invoice that requires refund email but already has one set, email input shouldn't show up
s.CreateInvoice(100, "USD", "a@g.com", null, true);
s.Driver.FindElement(By.ClassName("invoice-checkout-link")).Click();
Assert.NotEmpty(s.Driver.FindElements(By.Id("checkoutCtrl")));
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
s.Driver.Navigate().Refresh();
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
}
2019-10-06 15:49:28 +02:00
[Fact(Timeout = TestTimeout)]
public async Task CanUseLanguageDropdown()
{
2022-01-14 09:50:29 +01:00
using var s = CreateSeleniumTester();
await s.StartAsync();
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddDerivationScheme();
2022-01-14 09:50:29 +01:00
var invoiceId = s.CreateInvoice();
s.GoToInvoiceCheckout(invoiceId);
Assert.True(s.Driver.FindElement(By.Id("DefaultLang")).FindElements(By.TagName("option")).Count > 1);
var payWithTextEnglish = s.Driver.FindElement(By.Id("pay-with-text")).Text;
var prettyDropdown = s.Driver.FindElement(By.Id("prettydropdown-DefaultLang"));
prettyDropdown.Click();
await Task.Delay(200);
prettyDropdown.FindElement(By.CssSelector("[data-value=\"da-DK\"]")).Click();
await Task.Delay(1000);
Assert.NotEqual(payWithTextEnglish, s.Driver.FindElement(By.Id("pay-with-text")).Text);
s.Driver.Navigate().GoToUrl(s.Driver.Url + "?lang=da-DK");
Assert.NotEqual(payWithTextEnglish, s.Driver.FindElement(By.Id("pay-with-text")).Text);
s.Driver.Quit();
}
2021-09-01 05:21:44 +02:00
[Fact(Timeout = TestTimeout)]
[Trait("Lightning", "Lightning")]
public async Task CanSetDefaultPaymentMethod()
{
2022-01-14 09:50:29 +01:00
using var s = CreateSeleniumTester();
s.Server.ActivateLightning();
await s.StartAsync();
s.GoToRegister();
s.RegisterNewUser(true);
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
2022-01-14 09:50:29 +01:00
s.AddLightningNode();
s.AddDerivationScheme();
2022-01-14 09:50:29 +01:00
var invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
s.GoToInvoiceCheckout(invoiceId);
2023-04-25 11:20:10 +02:00
Assert.Equal("Bitcoin (Lightning)", s.Driver.FindElement(By.ClassName("payment__currencies")).Text);
2022-01-14 09:50:29 +01:00
s.Driver.Quit();
2021-09-01 05:21:44 +02:00
}
2019-10-06 15:49:28 +02:00
[Fact(Timeout = TestTimeout)]
[Trait("Lightning", "Lightning")]
2019-10-07 09:04:25 +02:00
public async Task CanUseLightningSatsFeature()
{
2022-01-14 09:50:29 +01:00
using var s = CreateSeleniumTester();
s.Server.ActivateLightning();
await s.StartAsync();
s.GoToRegister();
s.RegisterNewUser(true);
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
2022-01-14 09:50:29 +01:00
s.AddLightningNode();
s.GoToLightningSettings();
2022-01-14 09:50:29 +01:00
s.Driver.SetCheckbox(By.Id("LightningAmountInSatoshi"), true);
s.Driver.FindElement(By.Id("save")).Click();
Assert.Contains("BTC Lightning settings successfully updated", s.FindAlertMessage().Text);
var invoiceId = s.CreateInvoice(10, "USD", "a@g.com");
s.GoToInvoiceCheckout(invoiceId);
2023-04-25 11:20:10 +02:00
Assert.Contains("sats", s.Driver.FindElement(By.ClassName("buyerTotalLine")).Text);
}
2020-02-19 09:39:14 +01:00
[Fact(Timeout = TestTimeout)]
public async Task CanUseJSModal()
{
2022-01-14 09:50:29 +01:00
using var s = CreateSeleniumTester();
await s.StartAsync();
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.GoToStore();
2022-01-14 09:50:29 +01:00
s.AddDerivationScheme();
var invoiceId = s.CreateInvoice(0.001m, "BTC", "a@x.com");
var invoice = await s.Server.PayTester.InvoiceRepository.GetInvoice(invoiceId);
s.Driver.Navigate()
.GoToUrl(new Uri(s.ServerUri, $"tests/index.html?invoice={invoiceId}"));
TestUtils.Eventually(() =>
2020-02-19 09:39:14 +01:00
{
2022-01-14 09:50:29 +01:00
Assert.True(s.Driver.FindElement(By.Name("btcpay")).Displayed);
});
await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(invoice
.GetPaymentMethod(new PaymentMethodId("BTC", PaymentTypes.BTCLike))
.GetPaymentMethodDetails().GetPaymentDestination(), Network.RegTest),
new Money(0.001m, MoneyUnit.BTC));
IWebElement closebutton = null;
TestUtils.Eventually(() =>
{
var frameElement = s.Driver.FindElement(By.Name("btcpay"));
var iframe = s.Driver.SwitchTo().Frame(frameElement);
closebutton = iframe.FindElement(By.ClassName("close-action"));
Assert.True(closebutton.Displayed);
});
closebutton.Click();
s.Driver.AssertElementNotFound(By.Name("btcpay"));
Assert.Equal(s.Driver.Url,
new Uri(s.ServerUri, $"tests/index.html?invoice={invoiceId}").ToString());
2020-02-19 09:39:14 +01:00
}
}
}