mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 05:54:26 +01:00
(Refactor) : Converted Selenium test for CanCreateStores and Others to playwright (#6938)
* refactor : resolved merge conflicts Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> * (Refactor): Removed Selenium Test for CanCreateStores Signed-off-by: Abhijay jain <Abhijay007j@gmail.com> * (Test):Converted/Added Playwright Test for CanUseCoinSelection Signed-off-by: Abhijay jain <Abhijay007j@gmail.com> * (Refactor): Removed Selenium Test for CanUseCoinSelection Signed-off-by: Abhijay jain <Abhijay007j@gmail.com> * refactor: resolved merge conflicts Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> * refactor: resolved merge conflicts Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> * refactor : resolved minor issues Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> * refactor : updated tests Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> * refactor: updated test Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> * refactor: addressed requested changes Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> * refactor: addressed requested changes Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> --------- Signed-off-by: Abhijay007 <Abhijay007j@gmail.com> Signed-off-by: Abhijay jain <Abhijay007j@gmail.com>
This commit is contained in:
@@ -2335,8 +2335,7 @@ namespace BTCPayServer.Tests
|
||||
foreach (var path in storeSettingsPaths)
|
||||
{ // should have view access to settings, but no submit buttons or create links
|
||||
s.TestLogs.LogInformation($"Checking access to store page {path} as manager");
|
||||
await s.AssertPageAccess(true, $"/stores/{storeId}/{path}");
|
||||
await s.Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
||||
await s.AssertPageAccess(true, $"stores/{storeId}/{path}");
|
||||
Assert.False(await s.Page.GetByRole(AriaRole.Button, new() { Name = "Save" }).IsVisibleAsync());
|
||||
}
|
||||
await s.Logout();
|
||||
@@ -2438,6 +2437,245 @@ namespace BTCPayServer.Tests
|
||||
Assert.False(string.IsNullOrEmpty(pairingCode2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Lightning", "Lightning")]
|
||||
public async Task CanCreateStores()
|
||||
{
|
||||
await using var s = CreatePlaywrightTester();
|
||||
s.Server.ActivateLightning();
|
||||
await s.StartAsync();
|
||||
var alice = await s.RegisterNewUser(true);
|
||||
var (storeName, storeId) = await s.CreateNewStore();
|
||||
var storeUrl = $"/stores/{storeId}";
|
||||
|
||||
await s.GoToStore(storeId);
|
||||
Assert.Contains(storeName, await s.Page.ContentAsync());
|
||||
Assert.DoesNotContain("id=\"Dashboard\"", await s.Page.ContentAsync());
|
||||
|
||||
// verify steps for wallet setup are displayed correctly
|
||||
await s.GoToStore(storeId, StoreNavPages.Dashboard);
|
||||
await s.Page.WaitForSelectorAsync("#SetupGuide-StoreDone");
|
||||
await s.Page.WaitForSelectorAsync("#SetupGuide-Wallet");
|
||||
await s.Page.WaitForSelectorAsync("#SetupGuide-Lightning");
|
||||
|
||||
// setup onchain wallet
|
||||
await s.Page.Locator("#SetupGuide-Wallet").ClickAsync();
|
||||
await s.AddDerivationScheme();
|
||||
await s.Page.AssertNoError();
|
||||
|
||||
await s.GoToStore(storeId, StoreNavPages.Dashboard);
|
||||
await s.Page.WaitForSelectorAsync("#Dashboard");
|
||||
Assert.DoesNotContain("id=\"SetupGuide\"", await s.Page.ContentAsync());
|
||||
|
||||
// setup offchain wallet
|
||||
await s.Page.Locator("#menu-item-LightningSettings-BTC").ClickAsync();
|
||||
await s.AddLightningNode();
|
||||
await s.Page.AssertNoError();
|
||||
await s.FindAlertMessage(partialText: "BTC Lightning node updated.");
|
||||
|
||||
// Only click on section links if they exist
|
||||
if (await s.Page.Locator("#SectionNav .nav-link").CountAsync() > 0)
|
||||
{
|
||||
await s.ClickOnAllSectionLinks();
|
||||
}
|
||||
|
||||
await s.GoToInvoices(storeId);
|
||||
Assert.Contains("There are no invoices matching your criteria.", await s.Page.ContentAsync());
|
||||
var invoiceId = await s.CreateInvoice(storeId);
|
||||
await s.FindAlertMessage();
|
||||
|
||||
var invoiceUrl = s.Page.Url;
|
||||
|
||||
//let's test archiving an invoice
|
||||
Assert.DoesNotContain("Archived", await s.Page.Locator("#btn-archive-toggle").InnerTextAsync());
|
||||
await s.Page.Locator("#btn-archive-toggle").ClickAsync();
|
||||
Assert.Contains("Unarchive", await s.Page.Locator("#btn-archive-toggle").InnerTextAsync());
|
||||
|
||||
//check that it no longer appears in list
|
||||
await s.GoToInvoices(storeId);
|
||||
Assert.DoesNotContain(invoiceId, await s.Page.ContentAsync());
|
||||
|
||||
//ok, let's unarchive and see that it shows again
|
||||
await s.Page.GotoAsync(invoiceUrl);
|
||||
await s.Page.Locator("#btn-archive-toggle").ClickAsync();
|
||||
await s.FindAlertMessage();
|
||||
Assert.DoesNotContain("Unarchive", await s.Page.Locator("#btn-archive-toggle").InnerTextAsync());
|
||||
await s.GoToInvoices(storeId);
|
||||
Assert.Contains(invoiceId, await s.Page.ContentAsync());
|
||||
|
||||
// archive via list
|
||||
await s.Page.Locator($".mass-action-select[value=\"{invoiceId}\"]").ClickAsync();
|
||||
await s.Page.Locator("#ArchiveSelected").ClickAsync();
|
||||
Assert.Contains("1 invoice archived", await (await s.FindAlertMessage()).InnerTextAsync());
|
||||
Assert.DoesNotContain(invoiceId, await s.Page.ContentAsync());
|
||||
|
||||
// unarchive via list
|
||||
await s.Page.Locator("#StatusOptionsToggle").ClickAsync();
|
||||
await s.Page.Locator("#StatusOptionsIncludeArchived").ClickAsync();
|
||||
Assert.Contains(invoiceId, await s.Page.ContentAsync());
|
||||
await s.Page.Locator($".mass-action-select[value=\"{invoiceId}\"]").ClickAsync();
|
||||
await s.Page.Locator("#UnarchiveSelected").ClickAsync();
|
||||
Assert.Contains("1 invoice unarchived", await (await s.FindAlertMessage()).InnerTextAsync());
|
||||
Assert.Contains(invoiceId, await s.Page.ContentAsync());
|
||||
|
||||
// When logout out we should not be able to access store and invoice details
|
||||
await s.GoToUrl("/account");
|
||||
await s.Logout();
|
||||
await s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Page.Url);
|
||||
await s.Page.GotoAsync(invoiceUrl);
|
||||
Assert.Contains("ReturnUrl", s.Page.Url);
|
||||
await s.GoToRegister();
|
||||
|
||||
// When logged in as different user we should not be able to access store and invoice details
|
||||
var bob = await s.RegisterNewUser();
|
||||
await s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Page.Url);
|
||||
await s.Page.GotoAsync(invoiceUrl);
|
||||
Assert.Contains("ReturnUrl", s.Page.Url);
|
||||
// s.AssertAccessDenied(); // TODO: Playwright equivalent if needed
|
||||
await s.GoToUrl("/account");
|
||||
await s.Logout();
|
||||
|
||||
// Let's add Bob as an employee to alice's store
|
||||
await s.LogIn(alice);
|
||||
await s.AddUserToStore(storeId, bob, "Employee");
|
||||
await s.Logout();
|
||||
|
||||
// Bob should not have access to store, but should have access to invoice
|
||||
await s.LogIn(bob);
|
||||
await s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Page.Url);
|
||||
await s.GoToUrl(invoiceUrl);
|
||||
await s.Page.AssertNoError();
|
||||
await s.GoToUrl("/account");
|
||||
await s.Logout();
|
||||
await s.LogIn(alice);
|
||||
|
||||
// Check if we can enable the payment button
|
||||
await s.GoToStore(storeId, StoreNavPages.PayButton);
|
||||
await s.Page.Locator("#enable-pay-button").ClickAsync();
|
||||
await s.Page.Locator("#disable-pay-button").ClickAsync();
|
||||
await s.FindAlertMessage();
|
||||
await s.GoToStore(storeId);
|
||||
Assert.False(await s.Page.Locator("#AnyoneCanCreateInvoice").IsCheckedAsync());
|
||||
await s.Page.Locator("#AnyoneCanCreateInvoice").CheckAsync();
|
||||
await s.ClickPagePrimary();
|
||||
await s.FindAlertMessage();
|
||||
Assert.True(await s.Page.Locator("#AnyoneCanCreateInvoice").IsCheckedAsync());
|
||||
|
||||
// Store settings: Set and unset brand color
|
||||
await s.GoToStore(storeId);
|
||||
await s.Page.Locator("#BrandColor").FillAsync("#f7931a");
|
||||
await s.ClickPagePrimary();
|
||||
Assert.Contains("Store successfully updated", await (await s.FindAlertMessage()).InnerTextAsync());
|
||||
Assert.Equal("#f7931a", await s.Page.Locator("#BrandColor").InputValueAsync());
|
||||
await s.Page.Locator("#BrandColor").FillAsync("");
|
||||
await s.ClickPagePrimary();
|
||||
Assert.Contains("Store successfully updated", await (await s.FindAlertMessage()).InnerTextAsync());
|
||||
Assert.Equal(string.Empty, await s.Page.Locator("#BrandColor").InputValueAsync());
|
||||
|
||||
// Alice should be able to delete the store
|
||||
await s.GoToStore(storeId);
|
||||
await s.Page.Locator("#DeleteStore").ClickAsync();
|
||||
await s.Page.Locator("#ConfirmInput").FillAsync("DELETE");
|
||||
await s.Page.Locator("#ConfirmContinue").ClickAsync();
|
||||
await s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Page.Url);
|
||||
|
||||
// Archive store
|
||||
(storeName, storeId) = await s.CreateNewStore();
|
||||
|
||||
await s.Page.Locator("#StoreSelectorToggle").ClickAsync();
|
||||
Assert.Contains(storeName, await s.Page.Locator("#StoreSelectorMenu").InnerTextAsync());
|
||||
await s.Page.Locator($"#StoreSelectorMenuItem-{storeId}").ClickAsync();
|
||||
await s.GoToStore(storeId);
|
||||
await s.Page.Locator("#btn-archive-toggle").ClickAsync();
|
||||
Assert.Contains("The store has been archived and will no longer appear in the stores list by default.", await (await s.FindAlertMessage()).InnerTextAsync());
|
||||
|
||||
await s.Page.Locator("#StoreSelectorToggle").ClickAsync();
|
||||
Assert.DoesNotContain(storeName, await s.Page.Locator("#StoreSelectorMenu").InnerTextAsync());
|
||||
Assert.Contains("1 Archived Store", await s.Page.Locator("#StoreSelectorMenu").InnerTextAsync());
|
||||
await s.Page.Locator("#StoreSelectorArchived").ClickAsync();
|
||||
|
||||
var storeLink = s.Page.Locator($"#Store-{storeId}");
|
||||
Assert.Contains(storeName, await storeLink.InnerTextAsync());
|
||||
await s.GoToStore(storeId);
|
||||
await s.Page.Locator("#btn-archive-toggle").ClickAsync();
|
||||
Assert.Contains("The store has been unarchived and will appear in the stores list by default again.", await (await s.FindAlertMessage()).InnerTextAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanUseCoinSelection()
|
||||
{
|
||||
await using var s = CreatePlaywrightTester();
|
||||
await s.StartAsync();
|
||||
await s.RegisterNewUser(true);
|
||||
var (_, storeId) = await s.CreateNewStore();
|
||||
await s.GenerateWallet("BTC", "", false, true);
|
||||
var walletId = new WalletId(storeId, "BTC");
|
||||
await s.GoToWallet(walletId, WalletsNavPages.Receive);
|
||||
var addressStr = await s.Page.Locator("#Address").GetAttributeAsync("data-text");
|
||||
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 handlers = s.Server.PayTester.GetService<PaymentMethodHandlerDictionary>();
|
||||
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)));
|
||||
var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(walletId.CryptoCode);
|
||||
await TestUtils.EventuallyAsync(async () =>
|
||||
{
|
||||
var store = await s.Server.PayTester.StoreRepository.FindStore(storeId);
|
||||
var x = store.GetPaymentMethodConfig<DerivationSchemeSettings>(pmi, handlers);
|
||||
var wallet = s.Server.PayTester.GetService<BTCPayWalletProvider>().GetWallet(walletId.CryptoCode);
|
||||
wallet.InvalidateCache(x.AccountDerivation);
|
||||
Assert.Contains(
|
||||
await wallet.GetUnspentCoins(x.AccountDerivation),
|
||||
coin => coin.OutPoint == spentOutpoint);
|
||||
});
|
||||
await s.Server.ExplorerNode.GenerateAsync(1);
|
||||
await s.GoToWallet(walletId, WalletsNavPages.Send);
|
||||
await s.Page.Locator("#toggleInputSelection").ClickAsync();
|
||||
await s.Page.Locator($"[id='{spentOutpoint}']").WaitForAsync();
|
||||
Assert.Equal("true", (await s.Page.Locator("[name='InputSelection']").InputValueAsync()).ToLowerInvariant());
|
||||
|
||||
// Select All test
|
||||
await s.Page.Locator("#select-all-checkbox").ClickAsync();
|
||||
var selectedOptions = await s.Page.Locator("[name='SelectedInputs'] option[selected]").AllAsync();
|
||||
var listItems = await s.Page.Locator("li.list-group-item").AllAsync();
|
||||
Assert.Equal(listItems.Count, selectedOptions.Count);
|
||||
await s.Page.Locator("#select-all-checkbox").ClickAsync();
|
||||
selectedOptions = await s.Page.Locator("[name='SelectedInputs'] option[selected]").AllAsync();
|
||||
Assert.Empty(selectedOptions);
|
||||
|
||||
await s.Page.Locator($"[id='{spentOutpoint}']").ClickAsync();
|
||||
selectedOptions = await s.Page.Locator("[name='SelectedInputs'] option[selected]").AllAsync();
|
||||
Assert.Single(selectedOptions);
|
||||
|
||||
var bob = new NBitcoin.Key().PubKey.Hash.GetAddress(NBitcoin.Network.RegTest);
|
||||
await s.Page.Locator("[name='Outputs[0].DestinationAddress']").FillAsync(bob.ToString());
|
||||
var amountInput = s.Page.Locator("[name='Outputs[0].Amount']");
|
||||
await amountInput.FillAsync("0.3");
|
||||
var checkboxElement = s.Page.Locator("input[type='checkbox'][name='Outputs[0].SubtractFeesFromOutput']");
|
||||
if (!await checkboxElement.IsCheckedAsync())
|
||||
{
|
||||
await checkboxElement.ClickAsync();
|
||||
}
|
||||
await s.Page.Locator("#SignTransaction").ClickAsync();
|
||||
await s.Page.Locator("button[value='broadcast']").ClickAsync();
|
||||
var happyElement = await s.FindAlertMessage();
|
||||
var happyText = await happyElement.InnerTextAsync();
|
||||
var txid = System.Text.RegularExpressions.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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,168 +134,6 @@ namespace BTCPayServer.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Lightning", "Lightning")]
|
||||
public async Task CanCreateStores()
|
||||
{
|
||||
using var s = CreateSeleniumTester();
|
||||
s.Server.ActivateLightning();
|
||||
await s.StartAsync();
|
||||
var alice = s.RegisterNewUser(true);
|
||||
(string storeName, string storeId) = s.CreateNewStore();
|
||||
var storeUrl = $"/stores/{storeId}";
|
||||
|
||||
s.GoToStore();
|
||||
Assert.Contains(storeName, s.Driver.PageSource);
|
||||
Assert.DoesNotContain("id=\"Dashboard\"", s.Driver.PageSource);
|
||||
|
||||
// verify steps for wallet setup are displayed correctly
|
||||
s.GoToStore(StoreNavPages.Dashboard);
|
||||
Assert.True(s.Driver.FindElement(By.Id("SetupGuide-StoreDone")).Displayed);
|
||||
Assert.True(s.Driver.FindElement(By.Id("SetupGuide-Wallet")).Displayed);
|
||||
Assert.True(s.Driver.FindElement(By.Id("SetupGuide-Lightning")).Displayed);
|
||||
|
||||
// setup onchain wallet
|
||||
s.Driver.FindElement(By.Id("SetupGuide-Wallet")).Click();
|
||||
s.AddDerivationScheme();
|
||||
s.Driver.AssertNoError();
|
||||
|
||||
s.GoToStore(StoreNavPages.Dashboard);
|
||||
Assert.DoesNotContain("id=\"SetupGuide\"", s.Driver.PageSource);
|
||||
Assert.True(s.Driver.FindElement(By.Id("Dashboard")).Displayed);
|
||||
|
||||
// setup offchain wallet
|
||||
s.Driver.FindElement(By.CssSelector("[data-testid='Lightning-BTC']")).Click();
|
||||
s.AddLightningNode();
|
||||
s.Driver.AssertNoError();
|
||||
var successAlert = s.FindAlertMessage();
|
||||
Assert.Contains("BTC Lightning node updated.", successAlert.Text);
|
||||
|
||||
s.ClickOnAllSectionLinks();
|
||||
|
||||
s.GoToInvoices();
|
||||
Assert.Contains("There are no invoices matching your criteria.", s.Driver.PageSource);
|
||||
var invoiceId = s.CreateInvoice();
|
||||
s.FindAlertMessage();
|
||||
|
||||
var invoiceUrl = s.Driver.Url;
|
||||
|
||||
//let's test archiving an invoice
|
||||
Assert.DoesNotContain("Archived", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
|
||||
s.Driver.FindElement(By.Id("btn-archive-toggle")).Click();
|
||||
Assert.Contains("Unarchive", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
|
||||
|
||||
//check that it no longer appears in list
|
||||
s.GoToInvoices();
|
||||
Assert.DoesNotContain(invoiceId, s.Driver.PageSource);
|
||||
|
||||
//ok, let's unarchive and see that it shows again
|
||||
s.Driver.Navigate().GoToUrl(invoiceUrl);
|
||||
s.Driver.FindElement(By.Id("btn-archive-toggle")).Click();
|
||||
s.FindAlertMessage();
|
||||
Assert.DoesNotContain("Unarchive", s.Driver.FindElement(By.Id("btn-archive-toggle")).Text);
|
||||
s.GoToInvoices();
|
||||
Assert.Contains(invoiceId, s.Driver.PageSource);
|
||||
|
||||
// archive via list
|
||||
s.Driver.FindElement(By.CssSelector($".mass-action-select[value=\"{invoiceId}\"]")).Click();
|
||||
s.Driver.FindElement(By.Id("ArchiveSelected")).Click();
|
||||
Assert.Contains("1 invoice archived", s.FindAlertMessage().Text);
|
||||
Assert.DoesNotContain(invoiceId, s.Driver.PageSource);
|
||||
|
||||
// unarchive via list
|
||||
s.Driver.FindElement(By.Id("StatusOptionsToggle")).Click();
|
||||
s.Driver.FindElement(By.Id("StatusOptionsIncludeArchived")).Click();
|
||||
Assert.Contains(invoiceId, s.Driver.PageSource);
|
||||
s.Driver.FindElement(By.CssSelector($".mass-action-select[value=\"{invoiceId}\"]")).Click();
|
||||
s.Driver.FindElement(By.Id("UnarchiveSelected")).Click();
|
||||
Assert.Contains("1 invoice unarchived", s.FindAlertMessage().Text);
|
||||
Assert.Contains(invoiceId, s.Driver.PageSource);
|
||||
|
||||
// When logout out we should not be able to access store and invoice details
|
||||
s.Logout();
|
||||
s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
s.Driver.Navigate().GoToUrl(invoiceUrl);
|
||||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
s.GoToRegister();
|
||||
|
||||
// When logged in as different user we should not be able to access store and invoice details
|
||||
var bob = s.RegisterNewUser();
|
||||
s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
s.Driver.Navigate().GoToUrl(invoiceUrl);
|
||||
s.AssertAccessDenied();
|
||||
s.GoToHome();
|
||||
s.Logout();
|
||||
|
||||
// Let's add Bob as an employee to alice's store
|
||||
s.LogIn(alice);
|
||||
s.AddUserToStore(storeId, bob, "Employee");
|
||||
s.Logout();
|
||||
|
||||
// Bob should not have access to store, but should have access to invoice
|
||||
s.LogIn(bob);
|
||||
s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
s.GoToUrl(invoiceUrl);
|
||||
s.Driver.AssertNoError();
|
||||
|
||||
s.Logout();
|
||||
s.LogIn(alice);
|
||||
|
||||
// Check if we can enable the payment button
|
||||
s.GoToStore(StoreNavPages.PayButton);
|
||||
s.Driver.FindElement(By.Id("enable-pay-button")).Click();
|
||||
s.Driver.FindElement(By.Id("disable-pay-button")).Click();
|
||||
s.FindAlertMessage();
|
||||
s.GoToStore();
|
||||
Assert.False(s.Driver.FindElement(By.Id("AnyoneCanCreateInvoice")).Selected);
|
||||
s.Driver.SetCheckbox(By.Id("AnyoneCanCreateInvoice"), true);
|
||||
s.ClickPagePrimary();
|
||||
s.FindAlertMessage();
|
||||
Assert.True(s.Driver.FindElement(By.Id("AnyoneCanCreateInvoice")).Selected);
|
||||
|
||||
// Store settings: Set and unset brand color
|
||||
s.GoToStore();
|
||||
s.Driver.FindElement(By.Id("BrandColor")).SendKeys("#f7931a");
|
||||
s.ClickPagePrimary();
|
||||
Assert.Contains("Store successfully updated", s.FindAlertMessage().Text);
|
||||
Assert.Equal("#f7931a", s.Driver.FindElement(By.Id("BrandColor")).GetAttribute("value"));
|
||||
s.Driver.FindElement(By.Id("BrandColor")).Clear();
|
||||
s.ClickPagePrimary();
|
||||
Assert.Contains("Store successfully updated", s.FindAlertMessage().Text);
|
||||
Assert.Equal(string.Empty, s.Driver.FindElement(By.Id("BrandColor")).GetAttribute("value"));
|
||||
|
||||
// Alice should be able to delete the store
|
||||
s.GoToStore();
|
||||
s.Driver.FindElement(By.Id("DeleteStore")).Click();
|
||||
s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DELETE");
|
||||
s.Driver.FindElement(By.Id("ConfirmContinue")).Click();
|
||||
s.GoToUrl(storeUrl);
|
||||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
|
||||
// Archive store
|
||||
(storeName, storeId) = s.CreateNewStore();
|
||||
|
||||
s.Driver.FindElement(By.Id("StoreSelectorToggle")).Click();
|
||||
Assert.Contains(storeName, s.Driver.FindElement(By.Id("StoreSelectorMenu")).Text);
|
||||
s.Driver.FindElement(By.Id($"StoreSelectorMenuItem-{storeId}")).Click();
|
||||
s.GoToStore();
|
||||
s.Driver.FindElement(By.Id("btn-archive-toggle")).Click();
|
||||
Assert.Contains("The store has been archived and will no longer appear in the stores list by default.", s.FindAlertMessage().Text);
|
||||
|
||||
s.Driver.FindElement(By.Id("StoreSelectorToggle")).Click();
|
||||
Assert.DoesNotContain(storeName, s.Driver.FindElement(By.Id("StoreSelectorMenu")).Text);
|
||||
Assert.Contains("1 Archived Store", s.Driver.FindElement(By.Id("StoreSelectorMenu")).Text);
|
||||
s.Driver.FindElement(By.Id("StoreSelectorArchived")).Click();
|
||||
|
||||
var storeLink = s.Driver.FindElement(By.Id($"Store-{storeId}"));
|
||||
Assert.Contains(storeName, storeLink.Text);
|
||||
s.GoToStore(storeId);
|
||||
s.Driver.FindElement(By.Id("btn-archive-toggle")).Click();
|
||||
Assert.Contains("The store has been unarchived and will appear in the stores list by default again.", s.FindAlertMessage().Text);
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
public async Task CanCreateAppPoS()
|
||||
@@ -702,83 +540,6 @@ namespace BTCPayServer.Tests
|
||||
s.Driver.SwitchTo().Window(s.Driver.WindowHandles[0]);
|
||||
Assert.Equal("Settled", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text);
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
public async Task CanUseCoinSelection()
|
||||
{
|
||||
using var s = CreateSeleniumTester();
|
||||
await s.StartAsync();
|
||||
s.RegisterNewUser(true);
|
||||
(_, string storeId) = s.CreateNewStore();
|
||||
s.GenerateWallet("BTC", "", false, true);
|
||||
var walletId = new WalletId(storeId, "BTC");
|
||||
s.GoToWallet(walletId, WalletsNavPages.Receive);
|
||||
var addressStr = s.Driver.FindElement(By.Id("Address")).GetAttribute("data-text");
|
||||
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 handlers = s.Server.PayTester.GetService<PaymentMethodHandlerDictionary>();
|
||||
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)));
|
||||
var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(walletId.CryptoCode);
|
||||
await TestUtils.EventuallyAsync(async () =>
|
||||
{
|
||||
var store = await s.Server.PayTester.StoreRepository.FindStore(storeId);
|
||||
var x = store.GetPaymentMethodConfig<DerivationSchemeSettings>(pmi, handlers);
|
||||
var wallet = s.Server.PayTester.GetService<BTCPayWalletProvider>().GetWallet(walletId.CryptoCode);
|
||||
wallet.InvalidateCache(x.AccountDerivation);
|
||||
Assert.Contains(
|
||||
await wallet.GetUnspentCoins(x.AccountDerivation),
|
||||
coin => coin.OutPoint == spentOutpoint);
|
||||
});
|
||||
await s.Server.ExplorerNode.GenerateAsync(1);
|
||||
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());
|
||||
|
||||
//Select All test
|
||||
s.Driver.WaitForAndClick(By.Id("select-all-checkbox"));
|
||||
var inputSelectionSelectAll = s.Driver.FindElement(By.Name("SelectedInputs"));
|
||||
TestUtils.Eventually(() => {
|
||||
var selectedOptions = inputSelectionSelectAll.FindElements(By.CssSelector("option[selected]"));
|
||||
var listItems = s.Driver.FindElements(By.CssSelector("li.list-group-item"));
|
||||
Assert.Equal(listItems.Count, selectedOptions.Count);
|
||||
});
|
||||
s.Driver.WaitForAndClick(By.Id("select-all-checkbox"));
|
||||
TestUtils.Eventually(() => {
|
||||
var selectedOptions = inputSelectionSelectAll.FindElements(By.CssSelector("option[selected]"));
|
||||
Assert.Empty(selectedOptions);
|
||||
});
|
||||
|
||||
s.Driver.FindElement(By.Id(spentOutpoint.ToString()));
|
||||
s.Driver.FindElement(By.Id(spentOutpoint.ToString())).Click();
|
||||
var inputSelectionSelect = s.Driver.FindElement(By.Name("SelectedInputs"));
|
||||
Assert.Single(inputSelectionSelect.FindElements(By.CssSelector("[selected]")));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Selenium", "Selenium")]
|
||||
[Trait("Lightning", "Lightning")]
|
||||
|
||||
Reference in New Issue
Block a user