/** * RequestDetailsHtmlSnippet constructor. * @param TestInfo $testInfo * @param TestStepResult $stepResult * @param bool $useLinks */ public function __construct($testInfo, $stepResult, $useLinks) { $this->testInfo = $testInfo; $this->stepResult = $stepResult; $this->requests = $stepResult->getRequestsWithInfo(true, true); $this->useLinks = $useLinks; }
/** * Parse the page data and load the optimization-specific details for one step * * @param TestInfo $testInfo Test information * @param TestStepResult $testStepResult Results of the step to get the grades for * @return array|null An array with all labels, scores, grades, weights, etc per score */ function getOptimizationGradesForStep($testInfo, $testStepResult) { // The function getOptimizationGradesForRun is more powerful as it can compute averages. // With one step, it will do exactly what we want, so we create an artificial run $singlestepRunResult = TestRunResults::fromStepResults($testInfo, $testStepResult->getRunNumber(), $testStepResult->isCachedRun(), array($testStepResult)); return getOptimizationGradesForRun($singlestepRunResult); }
/** * WaterfallViewHtmlSnippet constructor. * @param TestInfo $testInfo * @param TestStepResult $stepResult * @param bool $enableCsi True if CSI data should be enabled */ public function __construct($testInfo, $stepResult, $enableCsi) { $this->testInfo = $testInfo; $this->stepResult = $stepResult; $this->requests = $stepResult->getRequestsWithInfo(true, true); $this->hasCsi = $enableCsi; }
/** * ConnectionViewHtmlSnippet constructor. * @param TestInfo $testInfo * @param TestStepResult $stepResult */ public function __construct($testInfo, $stepResult) { $this->testInfo = $testInfo; $this->stepResult = $stepResult; $this->requests = $stepResult->getRequestsWithInfo(true, true); $cached = $this->stepResult->isCachedRun() ? "rv_" : "fv_"; $this->mapName = "#connection_map_" . $cached . $this->stepResult->getStepNumber(); $this->imageId = "connectionView_" . $cached . $this->stepResult->getStepNumber(); }
/** * Constructs a new TestRunResults object by loading the results from the file system * @param TestInfo $testInfo Associated test info * @param int $runNumber The run number * @param bool $isCached False for first view, true for repeat view (cached) * @param FileHandler $fileHandler The FileHandler to use * @param array $options Options for loading the TestStepData * @return TestRunResults|null The initialized object or null if it failed */ public static function fromFiles($testInfo, $runNumber, $isCached, $fileHandler = null, $options = null) { $stepResults = array(); $isValid = false; for ($stepNumber = 1; $stepNumber <= $testInfo->stepsInRun($runNumber); $stepNumber++) { $stepResult = TestStepResult::fromFiles($testInfo, $runNumber, $isCached, $stepNumber, $fileHandler, $options); $stepResults[] = $stepResult; $isValid = $isValid || $stepResult !== null; } return $isValid ? new self($testInfo, $runNumber, $isCached, $stepResults) : null; }
/** * @param TestStepResult $testStepResult The test results of this step * @param UrlGenerator $urlGenerator For video frame URL generation for this tep * @param TestPaths $nameOnlyPaths To get the name of the video dir for this step * @return array Array with the additional information about this step */ private function getAdditionalInfoArray($testStepResult, $urlGenerator, $nameOnlyPaths) { $ret = array(); $progress = $testStepResult->getVisualProgress(); if (array_key_exists('frames', $progress) && is_array($progress['frames']) && count($progress['frames'])) { $ret['videoFrames'] = array(); foreach ($progress['frames'] as $ms => $frame) { $videoFrame = array('time' => $ms); $videoFrame['image'] = $urlGenerator->getFile($frame['file'], $nameOnlyPaths->videoDir()); $videoFrame['VisuallyComplete'] = $frame['progress']; $ret['videoFrames'][] = $videoFrame; } } $requests = $testStepResult->getRequests(); $ret['domains'] = $testStepResult->getDomainBreakdown(); $ret['breakdown'] = $testStepResult->getMimeTypeBreakdown(); // add requests if (!$this->hasInfoFlag(self::WITHOUT_REQUESTS)) { $ret['requests'] = $requests; } // Check to see if we're adding the console log if (!$this->hasInfoFlag(self::WITHOUT_CONSOLE)) { $console_log = $testStepResult->getConsoleLog(); if (isset($console_log)) { $ret['consoleLog'] = $console_log; } } $statusMessages = $testStepResult->getStatusMessages(); if ($statusMessages) { $ret['status'] = $statusMessages; return $ret; } return $ret; }
/** * @param TestStepResult $stepResult */ protected function __construct($stepResult) { $this->breakdownId = "breakdown_" . ($stepResult->isCachedRun() ? "rv" : "fv") . "_step_" . $stepResult->getStepNumber(); }
private function getTestRunResultsWithInvalid() { $step4 = array('result' => 404, 'TTFB' => 500, 'loadTime' => 1000); // result is error $steps = $this->getTestStepArray(); $steps[] = TestStepResult::fromPageData($this->testInfo, $step4, 2, false, 4); return TestRunResults::fromStepResults($this->testInfo, 2, false, $steps); }
/** * @param TestStepResult $stepResult * @return string Markup with label */ private function _getResultLabel($stepResult) { $out = ""; $error = $this->testInfo->getRunError($stepResult->getRunNumber(), $stepResult->isCachedRun()); if ($error) { $out .= '<br>(Test Error: ' . htmlspecialchars($error) . ')'; } $result = $stepResult->getMetric("result"); $loadTime = $stepResult->getMetric("loadTime"); if ($result !== null && $result !== 0 && $result !== 99999) { $out .= '<br>(Error: ' . LookupError($result) . ')'; } else { if ($loadTime !== null) { $out .= '<br>(' . number_format($loadTime / 1000.0, 3) . 's)'; } } return $out; }
/** * Draw the checklist image * * @param TestStepResult $testStepResult Step results to draw the waterfall for * @param resource $img */ function tbnDrawChecklist($testStepResult, &$img) { global $url; require_once __DIR__ . '/optimizationChecklist.inc'; $requests = $testStepResult->getRequests(); $img = drawChecklist($testStepResult->readableIdentifier($url), $requests, $testStepResult->getRawResults()); }
/** * @param FileHandler $fileHandler FileHandler to use * @param TestInfo $testInfo Information about the test * @param TestStepResult $testStepResult Results of the specific test * @param bool $useQuicklinks True if quicklinks are used, false otherwise */ function printStep($fileHandler, $testInfo, $testStepResult, $useQuicklinks) { $pageRunData = $testStepResult->getRawResults(); $localPaths = $testStepResult->createTestPaths(); $urlPaths = $testStepResult->createTestPaths(substr($testInfo->getRootDirectory(), 1)); $urlGenerator = $testStepResult->createUrlGenerator("", FRIENDLY_URLS); echo "<a name=\"step_" . $testStepResult->getStepNumber() . "\">"; echo "<h1 class='stepName'>" . $testStepResult->readableIdentifier() . "</h1>"; echo "</a>"; if ($fileHandler->dirExists($localPaths->videoDir())) { echo "<a href=\"" . $urlGenerator->createVideo() . "\">Create Video</a> • "; echo "<a href=\"" . $urlGenerator->downloadVideoFrames() . "\">Download Video Frames</a>"; if ($useQuicklinks) { echo " • "; } } if ($useQuicklinks) { echo '<a href="#quicklinks">Back to Quicklinks</a>'; } $screenShotUrl = null; if ($fileHandler->fileExists($localPaths->screenShotPngFile())) { $screenShotUrl = $urlPaths->screenShotPngFile(); } else { if ($fileHandler->fileExists($localPaths->screenShotFile())) { $screenShotUrl = $urlPaths->screenShotFile(); } } if ($screenShotUrl) { echo '<h2>Fully Loaded</h2>'; echo '<a href="' . $screenShotUrl . '">'; echo '<img class="center" alt="Screen Shot" style="max-width:930px; -ms-interpolation-mode: bicubic;" src="' . $screenShotUrl . '">'; echo '</a>'; } // display the last status message if we have one $messages = $testStepResult->getStatusMessages(); if (count($messages)) { $lastMessage = end($messages); if (strlen($lastMessage['message'])) { echo "\n<br>Last Status Message: \"{$lastMessage['message']}\"\n"; } } $stepNumber = $testStepResult->getStepNumber(); $linkSuffix = $stepNumber > 1 ? "_" . $stepNumber : ""; if ($fileHandler->fileExists($localPaths->additionalScreenShotFile("render"))) { echo '<br><br><a name="start_render' . $linkSuffix . '"><h2>Start Render'; if (isset($pageRunData) && isset($pageRunData['render'])) { echo ' (' . number_format($pageRunData['render'] / 1000.0, 3) . ' sec)'; } echo '</h2></a>'; echo '<img class="center" alt="Start Render Screen Shot" src="' . $urlPaths->additionalScreenShotFile("render") . '">'; } if ($fileHandler->fileExists($localPaths->additionalScreenShotFile("dom"))) { echo '<br><br><a name="dom_element' . $linkSuffix . '"><h2>DOM Element'; if (isset($pageRunData) && isset($pageRunData['domTime'])) { echo ' (' . number_format($pageRunData['domTime'] / 1000.0, 3) . ' sec)'; } echo '</h2></a>'; echo '<img class="center" alt="DOM Element Screen Shot" src="' . $urlPaths->additionalScreenShotFile("dom") . '">'; } if ($fileHandler->fileExists($localPaths->additionalScreenShotFile("doc"))) { echo '<br><br><a name="doc_complete' . $linkSuffix . '"><h2>Document Complete'; if (isset($pageRunData) && isset($pageRunData['docTime'])) { echo ' (' . number_format($pageRunData['docTime'] / 1000.0, 3) . ' sec)'; } echo '</h2></a>'; echo '<img class="center" alt="Document Complete Screen Shot" src="' . $urlPaths->additionalScreenShotFile("doc") . '">'; } if ($fileHandler->fileExists($localPaths->aftDiagnosticImageFile())) { echo '<br><br><a name="aft' . $linkSuffix . '"><h2>AFT Details'; if (isset($pageRunData) && isset($pageRunData['aft'])) { echo ' (' . number_format($pageRunData['aft'] / 1000.0, 3) . ' sec)'; } echo '</h2></a>'; echo 'White = Stabilized Early, Blue = Dynamic, Red = Late Static (failed AFT), Green = AFT<br>'; echo '<img class="center" alt="AFT Diagnostic image" src="' . $urlPaths->aftDiagnosticImageFile() . '">'; } if ($fileHandler->fileExists($localPaths->additionalScreenShotFile("responsive"))) { echo '<br><br><h2 id="responsive">Responsive Site Check</h2>'; echo '<img class="center" alt="Responsive Site Check image" src="' . $urlPaths->additionalScreenShotFile("responsive") . '">'; } // display all of the status messages if (count($messages)) { echo "\n<br><br><a name=\"status_messages" . $linkSuffix . "\"><h2>Status Messages</h2></a>\n"; echo "<table id=\"messages\" class=\"translucent\"><tr><th>Time</th><th>Message</th></tr>\n"; foreach ($messages as $message) { $time = $message['time'] / 1000.0; if ($time > 0.0) { echo "<tr><td class=\"time\">{$time} sec.</td><td>{$message['message']}</td></tr>"; } } echo "</table>\n"; } $row = 0; $console_log = $testStepResult->getConsoleLog(); if (isset($console_log) && count($console_log)) { echo "\n<br><br><a name=\"console-log" . $linkSuffix . "\"><h2>Console Log</h2></a>\n"; echo "<table id=\"console-log\" class=\"translucent\"><tr><th>Source</th><th>Level</th><th>Message</th><th>URL</th><th>Line</th></tr>\n"; foreach ($console_log as &$log_entry) { $row++; $rowClass = ''; if ($row % 2 == 0) { $rowClass = ' class="even"'; } echo "<tr{$rowClass}><td class=\"source\">" . htmlspecialchars($log_entry['source']) . "</td><td class=\"level\">" . htmlspecialchars($log_entry['level']) . "</td><td class=\"message\"><div>" . htmlspecialchars($log_entry['text']) . "</div></td><td class=\"url\"><div><a href=\"" . htmlspecialchars($log_entry['url']) . "\">" . htmlspecialchars($log_entry['url']) . "</a></div></td><td class=\"line\">" . htmlspecialchars($log_entry['line']) . "</td></tr>\n"; } echo "</table>\n"; } }
private static function singlestepRunFromPageData($testInfo, $runNumber, $cached, &$runs) { $cacheIdx = $cached ? 1 : 0; if (empty($runs[$cacheIdx])) { return null; } $step = TestStepResult::fromPageData($testInfo, $runs[$cacheIdx], $runNumber, $cached, 1); return TestRunResults::fromStepResults($testInfo, $runNumber, $cached, array($step)); }
padding-bottom: 1em; } </style> </head> <body> <div class="page"> <?php $tab = 'Test Result'; $subtab = null; include 'header.inc'; ?> <div class="translucent"> <?php $stepsInRun = $testInfo->stepsInRun($run); if ($stepsInRun > 1) { $stepResult = TestStepResult::fromFiles($testInfo, $run, $cached, $step); echo "<h3>Step " . $stepResult->readableIdentifier($step) . "</h3>"; } ?> <p>Images are what are currently being served from the given url and may not necessarily match what was loaded at the time of the test.</p> <table class="images"> <?php foreach ($requests as &$request) { if (array_key_exists('contentType', $request) && !strncasecmp($request['contentType'], 'image/', 6)) { $index = $request['index'] + 1; echo "<tr id=\"image{$index}\"><td><b>{$index}:</b></td><td>"; $reqUrl = "http://"; if ($request['is_secure']) { $reqUrl = "https://"; } $reqUrl .= $request['host'];
private function getTestStepArray() { $step1 = array('result' => 0, 'TTFB' => 300, 'loadTime' => 6000, 'foo' => 'lorem'); $step2 = array('result' => 0, 'TTFB' => 100, 'loadTime' => 2000, 'foo' => 'ipsum', 'eventName' => "MyEvent"); $step3 = array('result' => 99999, 'TTFB' => 500, 'loadTime' => 1000, 'foo' => 'dolor'); $stepResults = array(1 => TestStepResult::fromPageData($this->testInfo, $step1, 2, true, 1), 2 => TestStepResult::fromPageData($this->testInfo, $step2, 2, true, 2), 3 => TestStepResult::fromPageData($this->testInfo, $step3, 2, true, 3)); return $stepResults; }
/** * @param TestStepResult $stepResult * @return string */ private function _labelColumnText($stepResult) { $runNumber = $stepResult->getRunNumber(); if (!$this->isMultistep) { return $this->_rvLabel($stepResult->isCachedRun(), $runNumber); } $label = FitText($stepResult->readableIdentifier(), 30); if ($this->enableLabelLinks) { $label = "<a href='#run" . $runNumber . "_step" . $stepResult->getStepNumber() . "'>" . $label . "</a>"; } return $label; }
} $testInfo = parse_ini_file("./{$test['path']}/testinfo.ini", true); if ($testInfo !== FALSE) { if (array_key_exists('test', $testInfo) && array_key_exists('location', $testInfo['test'])) { $test['location'] = $testInfo['test']['location']; } if (isset($testInfo['test']) && isset($testInfo['test']['completeTime'])) { $test['done'] = true; $testInfoObject = TestInfo::fromFiles("./" . $test['path']); if (!array_key_exists('run', $test) || !$test['run']) { $testResults = TestResults::fromFiles($testInfoObject); $test['run'] = $testResults->getMedianRunNumber($test_median_metric, $test['cached']); $runResults = $testResults->getRunResult($test['run'], $test['cached']); $stepResult = $runResults->getStepResult($test['step']); } else { $stepResult = TestStepResult::fromFiles($testInfoObject, $test['run'], $test['cached'], $test['step']); } $test['stepResult'] = $stepResult; $test['aft'] = (int) $stepResult->getMetric('aft'); $loadTime = $stepResult->getMetric('fullyLoaded'); if (isset($loadTime) && (!isset($fastest) || $loadTime < $fastest)) { $fastest = $loadTime; } // figure out the real end time (in ms) if (isset($test['end'])) { $visualComplete = $stepResult->getMetric("visualComplte"); if (!strcmp($test['end'], 'visual') && $visualComplete !== null) { $test['end'] = $visualComplete; } elseif (!strcmp($test['end'], 'load')) { $test['end'] = $stepResult->getMetric('loadTime'); } elseif (!strcmp($test['end'], 'doc')) {
public function testHasBreakdownTimeline() { $fileHandlerExists = $this->getMock("FileHandler"); $fileHandlerExists->method("gzFileExists")->willReturn(true); $fileHandlerDoesntExists = $this->getMock("FileHandler"); $fileHandlerDoesntExists->method("gzFileExists")->willReturn(false); $testInfoWithTimeline = TestInfo::fromValues("testId", "/root/path", array("testinfo" => array("timeline" => "1"))); $testInfoWithoutTimeline = TestInfo::fromValues("testId", "/root/path", array("testinfo" => array())); $step = TestStepResult::fromPageData($testInfoWithTimeline, array(), 1, 1, 1, $fileHandlerExists); $this->assertTrue($step->hasBreakdownTimeline()); $step = TestStepResult::fromPageData($testInfoWithTimeline, array(), 1, 1, 1, $fileHandlerDoesntExists); $this->assertFalse($step->hasBreakdownTimeline()); $step = TestStepResult::fromPageData($testInfoWithoutTimeline, array(), 1, 1, 1, $fileHandlerExists); $this->assertFalse($step->hasBreakdownTimeline()); $step = TestStepResult::fromPageData($testInfoWithoutTimeline, array(), 1, 1, 1, $fileHandlerDoesntExists); $this->assertFalse($step->hasBreakdownTimeline()); }
/** * Print the console log if requested * @param TestStepResult $testResult Result data of affected run */ private function printConsoleLog($testResult) { if (!$this->shouldPrintInfo(self::INFO_CONSOLE)) { return; } $consoleLog = $testResult->getConsoleLog(); if (isset($consoleLog) && is_array($consoleLog) && count($consoleLog)) { echo "<consoleLog>\n"; foreach ($consoleLog as &$entry) { echo "<entry>\n"; echo "<source>" . xml_entities($entry['source']) . "</source>\n"; echo "<level>" . xml_entities($entry['level']) . "</level>\n"; echo "<message>" . xml_entities($entry['text']) . "</message>\n"; echo "<url>" . xml_entities($entry['url']) . "</url>\n"; echo "<line>" . xml_entities($entry['line']) . "</line>\n"; echo "</entry>\n"; } echo "</consoleLog>\n"; } }