diff options
author | mattab <matthieu.aubry@gmail.com> | 2015-03-13 02:17:33 +0300 |
---|---|---|
committer | mattab <matthieu.aubry@gmail.com> | 2015-03-13 02:17:33 +0300 |
commit | 10dc7d3da50eb8c33a783ba0eacbd3039d8597af (patch) | |
tree | 555fc375926181d6f41fbdee316c41d83fa256bc /plugins | |
parent | f95d109fb120c97828a5a908a88075e97d3f8b2e (diff) |
Ability to sync UI screenshots for Plugins including premium plugins
fixes #7393
updated wiki at: https://github.com/PiwikPRO/support/wiki/How-to-develop-PRO-plugins%3F
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php | 196 |
1 files changed, 159 insertions, 37 deletions
diff --git a/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php b/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php index be1bedd05d..b8bb7d64d8 100644 --- a/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php +++ b/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php @@ -11,15 +11,21 @@ namespace Piwik\Plugins\CoreConsole\Commands; use Piwik\Development; use Piwik\Http; +use Piwik\Log; 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\OutputInterface; /** + * Tool for core developers to help making UI screenshot builds green. + * */ class DevelopmentSyncUITestScreenshots extends ConsoleCommand { + protected $urlBase; + public function isEnabled() { return Development::isEnabled(); @@ -29,40 +35,32 @@ 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.'); - } + $diffviewer = $this->getDiffviewerContent($input); - $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); + 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 +71,166 @@ 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($input, $output, $file); } } - $this->displayGitInstructions($output); + $this->displayGitInstructions($input, $output); } - /** - * @param OutputInterface $output - */ - protected function displayGitInstructions(OutputInterface $output) + protected function displayGitInstructions(InputInterface $input, OutputInterface $output) { $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($input); + $commands = " +cd $downloadToPath git pull git add . -git commit -m '' # WRITE A COMMIT MESSAGE -git push +git commit -m '' # Write a good commit message +git push"; + + $plugin = $input->getOption('plugin'); + 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(InputInterface $input) + { + $buildNumber = $input->getArgument('buildnumber'); + if (empty($buildNumber)) { + throw new \InvalidArgumentException('Missing build number.'); + } + + $plugin = $input->getOption('plugin'); + if ($plugin) { + $urlBase = sprintf('http://builds-artifacts.piwik.org/ui-tests.master.%s/%s', $plugin, $buildNumber); + } else { + $urlBase = sprintf('http://builds-artifacts.piwik.org/ui-tests.master/%s', $buildNumber); + } + return $urlBase; + } + + protected function getDownloadToPath(InputInterface $input) + { + $plugin = $input->getOption('plugin'); + + $downloadTo = PIWIK_DOCUMENT_ROOT . "/"; + if (empty($plugin)) { + $downloadTo .= "tests/UI/expected-ui-screenshots/"; + } else { + $downloadTo .= "plugins/$plugin/tests/UI/expected-ui-screenshots/"; + } + if(is_dir($downloadTo)) { + return $downloadTo; + } + $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(InputInterface $input) + { + $this->urlBase = $this->getUrlBase($input); + $diffviewerUrl = $this->getDiffviewerUrl($this->urlBase); + + $diffviewer = $this->downloadDiffviewer($diffviewerUrl); + if($diffviewer) { + return $diffviewer; + } + + // Maybe this is a Premium Piwik PRO plugin... + return $this->getDiffviewContentForPrivatePlugin($input); + } + + protected function getDiffviewContentForPrivatePlugin(InputInterface $input) + { + $httpUser = $input->getOption('http-user'); + $httpPassword = $input->getOption('http-password'); + if (empty($httpUser) || empty($httpPassword)) { + Log::info("--http-user and --http-password was not specified, skip download of private plugins screenshots."); + return; + } + + // Attempt to download from protected/ artifacts... + $this->urlBase = str_replace("builds-artifacts.piwik.org/", "builds-artifacts.piwik.org/protected/", $this->urlBase); + $diffviewerUrl = $this->getDiffviewerUrl($this->urlBase); + + return $this->downloadDiffviewer($diffviewerUrl, $httpUser, $httpPassword); + } + + /** + * @return string + */ + protected function getDiffviewerUrl($urlBase) + { + return $urlBase . "/screenshot-diffs/diffviewer.html"; + } + + protected function downloadDiffviewer($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') { + $diffviewer = str_replace('&', '&', $responseExtended['data']); + return $diffviewer; + } + + Log::info("Could not download the diffviewer from $urlDiffviewer - Got HTTP status " . $httpStatus); + if($httpStatus == '401') { + Log::warning("HTTP AUTH username and password are not valid."); + } + return false; + } + + + protected function downloadProcessedScreenshot(InputInterface $input, OutputInterface $output, $file) + { + $downloadTo = $this->getDownloadToPath($input) . $file; + + $output->write("<info>Downloading $file to $downloadTo...</info>\n"); + $urlProcessedScreenshot = $this->urlBase . "/processed-ui-screenshots/$file"; + + Http::sendHttpRequest($urlProcessedScreenshot, + $timeout = 60, + $userAgent = null, + $downloadTo, + $followDepth = 0, + $acceptLanguage = false, + $byteRange = false, + $getExtendedInfo = true, + $httpMethod = 'GET', + $input->getOption('http-user'), + $input->getOption('http-password')); + } + } |