headless-browser: Print a diff when a test failure occurs

This will make it a lot easier to understand what went wrong, especially
when the failure occurs on CI but not at home.

And of course, use LibDiff to generate the diff! :^)
This commit is contained in:
Andreas Kling 2023-05-28 20:55:32 +02:00
parent 097b5e4803
commit ad6027433d
Notes: sideshowbarker 2024-07-17 06:38:11 +09:00
4 changed files with 54 additions and 5 deletions

View file

@ -113,7 +113,7 @@ qt_add_executable(headless-browser
Utilities.cpp)
target_include_directories(headless-browser PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(headless-browser PRIVATE Qt::Core LibWeb LibWebView LibWebSocket LibCrypto LibFileSystem LibGemini LibHTTP LibJS LibGfx LibMain LibTLS LibIPC LibJS)
target_link_libraries(headless-browser PRIVATE Qt::Core LibWeb LibWebView LibWebSocket LibCrypto LibFileSystem LibGemini LibHTTP LibJS LibGfx LibMain LibTLS LibIPC LibJS LibDiff)
set_target_properties(ladybird PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER org.SerenityOS.Ladybird

View file

@ -379,6 +379,7 @@ if (BUILD_LAGOM)
Compress
Crypto
DNS
Diff
Gemini
Gfx
GL

View file

@ -95,7 +95,7 @@ target_link_libraries(gml-format PRIVATE LibGUI)
target_link_libraries(grep PRIVATE LibFileSystem LibRegex)
target_link_libraries(gunzip PRIVATE LibCompress)
target_link_libraries(gzip PRIVATE LibCompress)
target_link_libraries(headless-browser PRIVATE LibCrypto LibFileSystem LibGemini LibGfx LibHTTP LibTLS LibWeb LibWebView LibWebSocket LibIPC LibJS)
target_link_libraries(headless-browser PRIVATE LibCrypto LibFileSystem LibGemini LibGfx LibHTTP LibTLS LibWeb LibWebView LibWebSocket LibIPC LibJS LibDiff)
target_link_libraries(icc PRIVATE LibGfx LibVideo)
target_link_libraries(image PRIVATE LibGfx)
target_link_libraries(image2bin PRIVATE LibGfx)

View file

@ -20,6 +20,7 @@
#include <LibCore/EventLoop.h>
#include <LibCore/File.h>
#include <LibCore/Timer.h>
#include <LibDiff/Generator.h>
#include <LibFileSystem/FileSystem.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/Font/FontDatabase.h>
@ -229,12 +230,59 @@ static ErrorOr<TestResult> run_test(HeadlessWebContentView& view, StringView inp
auto expectation = TRY(String::from_utf8(StringView(TRY(expectation_file->read_until_eof()).bytes())));
auto actual = result.release_value();
actual = TRY(actual.trim("\n"sv, TrimMode::Right));
expectation = TRY(expectation.trim("\n"sv, TrimMode::Right));
auto actual_trimmed = TRY(actual.trim("\n"sv, TrimMode::Right));
auto expectation_trimmed = TRY(expectation.trim("\n"sv, TrimMode::Right));
if (actual == expectation)
if (actual_trimmed == expectation_trimmed)
return TestResult::Pass;
bool color_output = isatty(STDOUT_FILENO);
dbgln("Test failed: {}", input_path);
auto hunks = Diff::from_text(expectation, actual);
for (auto const& hunk : hunks) {
auto original_start = hunk.original_start_line;
auto target_start = hunk.target_start_line;
auto num_added = hunk.added_lines.size();
auto num_removed = hunk.removed_lines.size();
StringBuilder builder;
// Source line(s)
builder.appendff("{}", original_start);
if (num_removed > 1)
builder.appendff(",{}", original_start + num_removed - 1);
// Action
if (num_added > 0 && num_removed > 0)
builder.append('c');
else if (num_added > 0)
builder.append('a');
else
builder.append('d');
// Target line(s)
builder.appendff("{}", target_start);
if (num_added > 1)
builder.appendff(",{}", target_start + num_added - 1);
outln("Hunk: {}", builder.string_view());
for (auto const& line : hunk.removed_lines) {
if (color_output)
outln("\033[31;1m< {}\033[0m", line);
else
outln("< {}", line);
}
if (num_added > 0 && num_removed > 0)
outln("---");
for (auto const& line : hunk.added_lines) {
if (color_output)
outln("\033[32;1m> {}\033[0m", line);
else
outln("> {}", line);
}
}
return TestResult::Fail;
}