Add ability for to upload screenshot to circleci artifact for Playwright tests

This commit is contained in:
nicolas.dorier
2025-06-15 23:06:18 +09:00
parent 0ba3f92ef4
commit 49f1f198f3
8 changed files with 67 additions and 6 deletions

View File

@@ -16,6 +16,12 @@ jobs:
- run: - run:
command: | command: |
cd .circleci && ./run-tests.sh "Playwright=Playwright" 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: selenium_tests:
machine: machine:
image: ubuntu-2004:2024.11.1 image: ubuntu-2004:2024.11.1

View File

@@ -10,7 +10,7 @@ n=0
until [ "$n" -ge 10 ] until [ "$n" -ge 10 ]
do do
docker-compose -f "docker-compose.altcoins.yml" pull && break docker-compose -f "docker-compose.altcoins.yml" pull && break
n=$((n+1)) n=$((n+1))
sleep 5 sleep 5
done done

View File

@@ -405,10 +405,8 @@ goodies:
Assert.Contains("0,77 €", await s.Page.TextContentAsync("#PaymentDetails-TaxIncluded")); Assert.Contains("0,77 €", await s.Page.TextContentAsync("#PaymentDetails-TaxIncluded"));
Assert.Contains("10,67 €", await s.Page.TextContentAsync("#PaymentDetails-TotalFiat")); Assert.Contains("10,67 €", await s.Page.TextContentAsync("#PaymentDetails-TotalFiat"));
// //
// Pay
await s.PayInvoice(true); await s.PayInvoice(true);
// Receipt // Receipt
await s.Page.ClickAsync("#ReceiptLink"); await s.Page.ClickAsync("#ReceiptLink");
await s.Page.WaitForSelectorAsync("#CartData table"); await s.Page.WaitForSelectorAsync("#CartData table");
@@ -435,7 +433,17 @@ goodies:
// Check inventory got updated and is now 3 instead of 5 // Check inventory got updated and is now 3 instead of 5
await s.GoToUrl(posUrl); 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 // Guest user can access recent transactions
await s.GoToHome(); await s.GoToHome();

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -566,7 +567,15 @@ namespace BTCPayServer.Tests
await Page.ClickAsync("#FakePayment"); await Page.ClickAsync("#FakePayment");
await Page.Locator("#CheatSuccessMessage").WaitForAsync(); await Page.Locator("#CheatSuccessMessage").WaitForAsync();
// TODO: Fix flakyness // 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) if (mine)
{ {
@@ -574,6 +583,25 @@ namespace BTCPayServer.Tests
} }
} }
/// <summary>
/// Take a screenshot. If running in CI, it is uploaded in the artifacts (see https://github.com/btcpayserver/btcpayserver/pull/6794)
/// </summary>
/// <param name="fileName"></param>
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() public async Task MineBlockOnInvoiceCheckout()
{ {
await Page.ClickAsync("#mine-block button"); await Page.ClickAsync("#mine-block button");

View File

@@ -34,6 +34,7 @@ namespace BTCPayServer.Tests
internal ILog TestLogs; internal ILog TestLogs;
public ServerTester(string scope, bool newDb, ILog testLogs, ILoggerProvider loggerProvider, BTCPayNetworkProvider networkProvider) public ServerTester(string scope, bool newDb, ILog testLogs, ILoggerProvider loggerProvider, BTCPayNetworkProvider networkProvider)
{ {
Scope = scope;
LoggerProvider = loggerProvider; LoggerProvider = loggerProvider;
this.TestLogs = testLogs; this.TestLogs = testLogs;
_Directory = scope; _Directory = scope;
@@ -73,6 +74,8 @@ namespace BTCPayServer.Tests
PayTester.SocksEndpoint = GetEnvironment("TESTS_SOCKSENDPOINT", "localhost:9050"); PayTester.SocksEndpoint = GetEnvironment("TESTS_SOCKSENDPOINT", "localhost:9050");
} }
public string Scope { get; set; }
public void ActivateLangs() public void ActivateLangs()
{ {
TestLogs.LogInformation("Activating Langs..."); TestLogs.LogInformation("Activating Langs...");

View File

@@ -82,7 +82,17 @@ public class WalletTests(ITestOutputHelper helper) : UnitTestBase(helper)
await w.AssertNotFound(cpfpTx); 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. // 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"); 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) // Now, we sweep all the UTXOs to a single destination. This should be RBF-able. (Fee deducted on the lone UTXO)

View File

@@ -29,6 +29,7 @@ services:
TESTS_SSHPASSWORD: "" TESTS_SSHPASSWORD: ""
TESTS_SSHKEYFILE: "" TESTS_SSHKEYFILE: ""
TESTS_SOCKSENDPOINT: "tor:9050" TESTS_SOCKSENDPOINT: "tor:9050"
TESTS_ARTIFACTS_DIR: "/tmp/Artifacts"
expose: expose:
- "80" - "80"
depends_on: depends_on:
@@ -44,6 +45,7 @@ services:
- "sshd_datadir:/root/.ssh" - "sshd_datadir:/root/.ssh"
- "customer_lightningd_datadir:/etc/customer_lightningd_datadir" - "customer_lightningd_datadir:/etc/customer_lightningd_datadir"
- "merchant_lightningd_datadir:/etc/merchant_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 # The dev container is not actually used, it is just handy to run `docker-compose up dev` to start all services
dev: dev:
@@ -366,6 +368,7 @@ services:
- "elementsd_liquid_datadir:/data" - "elementsd_liquid_datadir:/data"
volumes: volumes:
tests_datadir:
sshd_datadir: sshd_datadir:
bitcoin_datadir: bitcoin_datadir:
elementsd_liquid_datadir: elementsd_liquid_datadir:

View File

@@ -87,6 +87,9 @@ namespace BTCPayServer
} }
} }
if (Logs.Events.IsEnabled(LogLevel.Information))
Logs.Events.LogInformation("Event published {0}", evt);
foreach (var sub in actionList) foreach (var sub in actionList)
{ {
try try