diff options
author | Matthieu Aubry <matt@piwik.org> | 2015-03-16 06:04:47 +0300 |
---|---|---|
committer | Matthieu Aubry <matt@piwik.org> | 2015-03-16 06:04:47 +0300 |
commit | bc961a9cd0cf44528a0205c56a97043271d35840 (patch) | |
tree | 43bc747a41c099f7e87de130dd07955eeac9183a /plugins | |
parent | ca2f0d3047cee0e084bf02d1e6bae4761eb7c3c0 (diff) | |
parent | 2138eacaa6090b01e63baae996fbeb6caaba4060 (diff) |
Merge pull request #7419 from piwik/7393_sync_ui_screenshots_plugins
Ability to sync UI screenshots for Plugins including premium plugins
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php | 188 |
1 files changed, 153 insertions, 35 deletions
diff --git a/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php b/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php index be1bedd05d..a8fa9a7a6c 100644 --- a/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php +++ b/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php @@ -14,9 +14,13 @@ use Piwik\Http; use Piwik\Plugin\ConsoleCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\Output; use Symfony\Component\Console\Output\OutputInterface; /** + * Tool for core developers to help making UI screenshot builds green. + * */ class DevelopmentSyncUITestScreenshots extends ConsoleCommand { @@ -29,40 +33,44 @@ class DevelopmentSyncUITestScreenshots extends ConsoleCommand { $this->setName('development:sync-ui-test-screenshots'); $this->setDescription('For Piwik core devs. Copies screenshots ' - . 'from travis artifacts to tests/UI/expected-ui-screenshots/'); + . 'from travis artifacts to the tests/UI/expected-ui-screenshots/ folder'); $this->addArgument('buildnumber', InputArgument::REQUIRED, 'Travis build number you want to sync.'); $this->addArgument('screenshotsRegex', InputArgument::OPTIONAL, 'A regex to use when selecting screenshots to copy. If not supplied all screenshots are copied.', '.*'); + $this->addOption('plugin', 'p', InputOption::VALUE_OPTIONAL, 'Plugin name you want to sync screenshots for.'); + $this->addOption('http-user', '', InputOption::VALUE_OPTIONAL, 'the HTTP AUTH username (for premium plugins where artifacts are protected)'); + $this->addOption('http-password', '', InputOption::VALUE_OPTIONAL, 'the HTTP AUTH password (for premium plugins where artifacts are protected)'); } protected function execute(InputInterface $input, OutputInterface $output) { $buildNumber = $input->getArgument('buildnumber'); - $screenshotsRegex = $input->getArgument('screenshotsRegex'); - if (empty($buildNumber)) { throw new \InvalidArgumentException('Missing build number.'); } - $urlBase = sprintf('http://builds-artifacts.piwik.org/ui-tests.master/%s', $buildNumber); - $diffviewer = Http::sendHttpRequest($urlBase . "/screenshot-diffs/diffviewer.html", $timeout = 60); - $diffviewer = str_replace('&', '&', $diffviewer); + $screenshotsRegex = $input->getArgument('screenshotsRegex'); + + $plugin = $input->getOption('plugin'); + + $httpUser = $input->getOption('http-user'); + $httpPassword = $input->getOption('http-password'); + + $urlBase = $this->getUrlBase($plugin, $buildNumber); + $diffviewer = $this->getDiffviewerContent($output, $urlBase, $httpUser, $httpPassword); + + if(empty($diffviewer)) { + throw new \Exception("Screenshot tests artifacts were not found for this build."); + } + $dom = new \DOMDocument(); $dom->loadHTML($diffviewer); foreach ($dom->getElementsByTagName("tr") as $row) { $columns = $row->getElementsByTagName("td"); - $nameColumn = $columns->item(0); $processedColumn = $columns->item(3); - $testPlugin = null; - if ($nameColumn - && preg_match("/\(for ([a-zA-Z_]+) plugin\)/", $dom->saveXml($nameColumn), $matches) - ) { - $testPlugin = $matches[1]; - } - $file = null; if ($processedColumn && preg_match("/href=\".*\/(.*)\"/", $dom->saveXml($processedColumn), $matches) @@ -73,42 +81,152 @@ class DevelopmentSyncUITestScreenshots extends ConsoleCommand if ($file !== null && preg_match("/" . $screenshotsRegex . "/", $file) ) { - if ($testPlugin == null) { - $downloadTo = "tests/UI/expected-ui-screenshots/$file"; - } else { - $downloadTo = "plugins/$testPlugin/tests/UI/expected-ui-screenshots/$file"; - } - - $output->write("<info>Downloading $file to $downloadTo...</info>\n"); - Http::sendHttpRequest("$urlBase/processed-ui-screenshots/$file", $timeout = 60, $userAgent = null, - PIWIK_DOCUMENT_ROOT . "/" . $downloadTo); + $this->downloadProcessedScreenshot($output, $urlBase, $file, $plugin, $httpUser, $httpPassword); } } - $this->displayGitInstructions($output); + $this->displayGitInstructions($output, $plugin); } - /** - * @param OutputInterface $output - */ - protected function displayGitInstructions(OutputInterface $output) + protected function displayGitInstructions(OutputInterface $output, $plugin) { $output->writeln(''); $output->writeln('--------------'); $output->writeln(''); $output->writeln("If all downloaded screenshots are valid you may push them with these commands:"); - $output->writeln(''); - $commands = "cd tests/UI/expected-ui-screenshots + $downloadToPath = $this->getDownloadToPath($plugin); + $commands = " +cd $downloadToPath git pull git add . -git commit -m '' # WRITE A COMMIT MESSAGE -git push +git commit -m '' # Write a good commit message, eg. 'Fixed UI test failure caused by change introduced in <core or plugin commit> which caused failure by <explanation of failure>' +git push"; + + if(empty($plugin)) { + $commands .= " cd .. git pull -git add expected-ui-screenshots -git commit -m '' #WRITE A COMMIT MESSAGE -git push"; +git add expected-ui-screenshots/ +git commit -m '' # Copy paste the good commit message +git push +cd ../../\n\n"; + } else { + $commands .= " +cd ../../../../../\n\n"; + } $output->writeln($commands); } + + protected function getUrlBase($plugin, $buildNumber) + { + if ($plugin) { + return sprintf('http://builds-artifacts.piwik.org/ui-tests.master.%s/%s', $plugin, $buildNumber); + } + return sprintf('http://builds-artifacts.piwik.org/ui-tests.master/%s', $buildNumber); + } + + protected function getDownloadToPath($plugin) + { + if (empty($plugin)) { + return PIWIK_DOCUMENT_ROOT . "/tests/UI/expected-ui-screenshots/"; + } + + $downloadTo = PIWIK_DOCUMENT_ROOT . "/plugins/$plugin/tests/UI/expected-ui-screenshots/"; + if(is_dir($downloadTo)) { + return $downloadTo; + } + + // Maybe the plugin is using folder "Test/" instead of "tests/" + $downloadTo = str_replace("tests/", "Test/", $downloadTo); + if(is_dir($downloadTo)) { + return $downloadTo; + } + throw new \Exception("Download to path could not be found: $downloadTo"); + } + + protected function getDiffviewerContent(OutputInterface $output, $urlBase, $httpUser = false, $httpPassword = false) + { + $diffviewerUrl = $this->getDiffviewerUrl($urlBase); + + try { + return $this->downloadDiffviewer($output, $diffviewerUrl); + } catch(\Exception $e) { + + // Maybe this is a Premium Piwik PRO plugin... + return $this->getDiffviewContentForPrivatePlugin($output, $urlBase, $httpUser, $httpPassword); + } + } + + protected function getDiffviewContentForPrivatePlugin(OutputInterface $output, $urlBase, $httpUser, $httpPassword) + { + if (empty($httpUser) || empty($httpPassword)) { + $output->writeln("<info>--http-user and --http-password was not specified, skip download of private plugins screenshots.</info>"); + return; + } + + // Attempt to download from protected/ artifacts... + $urlBase = str_replace("builds-artifacts.piwik.org/", "builds-artifacts.piwik.org/protected/", $urlBase); + $diffviewerUrl = $this->getDiffviewerUrl($urlBase); + + return $this->downloadDiffviewer($output, $diffviewerUrl, $httpUser, $httpPassword); + } + + /** + * @return string + */ + protected function getDiffviewerUrl($urlBase) + { + return $urlBase . "/screenshot-diffs/diffviewer.html"; + } + + protected function downloadDiffviewer(OutputInterface $output, $urlDiffviewer, $httpUsername = false, $httpPassword = false) + { + $responseExtended = Http::sendHttpRequest( + $urlDiffviewer, + $timeout = 60, + $userAgent = null, + $destinationPath = null, + $followDepth = 0, + $acceptLanguage = false, + $byteRange = false, + $getExtendedInfo = true, + $httpMethod = 'GET', + $httpUsername, + $httpPassword + ); + $httpStatus = $responseExtended['status']; + if ($httpStatus == '200') { + $output->writeln("Found diffviewer at: " . $urlDiffviewer); + $diffviewer = str_replace('&', '&', $responseExtended['data']); + return $diffviewer; + } + + if($httpStatus == '401') { + $output->writeln("<error>HTTP AUTH username and password are not valid.</error>"); + } + throw new \Exception ("Failed downloading diffviewer from $urlDiffviewer - Got HTTP status " . $httpStatus); + } + + + protected function downloadProcessedScreenshot(OutputInterface $output, $urlBase, $file, $plugin, $httpUser, $httpPassword) + { + $downloadTo = $this->getDownloadToPath($plugin) . $file; + + $output->write("<info>Downloading $file to $downloadTo...</info>\n"); + $urlProcessedScreenshot = $urlBase . "/processed-ui-screenshots/$file"; + + Http::sendHttpRequest($urlProcessedScreenshot, + $timeout = 60, + $userAgent = null, + $downloadTo, + $followDepth = 0, + $acceptLanguage = false, + $byteRange = false, + $getExtendedInfo = true, + $httpMethod = 'GET', + $httpUser, + $httpPassword); + } + } |