/** * Convert an AVI video capture into the video frames the WPT is expecting * * @param mixed $testPath * @param mixed $run * @param mixed $cached */ function ProcessAVIVideo(&$test, $testPath, $run, $cached) { $cachedText = ''; if ($cached) { $cachedText = '_Cached'; } $videoFile = "{$testPath}/{$run}{$cachedText}_video.avi"; $crop = ''; if (!is_file($videoFile)) { $videoFile = "{$testPath}/{$run}{$cachedText}_video.mp4"; } if (!is_file($videoFile)) { $crop = ',crop=in_w:in_h-80:0:80'; $videoFile = "{$testPath}/{$run}{$cachedText}_appurify.mp4"; } // trim the video to align with the capture if we have timestamps for both $renderStart = null; if (array_key_exists('appurify_tests', $test) && is_array($test['appurify_tests']) && array_key_exists($run, $test['appurify_tests']) && is_array($test['appurify_tests'][$run])) { require_once 'page_data.inc'; $page_data = loadPageRunData($testPath, $run, $cached); if (isset($page_data) && is_array($page_data) && array_key_exists('render', $page_data)) { $renderStart = $page_data['render']; } } if (is_file($videoFile)) { $videoDir = "{$testPath}/video_{$run}" . strtolower($cachedText); if (!is_file("{$videoDir}/video.json")) { if (is_dir($videoDir)) { delTree($videoDir, false); } if (!is_dir($videoDir)) { mkdir($videoDir, 0777, true); } $videoFile = realpath($videoFile); $videoDir = realpath($videoDir); if (strlen($videoFile) && strlen($videoDir)) { if (Video2PNG($videoFile, $videoDir, $crop)) { $startOffset = DevToolsGetVideoOffset($testPath, $run, $cached, $endTime); FindAVIViewport($videoDir, $startOffset, $viewport); EliminateDuplicateAVIFiles($videoDir, $viewport); $lastImage = ProcessVideoFrames($videoDir, $renderStart, $viewport); $screenShot = "{$testPath}/{$run}{$cachedText}_screen.jpg"; if (isset($lastImage) && is_file($lastImage)) { //unlink($videoFile); if (!is_file($screenShot)) { copy($lastImage, $screenShot); } } } } $videoInfo = array(); if (isset($viewport)) { $videoInfo['viewport'] = $viewport; } file_put_contents("{$videoDir}/video.json", json_encode($videoInfo)); } } }
/** * Generate a HAR file for the given test * * @param mixed $testPath */ function GenerateHAR($id, $testPath, $options) { $json = '{}'; if (isset($testPath)) { $pageData = null; if (isset($options["run"]) && $options["run"]) { if (!strcasecmp($options["run"], 'median')) { $raw = loadAllPageData($testPath); $run = GetMedianRun($raw, $options['cached'], $median_metric); if (!$run) { $run = 1; } unset($raw); } $pageData[$run] = array(); if (isset($options['cached'])) { $pageData[$run][$options['cached']] = loadPageRunData($testPath, $run, $options['cached']); if (!isset($pageData[$run][$options['cached']])) { unset($pageData); } } else { $pageData[$run][0] = loadPageRunData($testPath, $run, 0); if (!isset($pageData[$run][0])) { unset($pageData); } $pageData[$run][1] = loadPageRunData($testPath, $run, 1); } } if (!isset($pageData)) { $pageData = loadAllPageData($testPath); } // build up the array $harData = BuildHAR($pageData, $id, $testPath, $options); $json_encode_good = version_compare(phpversion(), '5.4.0') >= 0 ? true : false; $pretty_print = false; if (isset($options['pretty']) && $options['pretty']) { $pretty_print = true; } if (isset($options['php']) && $options['php']) { if ($pretty_print && $json_encode_good) { $json = json_encode($harData, JSON_PRETTY_PRINT); } else { $json = json_encode($harData); } } elseif ($json_encode_good) { if ($pretty_print) { $json = json_encode($harData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } else { $json = json_encode($harData, JSON_UNESCAPED_UNICODE); } } else { $jsonLib = new Services_JSON(); $json = $jsonLib->encode($harData); } } return $json; }
public function postProcessRun() { $testerError = null; $secure = false; $haveLocations = false; loadPageRunData($this->testRoot, $this->run, $this->cached); $steps = $this->countSteps(); for ($i = 1; $i <= $steps; $i++) { $rootUrls = UrlGenerator::create(true, "", $this->id, $this->run, $this->cached, $i); $stepPaths = new TestPaths($this->testRoot, $this->run, $this->cached, $i); $requests = getRequestsForStep($stepPaths, $rootUrls, $secure, $haveLocations, true, true); if (isset($requests) && is_array($requests) && count($requests)) { getBreakdownForStep($stepPaths, $rootUrls, $requests); } else { $testerError = 'Missing Results'; } if (is_dir(__DIR__ . '/../google') && is_file(__DIR__ . '/../google/google_lib.inc')) { require_once __DIR__ . '/../google/google_lib.inc'; ParseCsiInfoForStep($stepPaths, true); } GetDevToolsCPUTimeForStep($stepPaths); } return $testerError; }
/** * Build a side-by-side table with the captured frames from each test * */ function ScreenShotTable() { global $tests; global $thumbSize; global $interval; global $maxCompare; global $color; global $bgcolor; global $supports60fps; $endTime = 'visual'; if (array_key_exists('end', $_REQUEST) && strlen($_REQUEST['end'])) { $endTime = trim($_REQUEST['end']); } $filmstrip_end_time = 0; if (count($tests)) { // figure out how many columns there are $end = 0; foreach ($tests as &$test) { if ($test['video']['end'] > $end) { $end = $test['video']['end']; } } if (!defined('EMBED')) { echo '<br>'; } echo '<form id="createForm" name="create" method="get" action="/video/create.php">'; echo "<input type=\"hidden\" name=\"end\" value=\"{$endTime}\">"; echo '<input type="hidden" name="tests" value="' . htmlspecialchars($_REQUEST['tests']) . '">'; echo "<input type=\"hidden\" name=\"bg\" value=\"{$bgcolor}\">"; echo "<input type=\"hidden\" name=\"text\" value=\"{$color}\">"; if (isset($_REQUEST['labelHeight']) && is_numeric($_REQUEST['labelHeight'])) { echo '<input type="hidden" name="labelHeight" value="' . htmlspecialchars($_REQUEST['labelHeight']) . '">"'; } if (isset($_REQUEST['timeHeight']) && is_numeric($_REQUEST['timeHeight'])) { echo '<input type="hidden" name="timeHeight" value="' . htmlspecialchars($_REQUEST['timeHeight']) . '">"'; } echo '<table id="videoContainer"><tr>'; // build a table with the labels echo '<td id="labelContainer"><table id="videoLabels"><tr><th> </th></tr>'; foreach ($tests as &$test) { // figure out the height of this video $height = 100; if ($test['video']['width'] && $test['video']['height']) { if ($test['video']['width'] > $test['video']['height']) { $height = 22 + (int) ((double) $thumbSize / (double) $test['video']['width'] * (double) $test['video']['height']); } else { $height = 22 + $thumbSize; } } $break = ''; if (!strpos($test['name'], ' ')) { $break = ' style="word-break: break-all;"'; } echo "<tr width=10% height={$height}px ><td{$break} class=\"pagelinks\">"; $name = urlencode($test['name']); $cached = 0; if ($test['cached']) { $cached = 1; } // Print the index outside of the link tag echo $test['index'] . ': '; if (!defined('EMBED')) { $cached = ''; if ($test['cached']) { $cached = 'cached/'; } if (FRIENDLY_URLS) { $href = "/result/{$test['id']}/{$test['run']}/details/{$cached}"; } else { $href = "/details.php?test={$test['id']}&run={$test['run']}&cached={$test['cached']}"; } echo "<a class=\"pagelink\" id=\"label_{$test['id']}\" href=\"{$href}\">" . WrapableString(htmlspecialchars($test['name'])) . '</a>'; } else { echo WrapableString(htmlspecialchars($test['name'])); } // Print out a link to edit the test echo '<br/>'; echo '<a href="#" class="editLabel" data-test-guid="' . $test['id'] . '" data-current-label="' . htmlentities($test['name']) . '">'; if (class_exists("SQLite3")) { echo '(Edit)'; } echo '</a>'; echo "</td></tr>\n"; } echo '</table></td>'; // the actual video frames echo '<td><div id="videoDiv"><table id="video"><thead><tr>'; $filmstrip_end_time = ceil($end / $interval) * $interval; $decimals = $interval >= 100 ? 1 : 3; $frameCount = 0; $ms = 0; while ($ms < $filmstrip_end_time) { $ms = $frameCount * $interval; echo '<th>' . number_format((double) $ms / 1000.0, $decimals) . 's</th>'; $frameCount++; } echo "</tr></thead><tbody>\n"; $firstFrame = 0; $maxThumbWidth = 0; foreach ($tests as &$test) { $aft = (int) $test['aft'] / 100; // figure out the height of the image $height = 0; $width = $thumbSize; if ($test['video']['width'] && $test['video']['height']) { if ($test['video']['width'] > $test['video']['height']) { $width = $thumbSize; $height = (int) ((double) $thumbSize / (double) $test['video']['width'] * (double) $test['video']['height']); } else { $height = $thumbSize; $width = (int) ((double) $thumbSize / (double) $test['video']['height'] * (double) $test['video']['width']); } } $maxThumbWidth = max($maxThumbWidth, $width); echo "<tr>"; $testEnd = ceil($test['video']['end'] / $interval) * $interval; $lastThumb = null; $frameCount = 0; $progress = null; $ms = 0; while ($ms < $filmstrip_end_time) { $ms = $frameCount * $interval; // find the closest video frame <= the target time $frame_ms = null; foreach ($test['video']['frames'] as $frameTime => $file) { if ($frameTime <= $ms && (!isset($frame_ms) || $frameTime > $frame_ms)) { $frame_ms = $frameTime; } } $path = null; if (isset($frame_ms)) { $path = $test['video']['frames'][$frame_ms]; } if (array_key_exists('frame_progress', $test['video']) && array_key_exists($frame_ms, $test['video']['frame_progress'])) { $progress = $test['video']['frame_progress'][$frame_ms]; } if (!isset($lastThumb)) { $lastThumb = $path; } echo '<td>'; if ($ms <= $testEnd) { $cached = ''; if ($test['cached']) { $cached = '_cached'; } $imgPath = GetTestPath($test['id']) . "/video_{$test['run']}{$cached}/{$path}"; echo "<a href=\"/{$imgPath}\">"; echo "<img title=\"" . htmlspecialchars($test['name']) . "\""; $class = 'thumb'; if ($lastThumb != $path) { if (!$firstFrame || $frameCount < $firstFrame) { $firstFrame = $frameCount; } $class = 'thumbChanged'; } echo " class=\"{$class}\""; echo " width=\"{$width}\""; if ($height) { echo " height=\"{$height}\""; } echo " src=\"/thumbnail.php?test={$test['id']}&fit={$thumbSize}&file=video_{$test['run']}{$cached}/{$path}\"></a>"; if (isset($progress)) { echo "<br>{$progress}%"; } $lastThumb = $path; } $frameCount++; echo '</td>'; } echo "</tr>\n"; } echo "</tr>\n"; // end of the table echo "</tbody></table></div>\n"; // end of the container table echo "</td></tr></table>\n"; echo "<div id=\"image\">"; echo "<a id=\"export\" class=\"pagelink\" href=\"filmstrip.php?tests={$_REQUEST['tests']}&thumbSize={$thumbSize}&ival={$interval}&end={$endTime}&text={$color}&bg={$bgcolor}\">Export filmstrip as an image...</a>"; echo "</div>"; echo '<div id="bottom"><input type="checkbox" name="slow" value="1"> Slow Motion<br><br>'; echo "<input id=\"SubmitBtn\" type=\"submit\" value=\"Create Video\">"; echo '<br><br><a class="pagelink" href="javascript:ShowAdvanced()">Advanced customization options...</a>'; echo "</div></form>"; if (!defined('EMBED')) { ?> <div id="layout"> <form id="layoutForm" name="layout" method="get" action="/video/compare.php"> <?php echo "<input type=\"hidden\" name=\"tests\" value=\"{$_REQUEST['tests']}\">\n"; ?> <table id="layoutTable"> <tr><th>Thumbnail Size</th><th>Thumbnail Interval</th><th>Comparison End Point</th></th></tr> <?php // fill in the thumbnail size selection echo "<tr><td>"; $checked = ''; if ($thumbSize <= 100) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"thumbSize\" value=\"100\"{$checked} onclick=\"this.form.submit();\"> Small<br>"; $checked = ''; if ($thumbSize <= 150 && $thumbSize > 100) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"thumbSize\" value=\"150\"{$checked} onclick=\"this.form.submit();\"> Medium<br>"; $checked = ''; if ($thumbSize > 150) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"thumbSize\" value=\"200\"{$checked} onclick=\"this.form.submit();\"> Large"; echo "</td>"; // fill in the interval selection echo "<td>"; if ($supports60fps) { $checked = ''; if ($interval < 100) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"16.67\"{$checked} onclick=\"this.form.submit();\"> 60 FPS<br>"; } $checked = ''; if ($supports60fps && $interval == 100 || !$supports60fps && $interval < 500) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"100\"{$checked} onclick=\"this.form.submit();\"> 0.1 sec<br>"; $checked = ''; if ($interval == 500) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"500\"{$checked} onclick=\"this.form.submit();\"> 0.5 sec<br>"; $checked = ''; if ($interval == 1000) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"1000\"{$checked} onclick=\"this.form.submit();\"> 1 sec<br>"; $checked = ''; if ($interval > 1000) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"5000\"{$checked} onclick=\"this.form.submit();\"> 5 sec<br>"; echo "</td>"; // fill in the end-point selection echo "<td>"; if (!strcasecmp($endTime, 'aft')) { $endTime = 'visual'; } $checked = ''; if (!strcasecmp($endTime, 'visual')) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"end\" value=\"visual\"{$checked} onclick=\"this.form.submit();\"> Visually Complete<br>"; $checked = ''; if (!strcasecmp($endTime, 'all')) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"end\" value=\"all\"{$checked} onclick=\"this.form.submit();\"> Last Change<br>"; $checked = ''; if (!strcasecmp($endTime, 'doc')) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"end\" value=\"doc\"{$checked} onclick=\"this.form.submit();\"> Document Complete<br>"; $checked = ''; if (!strcasecmp($endTime, 'full')) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"end\" value=\"full\"{$checked} onclick=\"this.form.submit();\"> Fully Loaded<br>"; echo "</td></tr>"; ?> </table> </form> </div> <?php // display the waterfall if there is only one test $end_seconds = $filmstrip_end_time / 1000; if (count($tests) == 1) { $data = loadPageRunData($tests[0]['path'], $tests[0]['run'], $tests[0]['cached']); $secure = false; $haveLocations = false; $requests = getRequests($tests[0]['id'], $tests[0]['path'], $tests[0]['run'], $tests[0]['cached'], $secure, $haveLocations, true, true); InsertWaterfall('', $requests, $tests[0]['id'], $tests[0]['run'], $tests[0]['cached'], $data, "&max={$end_seconds}&mime=1&state=1&cpu=1&bw=1"); echo '<br><br>'; } else { $waterfalls = array(); foreach ($tests as &$test) { $waterfalls[] = array('id' => $test['id'], 'label' => $test['name'], 'run' => $test['run'], 'cached' => $test['cached']); } $labels = ''; if (array_key_exists('hideurls', $_REQUEST) && $_REQUEST['hideurls']) { $labels = '&labels=0'; } InsertMultiWaterfall($waterfalls, "&max={$end_seconds}&mime=1&state=1&cpu=1&bw=1{$labels}"); } ?> <div id="advanced" style="display:none;"> <h3>Advanced Visual Comparison Configuration</h3> <p>There are additional customizations that can be done by modifying the <b>tests</b> parameter in the comparison URL directly.</p> <p>URL structure: ...compare.php?tests=<Test 1 ID>,<Test 2 ID>...</p> <p>The tests are displayed in the order listed and can be customized with options:</p> <table> <tr><td>Custom label</td><td>-l:<label></td><td>110606_MJ_RZEY-l:Original</td></tr> <tr><td>Specific run</td><td>-r:<run></td><td>110606_MJ_RZEY-r:3</td></tr> <tr><td>Repeat view</td><td>-c:1</td><td>110606_MJ_RZEY-c:1</td></tr> <tr><td>Specific End Time</td><td>-e:<seconds></td><td>110606_MJ_RZEY-e:1.1</td></tr> </table> <br> <p>You can also customize the background and text color by passing HTML color values to <b>bg</b> and <b>text</b> query parameters.</p> <p>Examples:</p> <ul> <li><b>Customizing labels:</b> http://www.webpagetest.org/video/compare.php?tests=110606_MJ_RZEY-l:Original,110606_AE_RZN5-l:No+JS</li> <li><b>Compare First vs. Repeat view:</b> http://www.webpagetest.org/video/compare.php?tests=110606_MJ_RZEY, 110606_MJ_RZEY-c:1</li> <li><b>White background with black text:</b> http://www.webpagetest.org/video/compare.php?tests=110606_MJ_RZEY, 110606_MJ_RZEY-c:1&bg=ffffff&text=000000</li> </ul> <input id="advanced-ok" type=button class="simplemodal-close" value="OK"> </div> <?php } // EMBED // scroll the table to show the first thumbnail change $scrollPos = $firstFrame * ($maxThumbWidth + 6); ?> <script language="javascript"> var thumbWidth = <?php echo "{$maxThumbWidth};"; ?> var scrollPos = <?php echo "{$scrollPos};"; ?> document.getElementById("videoDiv").scrollLeft = scrollPos; </script> <?php } }
<?php header("Content-type: image/png"); include 'common.inc'; include 'object_detail.inc'; include 'contentColors.inc'; include 'connectionView.inc'; include 'page_data.inc'; $pageData = loadPageRunData($testPath, $run, $cached); $mime = $_GET['mime']; // get all of the requests $secure = false; $haveLocations = false; $requests = getRequests($id, $testPath, $run, $cached, $secure, $haveLocations, false); $mimeColors = requestColors($requests); $summary = array(); $connections = getConnections($requests, $summary); $options = array('id' => $id, 'path' => $testPath, 'run' => $run, 'cached' => $cached, 'cpu' => true, 'bw' => true); $im = drawImage($connections, $summary, $url, $mime, $mimeColors, false, $pageData, $options); // spit the image out to the browser imagepng($im); imagedestroy($im);
function SpeedIndex($testPath, $run, $cached, $testInfo) { $speed_index = ''; $pageData = loadPageRunData($testPath, $run, $cached, null, $testInfo); $startOffset = array_key_exists('testStartOffset', $pageData) ? intval(round($pageData['testStartOffset'])) : 0; $progress = GetVisualProgress($testPath, $run, $cached, null, null, $startOffset); if (isset($progress) && is_array($progress) && array_key_exists('SpeedIndex', $progress)) { $speed_index = $progress['SpeedIndex']; } return $speed_index; }
echo '">'; ?> <br> </div> <br> <?php include './ads/optimization_middle.inc'; ?> <br> <h2>Details:</h2> <?php require 'optimization.inc'; require_once 'page_data.inc'; $pageData = loadPageRunData($testPath, $run, $cached, null, $test['testinfo']); require_once 'object_detail.inc'; $secure = false; $haveLocations = false; $requests = getRequests($id, $testPath, $run, $cached, $secure, $haveLocations, false); dumpOptimizationReport($pageData, $requests, $id, $run, $cached, $test); echo '<p></p><br>'; include './ads/optimization_bottom.inc'; echo '<br>'; dumpOptimizationGlossary($settings); ?> <?php include 'footer.inc'; ?> </div>
<?php header("Content-type: image/png"); include 'common.inc'; require_once 'object_detail.inc'; require_once 'page_data.inc'; require_once 'waterfall.inc'; $page_data = loadPageRunData($testPath, $run, $cached, $requests); $is_mime = (bool) @$_REQUEST['mime']; $is_state = (bool) @$_REQUEST['state']; $use_dots = !isset($_REQUEST['dots']) || $_REQUEST['dots'] != 0; $show_labels = !isset($_REQUEST['labels']) || $_REQUEST['labels'] != 0; $rowcount = array_key_exists('rowcount', $_REQUEST) ? $_REQUEST['rowcount'] : 0; // Get all of the requests; $is_secure = false; $has_locations = false; $use_location_check = false; if (!isset($requests)) { $requests = getRequests($id, $testPath, $run, $cached, $is_secure, $has_locations, $use_location_check); } else { // not multisteps enabled $requests = $requests[$run][$cached]; fixRequests($requests, $id, $testPath, $run, $cached, $is_secure, $has_locations, $use_location_check); } if (@$_REQUEST['type'] == 'connection') { $is_state = true; $rows = GetConnectionRows($requests, $show_labels); } else { $rows = GetRequestRows($requests, $use_dots, $show_labels); } $page_events = GetPageEvents($page_data);
/** * Parse the page data and load the optimization-specific details * * @param mixed $testPath * @param mixed $run * @param mixed $cached * @param mixed $includeObject */ function getOptimizationDetails($testPath, $run, $cached, $includeObject) { $opt = null; $pageData = loadPageRunData($testPath, $run, $cached); if ($pageData) { $opt = array(); // put them in rank-order $opt['keep-alive'] = array(); $opt['gzip'] = array(); $opt['image_compression'] = array(); $opt['caching'] = array(); $opt['combine'] = array(); $opt['cdn'] = array(); $opt['cookies'] = array(); $opt['minify'] = array(); $opt['e-tags'] = array(); // get the scores $opt['keep-alive']['score'] = $pageData['score_keep-alive']; $opt['gzip']['score'] = $pageData['score_gzip']; $opt['image_compression']['score'] = $pageData['score_compress']; $opt['caching']['score'] = $pageData['score_cache']; $opt['combine']['score'] = $pageData['score_combine']; $opt['cdn']['score'] = $pageData['score_cdn']; $opt['cookies']['score'] = $pageData['score_cookies']; $opt['minify']['score'] = $pageData['score_minify']; $opt['e-tags']['score'] = $pageData['score_etags']; // define the labels for all of them $opt['keep-alive']['label'] = 'Enable keep-alive'; $opt['gzip']['label'] = 'Compress Text'; $opt['image_compression']['label'] = 'Compress Images'; $opt['caching']['label'] = 'Cache static content'; $opt['combine']['label'] = 'Combine js and css files'; $opt['cdn']['label'] = 'Use a CDN'; $opt['cookies']['label'] = 'No cookies on static content'; $opt['minify']['label'] = 'Minify javascript'; $opt['e-tags']['label'] = 'Disable E-Tags'; // flag the important ones $opt['keep-alive']['important'] = true; $opt['gzip']['important'] = true; $opt['image_compression']['important'] = true; $opt['caching']['important'] = true; $opt['combine']['important'] = true; $opt['cdn']['important'] = true; // apply grades foreach ($opt as &$item) { $grade = 'N/A'; $weight = 0; if (isset($item['score'])) { $weight = 100; if ($item['score'] >= 90) { $grade = 'A'; } elseif ($item['score'] >= 80) { $grade = 'B'; } elseif ($item['score'] >= 70) { $grade = 'C'; } elseif ($item['score'] >= 60) { $grade = 'D'; } elseif ($item['score'] >= 0) { $grade = 'F'; } else { $weight = 0; } } $item['grade'] = $grade; $item['weight'] = $weight; } } return $opt; }
public function testLoadPageRunData() { echo $this->resultPath . "\n"; $pageRunData = loadPageRunData($this->resultPath, 1, 0); $this->assertArraySubset($this->expectedData, $pageRunData); }
require_once __DIR__ . '/include/TestInfo.php'; require_once __DIR__ . '/include/TestRunResults.php'; require_once __DIR__ . '/include/RunResultHtmlTable.php'; require_once __DIR__ . '/include/UserTimingHtmlTable.php'; require_once __DIR__ . '/include/WaterfallViewHtmlSnippet.php'; require_once __DIR__ . '/include/ConnectionViewHtmlSnippet.php'; require_once __DIR__ . '/include/RequestDetailsHtmlSnippet.php'; require_once __DIR__ . '/include/RequestHeadersHtmlSnippet.php'; require_once __DIR__ . '/include/AccordionHtmlHelper.php'; $options = null; if (array_key_exists('end', $_REQUEST)) { $options = array('end' => $_REQUEST['end']); } $testInfo = TestInfo::fromFiles($testPath); $testRunResults = TestRunResults::fromFiles($testInfo, $run, $cached, null, $options); $data = loadPageRunData($testPath, $run, $cached, $options, $test['testinfo']); $isMultistep = $testRunResults->countSteps() > 1; $page_keywords = array('Performance Test', 'Details', 'Webpagetest', 'Website Speed Test', 'Page Speed'); $page_description = "Website performance test details{$testLabel}"; ?> <!DOCTYPE html> <html> <head> <title>WebPagetest Test Details<?php echo $testLabel; ?> </title> <?php $gaTemplate = 'Details'; include 'head.inc'; ?>
<td> <div id="tableRequestsRv_div" style="width: 100%;"></div> </td> <td> <div id="tableBytesRv_div" style="width: 100%;"></div> </td> </tr> </table> <div style="text-align:center;"> <h3 name="connection">Connection View (Repeat View)</h3> <map name="connection_map_rv"> <?php $mimeColors = requestColors($requestsRv); $summary = array(); $connections = getConnections($requestsRv, $summary); $pageData = loadPageRunData($testPath, $run, 1); $options = array('id' => $id, 'path' => $testPath, 'run' => $run, 'cached' => $cached, 'cpu' => true); $map = drawImage($connections, $summary, $url, $mime, $mimeColors, true, $pageData, $options); foreach ($map as $entry) { if ($entry['request'] !== NULL) { $index = $entry['request'] + 1; $title = $index . ': ' . $entry['url']; echo '<area href="#request' . $index . '" alt="' . $title . '" title="' . $title . '" shape=RECT coords="' . $entry['left'] . ',' . $entry['top'] . ',' . $entry['right'] . ',' . $entry['bottom'] . '">' . "\n"; } else { echo '<area href="#request" alt="' . $entry['url'] . '" title="' . $entry['url'] . '" shape=RECT coords="' . $entry['left'] . ',' . $entry['top'] . ',' . $entry['right'] . ',' . $entry['bottom'] . '">' . "\n"; } } ?> </map> <table border="1" cellpadding="2px" cellspacing="0" style="width:auto; font-size:70%; margin-left:auto; margin-right:auto;"> <tr>
<?php include 'common.inc'; require_once 'object_detail.inc'; require_once 'page_data.inc'; require_once 'waterfall.inc'; $options = null; if (array_key_exists('end', $_REQUEST)) { $options = array('end' => $_REQUEST['end']); } $data = loadPageRunData($testPath, $run, $cached, $options); $page_keywords = array('Performance Test', 'Details', 'Webpagetest', 'Website Speed Test', 'Page Speed'); $page_description = "Website performance test details{$testLabel}"; ?> <!DOCTYPE html> <html> <head> <title>WebPagetest Test Details<?php echo $testLabel; ?> </title> <?php $gaTemplate = 'Details'; include 'head.inc'; ?> <style type="text/css"> div.bar { height:12px; margin-top:auto; margin-bottom:auto; }
/** * Draw the checklist image * * @param resource $img */ function tbnDrawChecklist(&$img) { global $id; global $testPath; global $run; global $cached; global $url; include 'optimizationChecklist.inc'; $is_secure = false; $has_locations = false; $requests = getRequests($id, $testPath, $run, $cached, $is_secure, $has_locations, false); $page_data = loadPageRunData($testPath, $run, $cached); $img = drawChecklist($url, $requests, $page_data); if (!$requests || !$page_data) { $failed = true; } }
$pageData; if (isset($_REQUEST["run"]) && $_REQUEST["run"]) { if (!strcasecmp($_REQUEST["run"], 'median')) { $raw = loadAllPageData($testPath); $run = GetMedianRun($raw, $cached, $median_metric); if (!$run) { $run = 1; } unset($raw); } $pageData[$run] = array(); if (isset($cached)) { $pageData[$run][$cached] = loadPageRunData($testPath, $run, $cached); } else { $pageData[$run][0] = loadPageRunData($testPath, $run, 0); $pageData[$run][1] = loadPageRunData($testPath, $run, 1); } } else { $pageData = loadAllPageData($testPath); } // build up the array $result = BuildResult($pageData); // spit it out as json $filename = ''; if (@strlen($url)) { $parts = parse_url($url); $filename = $parts['host']; } if (!strlen($filename)) { $filename = "pagetest"; }
/** * Build a side-by-side table with the captured frames from each test * */ function ScreenShotTable() { global $tests; global $thumbSize; global $interval; global $maxCompare; if (count($tests)) { // figure out how many columns there are $end = 0; foreach ($tests as &$test) { if ($test['video']['end'] > $end) { $end = $test['video']['end']; } } echo '<br/><form id="createForm" name="create" method="get" action="/video/create.php" onsubmit="return ValidateInput(this)"><table id="videoContainer"><tr>'; // build a table with the labels echo '<td id="labelContainer"><table id="videoLabels"><tr><th> </th></tr>'; foreach ($tests as &$test) { // figure out the height of this video $height = 100; if ($test['video']['width'] && $test['video']['height']) { $height = 10 + (int) ((double) $thumbSize / (double) $test['video']['width'] * (double) $test['video']['height']); } $break = ''; if (!strpos($test['name'], ' ')) { $break = ' style="word-break: break-all;"'; } echo "<tr width=10% height={$height}px ><td{$break}>"; $name = urlencode($test['name']); $cached = 0; if ($test['cached']) { $cached = 1; } echo "<input type=\"checkbox\" name=\"t[]\" value=\"{$test['id']},{$test['run']}," . $name . ",{$cached}\" checked=checked> "; $cached = ''; if ($test['cached']) { $cached = 'cached/'; } echo "<a class=\"pagelink\" href=\"/result/{$test['id']}/{$test['run']}/details/{$cached}\" target=\"_blank\">"; echo WrapableString($test['name']); echo "</a></td></tr>\n"; } echo '</table></td>'; // the actual video frames echo '<td><div id="videoDiv"><table id="video"><thead><tr>'; $skipped = $interval; $last = $end + $interval - 1; for ($frame = 0; $frame <= $last; $frame++) { $skipped++; if ($skipped >= $interval) { $skipped = 0; echo '<th>' . number_format((double) $frame / 10.0, 1) . 's</th>'; } } echo "</tr></thead><tbody>\n"; $firstFrame = 0; foreach ($tests as &$test) { // figure out the height of the image $height = 0; if ($test['video']['width'] && $test['video']['height']) { $height = (int) ((double) $thumbSize / (double) $test['video']['width'] * (double) $test['video']['height']); } echo "<tr>"; $lastThumb = null; $frameCount = 0; $skipped = $interval; $last = $end + $interval - 1; for ($frame = 0; $frame <= $last; $frame++) { $path = $test['video']['frames'][$frame]; if (isset($path)) { $test['currentframe'] = $frame; } else { if (isset($test['currentframe'])) { $path = $test['video']['frames'][$test['currentframe']]; } else { $path = $test['video']['frames'][0]; } } if (!$lastThumb) { $lastThumb = $path; } $skipped++; if ($skipped >= $interval) { $skipped = 0; echo '<td>'; if ($frame - $interval + 1 <= $test['video']['end']) { echo ''; $cached = ''; if ($test['cached']) { $cached = '_cached'; } $imgPath = GetTestPath($test['id']) . "/video_{$test['run']}{$cached}/{$path}"; echo "<a href=\"/{$imgPath}\">"; echo "<img title=\"{$test['name']}\""; $class = 'thumb'; if ($lastThumb != $path) { if (!$firstFrame || $frameCount < $firstFrame) { $firstFrame = $frameCount; } $class = 'thumbChanged'; } echo " class=\"{$class}\""; echo " width=\"{$thumbSize}\""; if ($height) { echo " height=\"{$height}\""; } echo " src=\"/thumbnail.php?test={$test['id']}&width={$thumbSize}&file=video_{$test['run']}{$cached}/{$path}\"></a>"; $lastThumb = $path; } $frameCount++; echo '</td>'; } } echo "</tr>\n"; } echo "</tr>\n"; // end of the table echo "</tbody></table></div>\n"; // end of the container table echo "</td></tr></table>\n"; echo "<div id=\"image\">"; $ival = $interval * 100; echo "<a class=\"pagelink\" href=\"filmstrip.php?tests={$_REQUEST['tests']}&thumbSize={$thumbSize}&ival={$ival}\">Export filmstrip as an image...</a>"; echo "</div>"; echo '<div id="bottom"><input type="checkbox" name="slow" value="1"> Slow Motion<br/><br/>'; echo "Select up to {$maxCompare} tests and <input id=\"SubmitBtn\" type=\"submit\" value=\"Create Video\"></div>"; echo "</form>"; ?> <div id="layout"> <form id="layoutForm" name="layout" method="get" action="/video/compare.php"> <?php echo "<input type=\"hidden\" name=\"tests\" value=\"{$_REQUEST['tests']}\" />\n"; ?> <table id="layoutTable"> <tr><th>Thumbnail Size</th><th>Thumbnail Interval</th></tr> <?php // fill in the thumbnail size selection echo "<tr><td>"; $checked = ''; if ($thumbSize <= 100) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"thumbSize\" value=\"100\"{$checked} onclick=\"this.form.submit();\"> Small<br>"; $checked = ''; if ($thumbSize <= 150 && $thumbSize > 100) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"thumbSize\" value=\"150\"{$checked} onclick=\"this.form.submit();\"> Medium<br>"; $checked = ''; if ($thumbSize > 150) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"thumbSize\" value=\"200\"{$checked} onclick=\"this.form.submit();\"> Large"; echo "</td>"; // fill in the interval selection echo "<td>"; $checked = ''; if ($interval <= 1) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"100\"{$checked} onclick=\"this.form.submit();\"> 0.1 sec<br>"; $checked = ''; if ($interval == 5) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"500\"{$checked} onclick=\"this.form.submit();\"> 0.5 sec<br>"; $checked = ''; if ($interval == 10) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"1000\"{$checked} onclick=\"this.form.submit();\"> 1 sec<br>"; $checked = ''; if ($interval == 50) { $checked = ' checked=checked'; } echo "<input type=\"radio\" name=\"ival\" value=\"5000\"{$checked} onclick=\"this.form.submit();\"> 5 sec<br>"; echo "</td></tr>"; ?> </table> </form> </div> <?php // scroll the table to show the first thumbnail change $scrollPos = $firstFrame * ($thumbSize + 8); ?> <script language="javascript"> var scrollPos = <?php echo "{$scrollPos};"; ?> document.getElementById("videoDiv").scrollLeft = scrollPos; </script> <?php // display the waterfall if there is only one test if (count($tests) == 1) { ?> <div id="waterfall"> <map name="waterfall_map"> <?php $data = loadPageRunData($tests[0]['path'], $tests[0]['run'], $tests[0]['cached']); $secure = false; $haveLocations = false; $requests = getRequests($tests[0]['id'], $tests[0]['path'], $tests[0]['run'], $tests[0]['cached'], $secure, $haveLocations, false); $options = array('id' => $tests[0]['id'], 'path' => $tests[0]['path'], 'run' => $tests[0]['run'], 'cached' => $tests[0]['cached'], 'cpu' => false); $map = drawWaterfall($tests[0]['url'], $requests, $data, true, $options); foreach ($map as $entry) { if ($entry['request'] !== NULL) { $index = $entry['request'] + 1; $title = $index . ': ' . $entry['url']; echo '<area alt="' . $title . '" title="' . $title . '" shape=RECT coords="' . $entry['left'] . ',' . $entry['top'] . ',' . $entry['right'] . ',' . $entry['bottom'] . '">' . "\n"; } else { echo '<area alt="' . $entry['url'] . '" title="' . $entry['url'] . '" shape=RECT coords="' . $entry['left'] . ',' . $entry['top'] . ',' . $entry['right'] . ',' . $entry['bottom'] . '">' . "\n"; } } ?> </map> <?php echo "<img id=\"waterfallImage\" usemap=\"#waterfall_map\" border=\"0\" alt=\"Waterfall\" src=\"/waterfall.php?test={$tests[0]['id']}&run={$tests[0]['run']}&cached={$tests[0]['cached']}&cpu=0&bw=0\">"; ?> </div> <?php } echo '<br/><br/>'; } }
$testInfo .= "id={$id}\r\n"; if ($test['video']) { $testInfo .= "video=1\r\n"; } $testInfo .= "connectivity=Unknown\r\n"; $testInfo .= "\r\n[runs]\r\n"; file_put_contents("{$testPath}/testinfo.ini", $testInfo); // write out the bulk test data $bulk = array(); $bulk['variations'] = array(); $bulk['urls'] = array(); foreach ($tests as &$test_id) { if (ValidateTestId($test_id)) { RestoreTest($test_id); $test_path = './' . GetTestPath($test_id); $pageData = loadPageRunData($test_path, 1, 0); $url = 'Imported Test'; if ($pageData && array_key_exists('URL', $pageData)) { $url = $pageData['URL']; } $bulk['urls'][] = array('u' => $url, 'id' => $test_id); } } gz_file_put_contents("{$testPath}/bulk.json", json_encode($bulk)); // Return the test ID (or redirect if not using the API) TestResult($test, $error); } elseif (array_key_exists('devtools', $_FILES)) { if (ValidateKey()) { /**************************************************************************** * Importing a test ****************************************************************************/