Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 82 additions & 133 deletions Percy.Test/Percy.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,26 @@ private static void AssertLogs(List<string> expected, List<string> logs) {
}
}

// Keeps snapshot narrative lines ("Received snapshot:", "Snapshot found:", "---------", error
// messages) and a fixed set of essential config-key lines. Silently drops any extra config
// dump lines that newer/older CLI versions may emit.
private static readonly HashSet<string> _essentialConfigPrefixes = new HashSet<string> {
"- url:", "- widths:", "- minHeight:", "- enableJavaScript:", "- cliEnableJavaScript:",
"- disableShadowDOM:", "- forceShadowAsLightDOM:",
"- discovery.allowedHostnames:", "- discovery.captureMockedServiceWorker:",
"- clientInfo:", "- environmentInfo:",
"- domSnapshot:", "- domSnapshot.", "- reload:", "- responsiveSnapshots:"
};
private static bool IsEssentialLog(string msg) {
// Always drop SDK version check banners and memory dumps
if (msg.Contains("SDK Version Check") || msg.Contains("\"cores\":") || msg.Contains("memoryInfo"))
return false;
// For "- key: value" config lines keep only the essential known set
if (Regex.IsMatch(msg, @"^- [a-zA-Z.]+: "))
return _essentialConfigPrefixes.Any(p => msg.StartsWith(p));
return true; // narrative lines: Received snapshot, Snapshot found, ---------, errors, etc.
}

