diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist index 7ba22e820e..66bbbf0c78 100644 --- a/core/phpunit.xml.dist +++ b/core/phpunit.xml.dist @@ -57,6 +57,10 @@ ./tests/TestSuites/BuildTestSuite.php + + + + diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/HtmlOutputLogger.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/HtmlOutputLogger.php index d67ff14140..9bc1a117b2 100644 --- a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/HtmlOutputLogger.php +++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/HtmlOutputLogger.php @@ -15,6 +15,13 @@ */ final class HtmlOutputLogger extends DefaultResultPrinter { + /** + * The singleton instance. + * + * @var self + */ + private static ?self $instance = NULL; + /** * File to write html links to. * @@ -27,79 +34,75 @@ * @throws \PHPUnit\Util\Exception * @throws \PHPUnit\Event\UnknownSubscriberTypeException */ - public function __construct(string $out, bool $verbose = false, bool $colors = false, int|string $numberOfColumns = 80, bool $reverse = false) { - parent::__construct($out, $verbose, $colors, $numberOfColumns, $reverse); + private function __construct(string $browserTestOutputDirectory) { + $this->browserOutputFile = $this->determineBrowserOutputFile($browserTestOutputDirectory); + parent::__construct($this->browserOutputFile); Facade::registerSubscriber(new TestRunnerFinishedSubscriber($this)); Facade::registerSubscriber(new TestRunnerStartedSubscriber($this)); } /** - * Creates the file to list the HTML output created during the test run. + * @todo * - * @see \Drupal\Tests\BrowserTestBase::initBrowserOutputFile() + * @throws \PHPUnit\Event\EventFacadeIsSealedException + * @throws \PHPUnit\Util\Exception + * @throws \PHPUnit\Event\UnknownSubscriberTypeException */ - public function testRunnerStarted(TestRunnerStarted $event): void { - $this->browserOutputFile = ''; - - if ($html_output_directory = getenv('BROWSERTEST_OUTPUT_DIRECTORY')) { - // Initialize html output debugging. - $html_output_directory = rtrim($html_output_directory, '/'); - - // Check if directory exists. - if (!is_dir($html_output_directory) || !is_writable($html_output_directory)) { - $this->writeWithColor('bg-red, fg-black', "HTML output directory $html_output_directory is not a writable directory."); - } - else { - // Convert to a canonicalized absolute pathname just in case the current - // working directory is changed. - $html_output_directory = realpath($html_output_directory); - $this->browserOutputFile = tempnam($html_output_directory, 'browser_output_'); - if ($this->browserOutputFile) { - touch($this->browserOutputFile); - } - else { - $this->writeWithColor('bg-red, fg-black', "Unable to create a temporary file in $html_output_directory."); - } - } + public static function init(string $browserTestOutputDirectory): void { + if (self::$instance === NULL) { + self::$instance = new self($browserTestOutputDirectory); } + } - if ($this->browserOutputFile !== '') { - putenv('BROWSERTEST_OUTPUT_FILE=' . $this->browserOutputFile); - } - else { - // Remove any environment variable. - putenv('BROWSERTEST_OUTPUT_FILE'); + /** + * @todo + */ + public static function log(string $logEntry): void { + if (self::$instance === NULL) { + return; } + self::$instance->write($logEntry); } /** - * Prints the list of HTML output generated during the test. + * @todo */ - public function testRunnerFinished(TestRunnerFinished $event): void { - if ($this->browserOutputFile !== '') { - $contents = file_get_contents($this->browserOutputFile); - if ($contents) { - $this->writeNewLine(); - $this->writeWithColor('bg-yellow, fg-black', 'HTML output was generated'); - $this->write($contents); - } - // No need to keep the file around any more. - unlink($this->browserOutputFile); + private function determineBrowserOutputFile(string $browserTestOutputDirectory): string { + // Convert to a canonicalized absolute pathname just in case the current + // working directory is changed. + if (($html_output_directory = realpath(rtrim($browserTestOutputDirectory, '/'))) === FALSE) { + throw new \RuntimeException("HTML output directory $browserTestOutputDirectory is not a writable directory"); + } + + if (($browserOutputFile = tempnam($browserTestOutputDirectory, 'browser_output_')) === FALSE) { + throw new \RuntimeException("Unable to create a temporary file in $browserTestOutputDirectory"); } + + return $browserOutputFile; } /** - * {@inheritdoc} + * Creates the file to list the HTML output created during the test run. + * + * @see \Drupal\Tests\BrowserTestBase::initBrowserOutputFile() */ - public function write(string $buffer): void { - $buffer = Html::escape($buffer); - // Turn HTML output URLs into clickable link tags. - $url_pattern = '@https?://[^\s]+@'; - $buffer = preg_replace($url_pattern, '$0', $buffer); - // Make the output readable in HTML by breaking up lines properly. - $buffer = nl2br($buffer); + public function testRunnerStarted(TestRunnerStarted $event): void { + putenv('BROWSERTEST_OUTPUT_FILE=' . $this->browserOutputFile); + } - print $buffer; + /** + * Prints the list of HTML output generated during the test. + */ + public function testRunnerFinished(TestRunnerFinished $event): void { + $this->flush(); + $contents = file_get_contents($this->browserOutputFile); + if ($contents) { + print "\n"; + print "HTML output was generated\n"; + print $contents; + } + // No need to keep the file around any more. + unlink($this->browserOutputFile); } } diff --git a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php index e0b85ef546..c2d51fb797 100644 --- a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php +++ b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php @@ -4,6 +4,8 @@ use Drupal\Component\Utility\Html; use Drupal\Core\Utility\Error; +use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\HtmlOutputLogger; +use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -126,7 +128,12 @@ protected function htmlOutput($message = NULL) { // Do not use the file_url_generator service as the module_handler service // might not be available. $uri = $this->htmlOutputBaseUrl . '/sites/simpletest/browser_output/' . $html_output_filename; - file_put_contents($this->htmlOutputFile, $uri . "\n", FILE_APPEND); + if (RunnerVersion::getMajor() > 9) { + HtmlOutputLogger::log($uri . "\n"); + } + else { + file_put_contents($this->htmlOutputFile, $uri . "\n", FILE_APPEND); + } } /** diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php index 0853496faa..7266aabdb1 100644 --- a/core/tests/bootstrap.php +++ b/core/tests/bootstrap.php @@ -11,6 +11,7 @@ use Drupal\TestTools\PhpUnitCompatibility\PhpUnit8\ClassWriter; use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\HtmlOutputLogger; use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion; +use PHPUnit\Util\Filesystem; /** * Finds all valid extension directories recursively within a given directory. @@ -182,6 +183,12 @@ class_alias('\Drupal\Tests\DocumentElement', '\Behat\Mink\Element\DocumentElemen // if they weren't on already. Handle::register(); +// Functional tests HTML output logging. if (RunnerVersion::getMajor() > 9) { - new HtmlOutputLogger('php://memory'); + $browserTestOutputDirectory = getenv('BROWSERTEST_OUTPUT_DIRECTORY'); + if ($browserTestOutputDirectory !== FALSE) { + if (Filesystem::createDirectory($browserTestOutputDirectory)) { + HtmlOutputLogger::init($browserTestOutputDirectory); + } + } }