diff --git a/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php b/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php index ca45baefe7..1cf2688a80 100644 --- a/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php +++ b/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php @@ -159,6 +159,9 @@ protected function setUp() { // Select profile. $this->setUpProfile(); + // Address the requirements problem screen, if any. + $this->setUpRequirementsProblem(); + // Configure settings. $this->setUpSettings(); @@ -198,7 +201,7 @@ protected function setUp() { } /** - *{@inheritdoc} + * {@inheritdoc} */ protected function initFrontPage() { // We don't want to visit the front page with the installer when @@ -240,6 +243,23 @@ protected function setUpSettings() { $this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']); } + /** + * Installer step: Requirements problem. + * + * Override this method to test specific requirements warnings or errors + * during the installer. + * + * @see system_requirements() + */ + protected function setUpRequirementsProblem() { + // By default, skip the "recommended PHP version" warning on older test + // environments. This allows the installer to be tested consistently on + // both recommended PHP versions and older (but still supported) versions. + if (version_compare(phpversion(), DRUPAL_RECOMMENDED_PHP) < 0) { + $this->continueOnExpectedWarnings(['PHP']); + } + } + /** * Final installer step: Configure site. */ @@ -285,4 +305,45 @@ protected function refreshVariables() { } } + /** + * Continues installation when an expected warning is found. + * + * @param string[] $expected_warnings + * A list of warning summaries to expect on the requirements screen (e.g. + * 'PHP', 'PHP OPcode caching', etc.). If only the expected warnings + * are found, the test will click the "continue anyway" link to go to the + * next screen of the installer. If an expected warning is not found, or if + * a warning not in the list is present, a fail is raised. + */ + protected function continueOnExpectedWarnings($expected_warnings = []) { + // Don't try to continue if there are errors. + if (strpos($this->getTextContent(), 'Errors found') !== FALSE) { + return; + } + // Allow only details elements that are directly after the warning header + // or each other. There is no guaranteed wrapper we can rely on across + // distributions. When there are multiple warnings, the selectors will be: + // - h3#warning+details summary + // - h3#warning+details+details summary + // - etc. + // We add one more selector than expected warnings to confirm that there + // isn't any other warning before clicking the link. + // @todo Make this more reliable in + // https://www.drupal.org/project/drupal/issues/2927345. + $selectors = []; + for ($i = 0; $i <= count($expected_warnings); $i++) { + $selectors[] = 'h3#warning' . implode('', array_fill(0, $i + 1, '+details')) . ' summary'; + } + $warning_elements = $this->cssSelect(implode(', ', $selectors)); + + // Confirm that there are only the expected warnings. + $warnings = []; + foreach ($warning_elements as $warning) { + $warnings[] = trim($warning->getText()); + } + $this->assertEquals($expected_warnings, $warnings); + $this->clickLink('continue anyway'); + $this->checkForMetaRefresh(); + } + }