Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML diff results page #2535

Merged
merged 28 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c3ae1b1
HTML diff results page
Nov 12, 2022
db846a8
whitespace
Nov 12, 2022
fa10419
Vendors JS versions, added to the nav, verbiage
Nov 14, 2022
f24398d
Anchor-able line numbers
Nov 18, 2022
e5928fd
CSS tweaks, scrollable long lines
Nov 18, 2022
acb0c79
Avoid extra new lines in the output
Nov 20, 2022
f73416a
Merge branch 'master' into htmldiff
tkadlec Nov 29, 2022
68c51f3
Merge branch 'master' into htmldiff
stoyan Dec 2, 2022
17325c2
use the new generated-html metric
Dec 15, 2022
39e89c7
fit and finish and prettier error handling
scottjehl Dec 15, 2022
2320ead
hide html diff from the results menu
Dec 15, 2022
bf9824f
spacing
scottjehl Dec 15, 2022
45658f2
HTML diff results page
Nov 12, 2022
e9b6e6c
whitespace
Nov 12, 2022
2dc48fe
Vendors JS versions, added to the nav, verbiage
Nov 14, 2022
f772b74
Anchor-able line numbers
Nov 18, 2022
e1f3ea0
CSS tweaks, scrollable long lines
Nov 18, 2022
92fa774
Avoid extra new lines in the output
Nov 20, 2022
0305a7c
use the new generated-html metric
Dec 15, 2022
ceb3e50
fit and finish and prettier error handling
scottjehl Dec 15, 2022
3999d61
hide html diff from the results menu
Dec 15, 2022
fed8570
spacing
scottjehl Dec 15, 2022
b867f9d
menu item
scottjehl Dec 15, 2022
bd88a88
move the diff to an inline worker and minor tweaks
scottjehl Dec 16, 2022
0a6dd5d
typo and docs
scottjehl Dec 16, 2022
a2acd7f
social meta
scottjehl Dec 16, 2022
e4d5c33
no generated screenshots
scottjehl Dec 19, 2022
c9a8a1b
one more time, with feeling
scottjehl Dec 19, 2022
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
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
www/chrome
www/assets/css/vendor
www/assets/js/vendor
www/assets/js/catchpoint-rum.js
www/assets/js/dygraph-combined.js
www/assets/js/codeflask.module.js
Expand Down
38 changes: 38 additions & 0 deletions www/assets/js/vendor/diff.min.js

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions www/assets/js/vendor/prettier-parser-babel.min.js

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions www/assets/js/vendor/prettier-parser-html.min.js

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions www/assets/js/vendor/prettier-parser-postcss.min.js

Large diffs are not rendered by default.

113 changes: 113 additions & 0 deletions www/assets/js/vendor/prettier-standalone.min.js

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions www/htmldiff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

require_once __DIR__ . '/common.inc';

// this output buffer hack avoids a bit of circularity
// on one hand we want the contents of header.inc
// on the other we want to get access to TestRunResults prior to that
ob_start();
define('NOBANNER', true); // otherwise Twitch banner shows 2x
$tab = 'Test Result';
$subtab = 'HTML diff';
include_once INCLUDES_PATH . '/header.inc';
$results_header = ob_get_contents();
ob_end_clean();

// all prerequisite libs were already required in header.inc
$fileHandler = new FileHandler();
$testInfo = TestInfo::fromFiles($testPath);
$testRunResults = TestRunResults::fromFiles($testInfo, $run, $cached, $fileHandler);
$pageData = loadAllPageData($testPath);

$error_message = null;
$delivered_html = null;
$rendered_html = @$pageData[$run][$cached]['rendered-html'];

if (!$rendered_html) {
$error_message = 'Rendered HTML not available, please run the test again';
}

$body_id = @$pageData[$run][$cached]['final_base_page_request_id'];
if (!$body_id) {
$error_message = 'Could not figure out the request ID of the final base page, please run the test again';
} else {
// TODO: move this to a utility and share with response_body.php
$cachedStr = $cached ? '_Cached' : '';
$bodies_file = $testPath . '/' . $run . $cachedStr . '_bodies.zip';
if (is_file($bodies_file)) {
$zip = new ZipArchive();
if ($zip->open($bodies_file) === true) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$name = $zip->getNameIndex($i);
$parts = explode('-', $name);
$id = trim($parts[1]);
if (!strcmp($id, $body_id)) {
$delivered_html = $zip->getFromIndex($i);
break;
}
}
}
}
}

