2019-09-10 10:03:24 +02:00
|
|
|
using System;
|
|
|
|
using System.Threading.Tasks;
|
2020-02-19 09:39:14 +01:00
|
|
|
using BTCPayServer.Payments;
|
2019-09-10 10:03:24 +02:00
|
|
|
using BTCPayServer.Tests.Logging;
|
|
|
|
using BTCPayServer.Views.Stores;
|
2020-02-19 09:39:14 +01:00
|
|
|
using NBitcoin;
|
2019-09-10 10:03:24 +02:00
|
|
|
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
|
2019-09-10 10:03:24 +02:00
|
|
|
{
|
2019-11-06 06:31:45 +01:00
|
|
|
public const int TestTimeout = TestUtils.TestTimeout;
|
2021-11-22 09:16:08 +01:00
|
|
|
public CheckoutUITests(ITestOutputHelper helper) : base(helper)
|
2019-09-10 10:03:24 +02:00
|
|
|
{
|
|
|
|
}
|
2019-09-11 09:22:41 +02:00
|
|
|
|
2019-10-12 13:35:30 +02:00
|
|
|
[Fact(Timeout = TestTimeout)]
|
2019-09-10 10:03:24 +02:00
|
|
|
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.AddDerivationScheme("BTC");
|
|
|
|
s.GoToStore(StoreNavPages.CheckoutAppearance);
|
|
|
|
s.Driver.FindElement(By.Id("RequiresRefundEmail")).Click();
|
|
|
|
s.Driver.FindElement(By.Name("command")).Click();
|
|
|
|
|
|
|
|
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-details-link")).Click();
|
|
|
|
s.Driver.AssertNoError();
|
|
|
|
s.Driver.Navigate().Back();
|
|
|
|
s.Driver.FindElement(By.ClassName("invoice-checkout-link")).Click();
|
|
|
|
Assert.NotEmpty(s.Driver.FindElements(By.Id("checkoutCtrl")));
|
|
|
|
|
|
|
|
Assert.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-09-11 09:22:41 +02:00
|
|
|
{
|
2019-10-12 13:35:30 +02:00
|
|
|
actionButton.Click();
|
2019-09-11 09:22:41 +02:00
|
|
|
}
|
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"));
|
2019-09-10 10:03:24 +02:00
|
|
|
}
|
|
|
|
|
2021-10-27 16:32:56 +02:00
|
|
|
[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.AddDerivationScheme("BTC");
|
2021-10-27 16:32:56 +02:00
|
|
|
|
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);
|
2021-10-27 16:32:56 +02:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
var emailInput = s.Driver.FindElement(By.Id("emailAddressFormInput"));
|
|
|
|
Assert.True(emailInput.Displayed);
|
2021-10-27 16:32:56 +02:00
|
|
|
|
2022-01-14 09:50:29 +01:00
|
|
|
emailInput.SendKeys("a@g.com");
|
2021-10-27 16:32:56 +02:00
|
|
|
|
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...
|
|
|
|
{
|
2021-10-27 16:32:56 +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"));
|
|
|
|
|
|
|
|
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-details-link")).Click();
|
|
|
|
s.Driver.AssertNoError();
|
|
|
|
s.Driver.Navigate().Back();
|
|
|
|
s.Driver.FindElement(By.ClassName("invoice-checkout-link")).Click();
|
|
|
|
Assert.NotEmpty(s.Driver.FindElements(By.Id("checkoutCtrl")));
|
|
|
|
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-details-link")).Click();
|
|
|
|
s.Driver.AssertNoError();
|
|
|
|
s.Driver.Navigate().Back();
|
|
|
|
s.Driver.FindElement(By.ClassName("invoice-checkout-link")).Click();
|
|
|
|
Assert.NotEmpty(s.Driver.FindElements(By.Id("checkoutCtrl")));
|
|
|
|
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
|
|
|
|
s.Driver.Navigate().Refresh();
|
|
|
|
s.Driver.AssertElementNotFound(By.Id("emailAddressFormInput"));
|
2021-10-27 16:32:56 +02:00
|
|
|
}
|
|
|
|
|
2019-10-06 15:49:28 +02:00
|
|
|
[Fact(Timeout = TestTimeout)]
|
2019-09-10 10:03:24 +02:00
|
|
|
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.AddDerivationScheme("BTC");
|
|
|
|
|
|
|
|
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();
|
2019-09-10 10:03:24 +02:00
|
|
|
}
|
2020-03-02 05:38:40 +01:00
|
|
|
|
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.AddLightningNode();
|
|
|
|
s.AddDerivationScheme("BTC");
|
|
|
|
|
|
|
|
var invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
|
|
|
|
s.GoToInvoiceCheckout(invoiceId);
|
|
|
|
|
|
|
|
Assert.Equal("Bitcoin (Lightning) (BTC)", s.Driver.FindElement(By.ClassName("payment__currencies")).Text);
|
|
|
|
s.Driver.Quit();
|
2021-09-01 05:21:44 +02:00
|
|
|
}
|
|
|
|
|
2019-10-06 15:49:28 +02:00
|
|
|
[Fact(Timeout = TestTimeout)]
|
2019-12-24 10:11:21 +01:00
|
|
|
[Trait("Lightning", "Lightning")]
|
2019-10-07 09:04:25 +02:00
|
|
|
public async Task CanUseLightningSatsFeature()
|
2019-09-10 10:03:24 +02:00
|
|
|
{
|
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.AddLightningNode();
|
2022-01-18 02:19:27 +01:00
|
|
|
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);
|
|
|
|
Assert.Contains("Sats", s.Driver.FindElement(By.ClassName("payment__currencies_noborder")).Text);
|
2019-09-10 10:03:24 +02:00
|
|
|
}
|
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();
|
2022-01-20 12:52:31 +01:00
|
|
|
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
|
|
|
}
|
2019-09-10 10:03:24 +02:00
|
|
|
}
|
|
|
|
}
|