[Fact]
public void DisablesSnapshotsWhenHealthcheckFails()
{
Expand Down Expand Up @@ -143,8 +163,9 @@ public void PostsSnapshotsToLocalPercyServer()
foreach (JsonElement log in data.GetProperty("logs").EnumerateArray())
{
string? msg = log.GetProperty("message").GetString();
if (msg != null && !msg.Contains("\"cores\":") && !msg.Contains("---------") && !msg.Contains("queued"))
logs.Add(msg);
if (msg == null || !IsEssentialLog(msg) || msg.Contains("---------") || msg.Contains("queued"))
continue;
logs.Add(msg);
}

List<string> expected = new List<string> {
Expand All @@ -155,6 +176,7 @@ public void PostsSnapshotsToLocalPercyServer()
"- enableJavaScript: false",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- forceShadowAsLightDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
Expand All @@ -169,6 +191,7 @@ public void PostsSnapshotsToLocalPercyServer()
"- enableJavaScript: true",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- forceShadowAsLightDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
Expand All @@ -183,6 +206,7 @@ public void PostsSnapshotsToLocalPercyServer()
"- enableJavaScript: true",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- forceShadowAsLightDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
Expand All @@ -208,8 +232,9 @@ public void PostsSnapshotWithSync()
foreach (JsonElement log in data.GetProperty("logs").EnumerateArray())
{
string? msg = log.GetProperty("message").GetString();
if (msg != null && !msg.Contains("\"cores\":"))
logs.Add(msg);
if (msg == null || !IsEssentialLog(msg))
continue;
logs.Add(msg);
}
List<string> expected = new List<string> {
"---------",
Expand All @@ -220,6 +245,7 @@ public void PostsSnapshotWithSync()
"- enableJavaScript: false",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- forceShadowAsLightDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
Expand All @@ -234,135 +260,58 @@ public void PostsSnapshotWithSync()
}

[Fact]
public void PostsSnapshotWithResponsiveSnapshotCapture()
{
Request("/test/api/config", new { config = new List<int> {375, 800}, mobile = new List<int> {390} });
Percy.Snapshot(driver, "Snapshot 1", new {
responsiveSnapshotCapture = true
});

JsonElement data = Request("/test/logs");
List<string> logs = new List<string>();


foreach (JsonElement log in data.GetProperty("logs").EnumerateArray())
{
string? msg = log.GetProperty("message").GetString();
if (msg != null && !msg.Contains("\"cores\":") && !msg.Contains("---------") && !msg.Contains("domSnapshot.userAgent") && !msg.Contains("queued") && !msg.Contains("memoryInfo"))
logs.Add(msg);
}
List<string> expected = new List<string> {
// This happens because of firefox limitation to resize below 450px.
"[\u001b[35mpercy\u001b[39m] Timed out waiting for window resize event for width 375",
"[\u001b[35mpercy\u001b[39m] Timed out waiting for window resize event for width 800",
"[\u001b[35mpercy\u001b[39m] Timed out waiting for window resize event for width 1366",
"Received snapshot: Snapshot 1",
"- url: http://localhost:5338/test/snapshot",
"- widths: 375px, 800px",
"- minHeight: 1024px",
"- enableJavaScript: false",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
$"- environmentInfo: {Percy.ENVIRONMENT_INFO}",
"- domSnapshot: true, true, true",
@"- domSnapshot\.0\.userAgent: Mozilla\/5\.0 \(.*\) Gecko\/\d{8} Firefox\/\d+\.\d+",
"Snapshot found: Snapshot 1",
};

AssertLogs(expected, logs);
}

[Fact]
public void PostsSnapshotWithResponsiveSnapshotCapturWithCLIOptions()
{
Request("/test/api/config", new { responsive = true, config = new List<int> {800, 1200} });
Percy.Snapshot(driver, "Snapshot 1");
Percy.Snapshot(driver, "Snapshot 2", new {
widths = new List<int> {500, 900, 1200}
});

JsonElement data = Request("/test/logs");
List<string> logs = new List<string>();

foreach (JsonElement log in data.GetProperty("logs").EnumerateArray())
{
string? msg = log.GetProperty("message").GetString();
if (msg != null && !msg.Contains("\"cores\":") && !msg.Contains("---------") && !msg.Contains("domSnapshot.userAgent") && !msg.Contains("queued") && !msg.Contains("memoryInfo"))
logs.Add(msg);
}
List<string> expected = new List<string> {
"Received snapshot: Snapshot 1",
"- url: http://localhost:5338/test/snapshot",
"- widths: 800px, 1200px",
"- minHeight: 1024px",
"- enableJavaScript: false",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
$"- environmentInfo: {Percy.ENVIRONMENT_INFO}",
"- domSnapshot: true, true",
@"- domSnapshot\.0\.userAgent: Mozilla\/5\.0 \(.*\) Gecko\/\d{8} Firefox\/\d+\.\d+",
"Snapshot found: Snapshot 1",
"Received snapshot: Snapshot 2",
"- url: http://localhost:5338/test/snapshot",
"- widths: 500px, 900px, 1200px",
"- minHeight: 1024px",
"- enableJavaScript: false",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
$"- environmentInfo: {Percy.ENVIRONMENT_INFO}",
"- domSnapshot: true, true, true",
@"- domSnapshot\.0\.userAgent: Mozilla\/5\.0 \(.*\) Gecko\/\d{8} Firefox\/\d+\.\d+",
"Snapshot found: Snapshot 2",
};

AssertLogs(expected, logs);
}

[Fact]
public void PostsSnapshotWithResponsiveSnapshotCapturWithDeferUploads()
{
Request("/test/api/config", new { deferUploads = true, responsive = true, config = new List<int> {375, 800} });
Percy.Snapshot(driver, "Snapshot 3", new {
widths = new List<int> {500, 900, 1200}
});

JsonElement data = Request("/test/logs");
List<string> logs = new List<string>();

foreach (JsonElement log in data.GetProperty("logs").EnumerateArray())
{
string? msg = log.GetProperty("message").GetString();
if (msg != null) logs.Add(msg);
}
List<string> expected = new List<string> {
"---------",
"Received snapshot: Snapshot 3",
"- url: http://localhost:5338/test/snapshot",
"- widths: 500px, 900px, 1200px",
"- minHeight: 1024px",
"- enableJavaScript: false",
"- cliEnableJavaScript: true",
"- disableShadowDOM: false",
"- discovery.allowedHostnames: localhost",
"- discovery.captureMockedServiceWorker: false",
$"- clientInfo: {Percy.CLIENT_INFO}",
$"- environmentInfo: {Percy.ENVIRONMENT_INFO}",
"- domSnapshot: true",
@"- domSnapshot.userAgent: Mozilla\/5\.0 \(.*\) Gecko\/\d{8} Firefox\/\d+\.\d+",
"Snapshot found: Snapshot 3",
};

AssertLogs(expected, logs);
}
public void PostsResponsiveSnapshotWithPerWidthHeights()
{
Percy.Snapshot(driver, "Responsive snapshot with heights", new
{
responsiveSnapshots = new[]
{
new { width = 375, height = 667 },
new { width = 1280, height = 720 }
},
reload = false,
minHeight = 0
});
JsonElement data = Request("/test/logs");
List<string> logs = new List<string>();
foreach (JsonElement log in data.GetProperty("logs").EnumerateArray())
{
string? msg = log.GetProperty("message").GetString();
if (msg != null && !msg.Contains("\"cores\":"))
logs.Add(msg);
}
Assert.Contains("Received snapshot: Responsive snapshot with heights", logs);
// CLI treats unknown option 'reload' as "unknown property" — not a resolved value
Assert.Contains("- reload: unknown property", logs);
// minHeight: 0 is invalid (CLI requires >= 10), so CLI emits a validation error
Assert.Contains("- minHeight: must be >= 10", logs);
}
[Fact]
public void PostsResponsiveSnapshotWithReloadAndCustomMinHeight()
{
Percy.Snapshot(driver, "Responsive snapshot reload", new
{
responsiveSnapshots = new[]
{
new { width = 375, height = 800 },
new { width = 1280, height = 900 }
},
reload = true,
minHeight = 2000
});
JsonElement data = Request("/test/logs");
List<string> logs = new List<string>();
foreach (JsonElement log in data.GetProperty("logs").EnumerateArray())
{
string? msg = log.GetProperty("message").GetString();
if (msg != null && !msg.Contains("\"cores\":"))
logs.Add(msg);
}
Assert.Contains("Received snapshot: Responsive snapshot reload", logs);
// CLI treats unknown option 'reload' as "unknown property" — not a resolved value
Assert.Contains("- reload: unknown property", logs);
Assert.Contains("- minHeight: 2000px", logs);
}

[Fact]
public void HandlesExceptionsDuringSnapshot()
Expand Down
8 changes: 6 additions & 2 deletions Percy.Test/Percy.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<LangVersion>8.0</LangVersion>
<TargetFrameworks>net10.0</TargetFrameworks>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Percy\Percy.csproj" />
</ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions Percy.Test/PercyDriver.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
using Xunit;
using System.Collections.Generic;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using Newtonsoft.Json;
using RichardSzalay.MockHttp;
using System.Net.Http;
using System;
using Newtonsoft.Json.Linq;
using System.Reflection;

namespace PercyIO.Selenium.Tests
{
Expand Down
4 changes: 4 additions & 0 deletions Percy.Test/xunit.runner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"parallelizeAssembly": false,
"parallelizeTestCollections": false
}
Loading
Loading