From 49f1f198f3cfbcf3b417bfa7d6141cae1ff1e69a Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Sun, 15 Jun 2025 23:06:18 +0900 Subject: [PATCH] Add ability for to upload screenshot to circleci artifact for Playwright tests --- .circleci/config.yml | 6 ++++ .circleci/run-tests.sh | 2 +- BTCPayServer.Tests/POSTests.cs | 14 +++++++-- BTCPayServer.Tests/PlaywrightTester.cs | 30 ++++++++++++++++++- BTCPayServer.Tests/ServerTester.cs | 3 ++ BTCPayServer.Tests/WalletTests.cs | 12 +++++++- .../docker-compose.altcoins.yml | 3 ++ BTCPayServer/EventAggregator.cs | 3 ++ 8 files changed, 67 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7e3eb6e75..2c54df88c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,6 +16,12 @@ jobs: - run: command: | cd .circleci && ./run-tests.sh "Playwright=Playwright" + - run: + when: always + command: | + docker run --rm -v btcpayservertests_tests_datadir:/data -v /tmp/Artifacts:/host alpine sh -c "cp -r /data/. /host/" + - store_artifacts: + path: /tmp/Artifacts selenium_tests: machine: image: ubuntu-2004:2024.11.1 diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index acd577e84..b0f9ad58e 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -10,7 +10,7 @@ n=0 until [ "$n" -ge 10 ] do docker-compose -f "docker-compose.altcoins.yml" pull && break - n=$((n+1)) + n=$((n+1)) sleep 5 done diff --git a/BTCPayServer.Tests/POSTests.cs b/BTCPayServer.Tests/POSTests.cs index f05f1ab69..d44d792f7 100644 --- a/BTCPayServer.Tests/POSTests.cs +++ b/BTCPayServer.Tests/POSTests.cs @@ -405,10 +405,8 @@ goodies: Assert.Contains("0,77 €", await s.Page.TextContentAsync("#PaymentDetails-TaxIncluded")); Assert.Contains("10,67 €", await s.Page.TextContentAsync("#PaymentDetails-TotalFiat")); // - // Pay await s.PayInvoice(true); - // Receipt await s.Page.ClickAsync("#ReceiptLink"); await s.Page.WaitForSelectorAsync("#CartData table"); @@ -435,7 +433,17 @@ goodies: // Check inventory got updated and is now 3 instead of 5 await s.GoToUrl(posUrl); - Assert.Equal("3 left", await s.Page.TextContentAsync(".posItem:nth-child(3) .badge.inventory")); + try + { + Assert.Equal("3 left", await s.Page.TextContentAsync(".posItem:nth-child(3) .badge.inventory")); + } + catch (Exception e) + { + // Flaky + await s.TakeScreenshot("BadInventory.png"); + throw; + } + // Guest user can access recent transactions await s.GoToHome(); diff --git a/BTCPayServer.Tests/PlaywrightTester.cs b/BTCPayServer.Tests/PlaywrightTester.cs index 5f9d3bfc1..1c6501e42 100644 --- a/BTCPayServer.Tests/PlaywrightTester.cs +++ b/BTCPayServer.Tests/PlaywrightTester.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -566,7 +567,15 @@ namespace BTCPayServer.Tests await Page.ClickAsync("#FakePayment"); await Page.Locator("#CheatSuccessMessage").WaitForAsync(); // TODO: Fix flakyness - await Page.Locator("text=Payment Received").WaitForAsync(); + try + { + await Page.Locator("text=Payment Received").WaitForAsync(); + } + catch + { + await TakeScreenshot("PayInvoice.png"); + throw; + } if (mine) { @@ -574,6 +583,25 @@ namespace BTCPayServer.Tests } } + /// + /// Take a screenshot. If running in CI, it is uploaded in the artifacts (see https://github.com/btcpayserver/btcpayserver/pull/6794) + /// + /// + public async Task TakeScreenshot(string fileName) + { + var screenshotDir = Environment.GetEnvironmentVariable("TESTS_ARTIFACTS_DIR") ?? "Screenshots"; + Directory.CreateDirectory(screenshotDir); + screenshotDir = Path.Combine(screenshotDir, this.Server.Scope); + Directory.CreateDirectory(screenshotDir); + var filePath = Path.Combine(screenshotDir, fileName); + Server.TestLogs.LogInformation("Saving test screenshot to " + filePath); + await Page.ScreenshotAsync(new() + { + Path = filePath, + FullPage = true, + }); + } + public async Task MineBlockOnInvoiceCheckout() { await Page.ClickAsync("#mine-block button"); diff --git a/BTCPayServer.Tests/ServerTester.cs b/BTCPayServer.Tests/ServerTester.cs index a4ad74457..528cf00f9 100644 --- a/BTCPayServer.Tests/ServerTester.cs +++ b/BTCPayServer.Tests/ServerTester.cs @@ -34,6 +34,7 @@ namespace BTCPayServer.Tests internal ILog TestLogs; public ServerTester(string scope, bool newDb, ILog testLogs, ILoggerProvider loggerProvider, BTCPayNetworkProvider networkProvider) { + Scope = scope; LoggerProvider = loggerProvider; this.TestLogs = testLogs; _Directory = scope; @@ -73,6 +74,8 @@ namespace BTCPayServer.Tests PayTester.SocksEndpoint = GetEnvironment("TESTS_SOCKSENDPOINT", "localhost:9050"); } + public string Scope { get; set; } + public void ActivateLangs() { TestLogs.LogInformation("Activating Langs..."); diff --git a/BTCPayServer.Tests/WalletTests.cs b/BTCPayServer.Tests/WalletTests.cs index a0d6b9ddd..b9764dcc3 100644 --- a/BTCPayServer.Tests/WalletTests.cs +++ b/BTCPayServer.Tests/WalletTests.cs @@ -82,7 +82,17 @@ public class WalletTests(ITestOutputHelper helper) : UnitTestBase(helper) await w.AssertNotFound(cpfpTx); // However, the new transaction should have copied the CPFP tag from the transaction it replaced, and have a RBF label as well. - await w.AssertHasLabels(rbfTx, "CPFP"); + try + { + await w.AssertHasLabels(rbfTx, "CPFP"); + } + catch + { + // TODO: Flaky + await s.TakeScreenshot("AssertHasLabels-Fails.png"); + throw; + } + await w.AssertHasLabels(rbfTx, "RBF"); // Now, we sweep all the UTXOs to a single destination. This should be RBF-able. (Fee deducted on the lone UTXO) diff --git a/BTCPayServer.Tests/docker-compose.altcoins.yml b/BTCPayServer.Tests/docker-compose.altcoins.yml index 43b9190ba..33a3780ee 100644 --- a/BTCPayServer.Tests/docker-compose.altcoins.yml +++ b/BTCPayServer.Tests/docker-compose.altcoins.yml @@ -29,6 +29,7 @@ services: TESTS_SSHPASSWORD: "" TESTS_SSHKEYFILE: "" TESTS_SOCKSENDPOINT: "tor:9050" + TESTS_ARTIFACTS_DIR: "/tmp/Artifacts" expose: - "80" depends_on: @@ -44,6 +45,7 @@ services: - "sshd_datadir:/root/.ssh" - "customer_lightningd_datadir:/etc/customer_lightningd_datadir" - "merchant_lightningd_datadir:/etc/merchant_lightningd_datadir" + - "tests_datadir:/tmp/Artifacts" # The dev container is not actually used, it is just handy to run `docker-compose up dev` to start all services dev: @@ -366,6 +368,7 @@ services: - "elementsd_liquid_datadir:/data" volumes: + tests_datadir: sshd_datadir: bitcoin_datadir: elementsd_liquid_datadir: diff --git a/BTCPayServer/EventAggregator.cs b/BTCPayServer/EventAggregator.cs index 344fe24b3..e589a83eb 100644 --- a/BTCPayServer/EventAggregator.cs +++ b/BTCPayServer/EventAggregator.cs @@ -87,6 +87,9 @@ namespace BTCPayServer } } + if (Logs.Events.IsEnabled(LogLevel.Information)) + Logs.Events.LogInformation("Event published {0}", evt); + foreach (var sub in actionList) { try