<commit_before><!DOCTYPE html>
<html>
    <head>
        <title>Cockpit starting...</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="//code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>
        <script>

var tap_range = /^([0-9]+)\.\.([0-9]+)$/m;
var tap_result = /^(ok|not ok) ([0-9]+) (.*$)/gm;
var tap_skipped = /^ok [0-9]+ ([^#].*) # SKIP (.*$)/gm;

function extract(text) {
    var m;
    var first, last, total, passed, failed, skipped;

    $('#testing').hide();

    if (m = tap_range.exec(text)) {
        first = parseInt(m[1]);
        last = parseInt(m[2]);
        total = last-first+1;

        passed = 0;
        failed = 0;
        $('#failures').empty();
        while (m = tap_result.exec(text)) {
            if(m[1] == "ok")
                passed += 1;
            else {
                failed += 1;
                $('#failures').append($('<li>').text(m[3]));
            }
        }
        skipped = 0;
        while (m = tap_skipped.exec(text)) {
            skipped += 1;
            passed -= 1;
            $('#skipped-tests').append($('<li>').text(m[1] + " -- " + m[2]));
        }

        $('#total').text(total);
        $('#passed').text(passed);
        $('#failed').text(failed);
        $('#skipped').text(skipped);
        $('#left').text(total - passed - failed - skipped);
        $('#testing').show();
    }
}

var interval_id;

function poll() {
    $.get("log", "text").
        done(function (text) {
            $('#log').text(text);
            extract(text);
        });

    $.get("status", "json").
        done(function (text) {
            var status = JSON.parse(text);
            $('#message').text(status.message);
            $('#status').show();
            clearInterval(interval_id);
        });
}

$(function () {
    interval_id = setInterval(poll, 30000);
    poll();
});

  </script>
</head>
  <body>
    <h1>Logs</h1>
    <p>
      <a href=".">Result directory</a>
    </p>
    <p id="testing" style="display:none">
      <span id="total"></span> tests,
      <span id="passed"></span> passed,
      <span id="failed"></span> failed,
      <span id="skipped"></span> skipped,
      <span id="left"></span> to go.<br>
      <span>Failed tests:</span>
          <ul id="failures"></ul>
      <span>Skipped tests:</span>
          <ul id="skipped-tests"></ul>
    </p>
    <p id="status" style="display:none">
      Done: <span id="message"></span>.
    </p>
    <pre id="log">
    </pre>
  </body>
</html><commit_msg>test: Improve log display<commit_after><!DOCTYPE html>
<html>
    <head>
        <title>Cockpit Integration Tests</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="//code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="<KEY>" crossorigin="anonymous">
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="<KEY>" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.2.1/mustache.min.js"></script>
        <!-- nicer arrows for the collapsible panels and preformatted text-->
        <style>
        * {
         font-family: "Open Sans";
        }
        .panel-heading:last-child:after {
            font-family:'Glyphicons Halflings';
            content:"\e114";
            float: right;
            color: grey;
        }
        .panel-heading:last-child.collapsed:after {
            content:"\e080";
        }
        .panel-heading.failed {
            color: #A94442;
            background-color: #F2DEDE;
            border-color: #EBCCD1;
        }
        .panel-heading.skipped {
            color: #8A6D3B;
            background-color: #FCF8E3;
            border-color: #FAEBCC;
        }
        li.failed {
            color: #A94442;
            background-color: #F2DEDE;
            border-color: #EBCCD1;
        }
        .preformatted {
            font-family: monospace;
            white-space: pre;
        }
        </style>
        <script id="Tests" type="text/template">
            <div class="panel-group" id="accordion">
                {{#tests}} {{{html}}} {{/tests}}
            </div>
        </script>
        <script id="ScreenshotLink" type="text/template">
            <a href="./{{screenshot}}" title="{{screenshot}}">
                <span class="glyphicon glyphicon-camera" aria-hidden="true"></span>
                screenshot
            </a>
        </script>
        <script id="JournalLink" type="text/template">
            <a href="./{{journal}}" title="{{journal}}">
                <span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span>
                journal
            </a>
        </script>
        <script id="TestEntry" type="text/template">
            <div class="panel panel-default" id="{{id}}">
                <div class="panel-heading
                            {{#collapsed}}collapsed{{/collapsed}}
                            {{^passed}}failed{{/passed}}
                            {{#skipped}}skipped{{/skipped}}" data-toggle="collapse" data-target="#collapse{{id}}"
                            style="cursor: pointer">
                    <h4 class="panel-title">
                        {{#failed}}
                            <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
                        {{/failed}}
                        <span>
                          {{title}}
                        </span>
                        {{#reason}}<span>-- skipped: {{reason}}</span>{{/reason}}
                        {{#screenshots}}
                            {{{screenshot_html}}}
                        {{/screenshots}}
                        {{#journals}}
                            {{{journal_html}}}
                        {{/journals}}
                    </h4>
                </div>
                <div id="collapse{{id}}" class="panel-collapse collapse {{^collapsed}}in{{/collapsed}}">
                    <div class="panel-body preformatted">{{text}}</div>
                </div>
            </div>
        </script>
        <script id="TextOnly" type="text/template">
            <div class="panel-body preformatted">{{text}}</div>
        </script>
        <script id="TestProgress" type="text/template">
            <div class="progress" style="width: 40%">
                <div class="progress-bar progress-bar-success" style="width: {{percentage_passed}}%">
                    {{num_passed}}
                    <span class="sr-only">{{percentage_passed}}% Passed</span>
                </div>
                <div class="progress-bar progress-bar-warning" style="width: {{percentage_skipped}}%">
                    {{num_skipped}}
                    <span class="sr-only">{{percentage_skipped}}% Skipped</span>
                </div>
                <div class="progress-bar progress-bar-danger" style="width: {{percentage_failed}}%">
                    {{num_failed}}
                    <span class="sr-only">{{percentage_failed}}% Failed</span>
                </div>
            </div>
        </script>
        <script id="TestingOverview" type="text/template">
            <div id="testing">
                {{total}} tests, {{passed}} passed, {{failed}} failed,
                {{skipped}} skipped, {{left}} to go.<br>

                <span>Failed and skipped tests:</span>
                <ul>
                {{#tests}}
                    {{^entry.passed}}
                        <li
                        {{^entry.skipped}}
                            class="failed"
                        {{/entry.skipped}}
                        >
                        <a href="#{{entry.id}}">
                        {{entry.title}}
                        </a>
                        {{#entry.screenshots}}
                            {{{screenshot_html}}}
                        {{/entry.screenshots}}
                        {{#entry.journals}}
                            {{{journal_html}}}
                        {{/entry.journals}}
                        {{#entry.reason}}<span>-- skipped: {{entry.reason}}</span>{{/entry.reason}}
                        </li>
                    {{/entry.passed}}
                {{/tests}}
                </ul>
            </div>
        </script>
        <script>

var tap_range = /^([0-9]+)\.\.([0-9]+)$/m;
var tap_result = /^(ok|not ok) ([0-9]+) (.*$)/gm;
var tap_skipped = /^ok [0-9]+ ([^#].*) # SKIP (.*$)/gm;
var image_file = /([A-Za-z0-9-]+)\.(png)$/gm;
var journal_file = /(Journal extracted to )([A-Za-z0-9\-\.]+)\.(log)$/gm;
var test_header_start = "# ----------------------------------------------------------------------"

var entry_template = $("#TestEntry").html();
Mustache.parse(entry_template);
var tests_template = $("#Tests").html();
Mustache.parse(tests_template);
var text_only_template = $("#TextOnly").html();
Mustache.parse(text_only_template);
var progress_template = $("#TestProgress").html();
Mustache.parse(progress_template);
var overview_template = $("#TestingOverview").html();
Mustache.parse(overview_template);
var screenshot_template = $("#ScreenshotLink").html();
Mustache.parse(screenshot_template);
var journal_template = $("#JournalLink").html();
Mustache.parse(journal_template);

function extract(text) {
    var m;
    var first, last, total, passed, failed, skipped;
    /* default is to show the text we have, unless we find actual results */
    var altered_text = Mustache.render(text_only_template, {
                    text: text
                });
    var entries = [];
    if (m = tap_range.exec(text)) {
        first = parseInt(m[1]);
        last = parseInt(m[2]);
        total = last-first+1;

        passed = 0;
        failed = 0;
        skipped = 0;

        var segments = text.split(test_header_start);
        $('#test-info').text(text.slice(0, text.indexOf('\n')));

        var test_links = {};
        segments.forEach(function (segment) {
            tap_range.lastIndex = 0;
            tap_result.lastIndex = 0;
            tap_skipped.lastIndex = 0;
            image_file.lastIndex = 0;
            journal_file.lastIndex = 0;
            var entry = { passed: true,
                          skipped: false,
                          screenshots: [],
                          journals: [],
                          text: segment};
            if (m = tap_range.exec(segment)) {
                entry.idx = 0;
                entry.id = "initialization"
                entry.title = entry.id;
                // hide this by default
                // maybe we can have better criteria?
                entry.passed = true;
            } else if (m = tap_result.exec(segment)) {
                entry.idx = m[2];
                entry.id = m[2];
                entry.title = entry.id + ": " + m[3];
                if(m[1] == "ok") {
                    if (m = tap_skipped.exec(segment)) {
                        entry.title = entry.id + ": " + m[1];
                        entry.reason = m[2];
                        entry.skipped = true;
                        entry.passed = false;
                        skipped += 1;
                    } else {
                        passed += 1;
                    }
                } else {
                    entry.passed = false;
                    failed += 1;
                }
            } else {
                entry.idx = 10000;
                entry.id = "in-progress";
                entry.title = "in progress";
                entry.passed = true;
            }
            while (m = image_file.exec(segment)) {
                // we have an image link
                entry.screenshots.push({screenshot_html: Mustache.render(screenshot_template,
                                                                        { screenshot: m[1] + "." + m[2] })
                                       });
            }
            while (m = journal_file.exec(segment)) {
                entry.journals.push({journal_html: Mustache.render(journal_template,
                                                                   { journal: m[2] + "." + m[3] })
                                    });
            }
            entry.failed = !entry.passed && !entry.skipped;
            entry.collapsed = !entry.failed;
            entries.push({ idx: entry.idx, entry: entry, html: Mustache.render(entry_template, entry) });
        });
        entries.sort(function(a, b) {
            a = isNaN(parseInt(a.idx)) ? a.idx : parseInt(a.idx)
            b = isNaN(parseInt(b.idx)) ? b.idx : parseInt(b.idx)
            return a < b ? -1 : (a > b ? 1 : 0);
        });
        altered_text = Mustache.render(tests_template, { tests: entries });
        // for the overview list, put the failed entries first
        entries.sort(function(a, b) {
                var a_idx = isNaN(parseInt(a.idx)) ? a.idx : parseInt(a.idx)
                var b_idx = isNaN(parseInt(b.idx)) ? b.idx : parseInt(b.idx)
                if (a.entry.skipped == b.entry.skipped)
                    return a_idx < b_idx ? -1 : (a_idx > b_idx ? 1 : 0);
                else if (!a.entry.skipped)
                    return -1;
                else
                    return 1;
            });
        $('#testing').html(Mustache.render(overview_template, { tests: entries,
                                                                passed: passed,
                                                                failed: failed,
                                                                skipped: skipped,
                                                                total: total,
                                                                left: total - passed - failed - skipped
                                                              })
                           );
        $('#testing-progress').html(Mustache.render(progress_template,
                                                        { percentage_passed: 100*passed/total,
                                                          percentage_skipped: 100*skipped/total,
                                                          percentage_failed: 100*failed/total,
                                                          num_passed: passed,
                                                          num_skipped: skipped,
                                                          num_failed: failed
                                                        })
                                       );
    } else {
        $('#testing').empty();
        $('#testing-progress').empty();
    }

    return altered_text;
}

var interval_id;

function poll() {
    $.get("log", "text").
        done(function (text) {
            var amended_text = extract(text);
            $('#log').html(amended_text);
        });

    $.get("status", "json").
        done(function (text) {
            var status = JSON.parse(text);
            $('#message').text(status.message);
            if ((status.message == "Install failed") ||
                (status.message == "Rebase failed")) {
                $('#testing-progress').html(Mustache.render(progress_template,
                                                        { percentage_passed: 0,
                                                          percentage_skipped: 0,
                                                          percentage_failed: 100,
                                                          num_passed: 0,
                                                          num_skipped: 0,
                                                          num_failed: status.message
                                                        })
                                            );
            }
            $('#status').show();
            clearInterval(interval_id);
        });
}

$(function () {
    interval_id = setInterval(poll, 30000);
    poll();
});

  </script>
</head>
    <body>
        <h3 id="test-info">Logs</h3>
        <p>
            <a href=".">Result directory</a><br>
            <a href="./log">Raw log</a>
        </p>
        <div id="status" style="display:none">
            Done: <span id="message"></span>.
        </div>
        <div id="testing-progress"></div>
        <div id="testing"></div>
        <div id="log"></div>
    </body>
</html>
{'fraction_non_alphanumeric': 0.1575706856357224, 'fraction_numerical': 0.00926534759997609, 'mean_word_length': 1.2743338771071235, 'pattern_counts': {'":': 2, '<': 168, '<?xml version=': 0, '>': 168, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 51, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5069081', 'n_tokens_mistral': 4617, 'n_tokens_neox': 4371, 'n_words': 824}