if (!$delivered_html) {
$error_message = 'Response body is not available, please turn on the "Save Response Bodies" option in the advanced settings to capture text resources.';
}

// template
echo view('pages.htmldiff', [
'test_results_view' => true,
'body_class' => 'result',
'results_header' => $results_header,
'rendered_html' => $rendered_html,
'delivered_html' => $delivered_html,
'error_message' => $error_message,
]);
4 changes: 4 additions & 0 deletions www/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/consolelog$ /consolelog.php?test
rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/consolelog/$ /consolelog.php?test=$1&run=$2 last;
rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/consolelog/cached$ /consolelog.php?test=$1&run=$2&cached=1 last;
rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/consolelog/cached/$ /consolelog.php?test=$1&run=$2&cached=1 last;
rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/htmldiff$ /htmldiff.php?test=$1&run=$2 last;
rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/htmldiff/$ /htmldiff.php?test=$1&run=$2 last;
rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/htmldiff/cached$ /htmldiff.php?test=$1&run=$2&cached=1 last;
rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/htmldiff/cached/$ /htmldiff.php?test=$1&run=$2&cached=1 last;

#csv combined results
rewrite ^/result/([a-zA-Z0-9_]+)/.*page_data.csv$ /csv.php?test=$1 last;
Expand Down
100 changes: 100 additions & 0 deletions www/resources/views/pages/htmldiff.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
@extends('default')

@section('style')
<style>
del {
text-decoration: none;
color: #b30000;
background: #fadad7;
}
ins {
background: #eaf2c2;
color: #406619;
text-decoration: none;
}
#delivered, #rendered {
display: none;
}
#diff-result {
white-space: pre-wrap;
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
}
</style>
@endsection

@section('content')
<div class="results_main_contain">
<div class="results_main">
<div class="results_and_command">
<div class="results_header">
<h2>HTML Diff</h2>
</div>
</div>
@if ($error_message)
<div id="result" class="results_body error-banner">
<div>{{ $error_message }}</div>
</div>
@else
<label>
<input type="checkbox" id="prettier">
Run Prettier before the diff
</label>
<div id="result" class="results_body @if ($error_message) error-banner @endif">
<div class="overflow-container">
<pre id="diff-result"></pre>
</div>
<pre id="delivered">{{$delivered_html}}</pre>
<pre id="rendered">{{$rendered_html}}</pre>
</div>
<script src="/assets/js/vendor/diff.min.js"></script>
<script type="module">
async function diff() {
let before = document.getElementById('delivered').innerText;
let after = document.getElementById('rendered').innerText;
if (document.getElementById('prettier').checked) {
await import("/assets/js/vendor/prettier-standalone.min.js");
await import("/assets/js/vendor/prettier-parser-html.min.js");
await import("/assets/js/vendor/prettier-parser-babel.min.js");
await import("/assets/js/vendor/prettier-parser-postcss.min.js");
const opts = {
parser: "html",
plugins: prettierPlugins,
};
before = prettier.format(before, opts);
after = prettier.format(after, opts);
}

const diff = Diff.diffLines(before, after);
const fragment = document.createDocumentFragment();
for (let i = 0; i < diff.length; i++) {

if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
let swap = diff[i];
diff[i] = diff[i + 1];
diff[i + 1] = swap;
}

let node;
if (diff[i].removed) {
node = document.createElement('del');
node.appendChild(document.createTextNode(diff[i].value));
} else if (diff[i].added) {
node = document.createElement('ins');
node.appendChild(document.createTextNode(diff[i].value));
} else {
node = document.createTextNode(diff[i].value);
}
fragment.appendChild(node);
}
document.getElementById('diff-result').innerHTML = '';
document.getElementById('diff-result').appendChild(fragment);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the diff rendering

}
diff();
document.getElementById('prettier').addEventListener('change', diff);
</script>
@endif

</div>
</div>

@endsection