(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:
Abhijay Jain
2025-11-11 06:56:45 +05:30
committed by GitHub
parent 999bd4db41
commit 2ca06c6614
3 changed files with 241 additions and 242 deletions

View File

@@ -323,7 +323,7 @@ namespace BTCPayServer.Tests
await GoToUrl("/login"); await GoToUrl("/login");
} }
public async Task Logout() public async Task Logout()
{ {
await Page.Locator("#menu-item-Account").ClickAsync(); await Page.Locator("#menu-item-Account").ClickAsync();
await Page.Locator("#Nav-Logout").ClickAsync(); await Page.Locator("#Nav-Logout").ClickAsync();
} }

View File

@@ -2335,8 +2335,7 @@ namespace BTCPayServer.Tests
foreach (var path in storeSettingsPaths) foreach (var path in storeSettingsPaths)
{ // should have view access to settings, but no submit buttons or create links { // should have view access to settings, but no submit buttons or create links
s.TestLogs.LogInformation($"Checking access to store page {path} as manager"); s.TestLogs.LogInformation($"Checking access to store page {path} as manager");
await s.AssertPageAccess(true, $"/stores/{storeId}/{path}"); await s.AssertPageAccess(true, $"stores/{storeId}/{path}");
await s.Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
Assert.False(await s.Page.GetByRole(AriaRole.Button, new() { Name = "Save" }).IsVisibleAsync()); Assert.False(await s.Page.GetByRole(AriaRole.Button, new() { Name = "Save" }).IsVisibleAsync());
} }
await s.Logout(); await s.Logout();
@@ -2438,6 +2437,245 @@ namespace BTCPayServer.Tests
Assert.False(string.IsNullOrEmpty(pairingCode2)); 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);
}
} }
} }

View File

@@ -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)] [Fact(Timeout = TestTimeout)]
public async Task CanCreateAppPoS() public async Task CanCreateAppPoS()
@@ -702,83 +540,6 @@ namespace BTCPayServer.Tests
s.Driver.SwitchTo().Window(s.Driver.WindowHandles[0]); s.Driver.SwitchTo().Window(s.Driver.WindowHandles[0]);
Assert.Equal("Settled", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text); 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] [Fact]
[Trait("Selenium", "Selenium")] [Trait("Selenium", "Selenium")]
[Trait("Lightning", "Lightning")] [Trait("Lightning", "Lightning")]