diff --git a/BTCPayServer.Tests/SeleniumTester.cs b/BTCPayServer.Tests/SeleniumTester.cs index e2f51b29d..7e50b3bd8 100644 --- a/BTCPayServer.Tests/SeleniumTester.cs +++ b/BTCPayServer.Tests/SeleniumTester.cs @@ -18,6 +18,7 @@ using NBitcoin; using NBitcoin.RPC; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; +using OpenQA.Selenium.Support.Extensions; using OpenQA.Selenium.Support.UI; using Xunit; diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index 65419ce2f..5aa2c6dbd 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -2063,7 +2063,7 @@ namespace BTCPayServer.Tests s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP1"); s.Driver.FindElement(By.Id("Amount")).Clear(); s.Driver.FindElement(By.Id("Amount")).SendKeys("99.0"); @@ -2108,7 +2108,7 @@ namespace BTCPayServer.Tests await s.Server.ExplorerNode.GenerateAsync(1); await s.FundStoreWallet(denomination: 50.0m); s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP1"); s.Driver.FindElement(By.Id("Amount")).Clear(); s.Driver.FindElement(By.Id("Amount")).SendKeys("99.0"); @@ -2122,7 +2122,7 @@ namespace BTCPayServer.Tests s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP2"); s.Driver.FindElement(By.Id("Amount")).Clear(); s.Driver.FindElement(By.Id("Amount")).SendKeys("100.0"); @@ -2225,7 +2225,7 @@ namespace BTCPayServer.Tests s.GenerateWallet("BTC", "", true, true); s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("External Test"); s.Driver.FindElement(By.Id("Amount")).Clear(); s.Driver.FindElement(By.Id("Amount")).SendKeys("0.001"); @@ -2276,7 +2276,7 @@ namespace BTCPayServer.Tests //Currently an onchain wallet is required to use the Lightning payouts feature.. s.GenerateWallet("BTC", "", true, true); s.GoToStore(newStore.storeId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); var paymentMethodOptions = s.Driver.FindElements(By.CssSelector("input[name='PayoutMethods']")); Assert.Equal(2, paymentMethodOptions.Count); @@ -2344,7 +2344,7 @@ namespace BTCPayServer.Tests //auto-approve pull payments s.GoToStore(StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP1"); s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), true); s.Driver.FindElement(By.Id("Amount")).Clear(); @@ -2367,7 +2367,7 @@ namespace BTCPayServer.Tests // LNURL Withdraw support check with BTC denomination s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP1"); s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), true); s.Driver.FindElement(By.Id("Amount")).Clear(); @@ -2459,7 +2459,7 @@ namespace BTCPayServer.Tests } s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP1"); s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), false); s.Driver.FindElement(By.Id("Amount")).Clear(); @@ -2499,7 +2499,7 @@ namespace BTCPayServer.Tests // LNURL Withdraw support check with SATS denomination s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP SATS"); s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), true); s.Driver.FindElement(By.Id("Amount")).Clear(); @@ -3122,7 +3122,7 @@ namespace BTCPayServer.Tests // Check that pull payment has lightning option s.GoToStore(s.StoreId, StoreNavPages.PullPayments); - s.Driver.FindElement(By.Id("NewPullPayment")).Click(); + s.ClickPagePrimary(); Assert.Equal(PaymentTypes.LN.GetPaymentMethodId(cryptoCode), PaymentMethodId.Parse(Assert.Single(s.Driver.FindElements(By.CssSelector("input[name='PayoutMethods']"))).GetAttribute("value"))); s.Driver.FindElement(By.Id("Name")).SendKeys("PP1"); s.Driver.FindElement(By.Id("Amount")).Clear(); diff --git a/BTCPayServer.Tests/UtilitiesTests.cs b/BTCPayServer.Tests/UtilitiesTests.cs index 9591870e5..543809a02 100644 --- a/BTCPayServer.Tests/UtilitiesTests.cs +++ b/BTCPayServer.Tests/UtilitiesTests.cs @@ -15,8 +15,10 @@ using BTCPayServer.Client; using BTCPayServer.Client.Models; using BTCPayServer.Controllers; using ExchangeSharp; +using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using NBitcoin; @@ -27,6 +29,7 @@ using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; using Xunit; using Xunit.Abstractions; +using static System.Net.Mime.MediaTypeNames; namespace BTCPayServer.Tests { @@ -267,6 +270,63 @@ retry: Thread.Sleep(200); } + class TranslatedKeyNodeWalker : IntermediateNodeWalker + { + private List _defaultTranslatedKeys; + private string _txt; + + public TranslatedKeyNodeWalker(List defaultTranslatedKeys) + { + _defaultTranslatedKeys = defaultTranslatedKeys; + } + + public TranslatedKeyNodeWalker(List defaultTranslatedKeys, string txt) : this(defaultTranslatedKeys) + { + _txt = txt; + } + + public override void VisitTagHelper(TagHelperIntermediateNode node) + { + if (node.TagName == "input") + { + foreach (var tagHelper in node.TagHelpers) + { + if (tagHelper.Name.EndsWith("TranslateTagHelper")) + { + var inner = ToString(node); + if (inner.Contains("type=\"submit\"")) + { + var m = Regex.Match(inner, "value=\"(.*?)\""); + if (m.Success) + { + _defaultTranslatedKeys.Add(m.Groups[1].Value); + } + } + } + } + return; + } + foreach (var tagHelper in node.TagHelpers) + { + if (tagHelper.Name.EndsWith("TranslateTagHelper")) + { + var htmlContent = node.FindDescendantNodes().FirstOrDefault(); + if (htmlContent is not null) + { + var inner = ToString(htmlContent); + _defaultTranslatedKeys.Add(inner); + } + } + } + base.VisitTagHelper(node); + } + + private string ToString(IntermediateNode? node) + { + return _txt.Substring(node.Source.Value.AbsoluteIndex, node.Source.Value.Length); + } + } + /// /// This utilities crawl through the cs files in search for /// Display attributes, then update Translations.Default to list them @@ -308,30 +368,17 @@ retry: defaultTranslatedKeys.Add(match.Groups[1].Value); } } - else if (txt.Contains("text-translate")) - { - filePath = filePath.Replace(Path.Combine(soldir.FullName, "BTCPayServer"), "/"); - var item = engine.FileSystem.GetItem(filePath); + + filePath = filePath.Replace(Path.Combine(soldir.FullName, "BTCPayServer"), "/"); + var item = engine.FileSystem.GetItem(filePath); - var node = (DocumentIntermediateNode)engine.Process(item).Items[typeof(DocumentIntermediateNode)]; - foreach (var n in node.FindDescendantNodes()) - { - foreach (var tagHelper in n.TagHelpers) - { - if (tagHelper.Name.EndsWith("TranslateTagHelper")) - { - var htmlContent = n.FindDescendantNodes().First(); - var inner = txt.Substring(htmlContent.Source.Value.AbsoluteIndex, htmlContent.Source.Value.Length); - defaultTranslatedKeys.Add(inner); - } - } - } - - } + var node = (DocumentIntermediateNode)engine.Process(item).Items[typeof(DocumentIntermediateNode)]; + var w = new TranslatedKeyNodeWalker(defaultTranslatedKeys, txt); + w.Visit(node); } } - defaultTranslatedKeys = defaultTranslatedKeys.Distinct().OrderBy(o => o).ToList(); + defaultTranslatedKeys = defaultTranslatedKeys.Select(d => d.Trim()).Distinct().OrderBy(o => o).ToList(); var path = Path.Combine(soldir.FullName, "BTCPayServer/Services/Translations.Default.cs"); var defaultTranslation = File.ReadAllText(path); var startIdx = defaultTranslation.IndexOf("\"\"\""); diff --git a/BTCPayServer/Components/MainNav/Default.cshtml b/BTCPayServer/Components/MainNav/Default.cshtml index c22cd6f0d..838fdea49 100644 --- a/BTCPayServer/Components/MainNav/Default.cshtml +++ b/BTCPayServer/Components/MainNav/Default.cshtml @@ -34,43 +34,43 @@ @if (ViewData.IsActivePage([StoreNavPages.General, StoreNavPages.Rates, StoreNavPages.CheckoutAppearance, StoreNavPages.Tokens, StoreNavPages.Users, StoreNavPages.Roles, StoreNavPages.Webhooks, StoreNavPages.PayoutProcessors, StoreNavPages.Emails, StoreNavPages.Forms])) { } @@ -79,9 +79,7 @@