diff --git a/admin/tool/behat/cli/util_single_run.php b/admin/tool/behat/cli/util_single_run.php index 967fde33358..f0a3650f540 100644 --- a/admin/tool/behat/cli/util_single_run.php +++ b/admin/tool/behat/cli/util_single_run.php @@ -164,6 +164,8 @@ if ($options['install']) { mtrace("Acceptance tests site installed"); } + // Note: Do not build the themes here. This is done during the 'enable' stage. + } else if ($options['drop']) { // Ensure no tests are running. test_lock::acquire('behat'); @@ -182,6 +184,10 @@ if ($options['install']) { // Enable test mode. behat_util::start_test_mode($options['add-core-features-to-theme'], $options['optimize-runs'], $parallel, $run); + // Themes are only built in the 'enable' command. + behat_util::build_themes(); + mtrace("Testing environment themes built"); + // This is only displayed once for parallel install. if (empty($run)) { // Notify user that 2.5 profile has been converted to 3.5. diff --git a/lib/behat/classes/util.php b/lib/behat/classes/util.php index 267406bb5bf..b24ea485065 100644 --- a/lib/behat/classes/util.php +++ b/lib/behat/classes/util.php @@ -32,6 +32,7 @@ require_once(__DIR__ . '/behat_config_manager.php'); require_once(__DIR__ . '/../../filelib.php'); require_once(__DIR__ . '/../../clilib.php'); +require_once(__DIR__ . '/../../csslib.php'); use Behat\Mink\Session; use Behat\Mink\Exception\ExpectationException; @@ -131,6 +132,35 @@ class behat_util extends testing_util { self::store_database_state(); } + /** + * Build theme CSS. + */ + public static function build_themes() { + global $CFG; + require_once("{$CFG->libdir}/outputlib.php"); + + $themenames = array_keys(\core_component::get_plugin_list('theme')); + + // Load the theme configs. + $themeconfigs = array_map(function($themename) { + return \theme_config::load($themename); + }, $themenames); + + // Build the list of themes and cache them in local cache. + $themes = theme_build_css_for_themes($themeconfigs, ['ltr'], true); + + $framework = self::get_framework(); + $storageroot = self::get_dataroot() . "/{$framework}/themedata"; + + foreach ($themes as $themename => $themedata) { + $dirname = "{$storageroot}/{$themename}"; + check_dir_exists($dirname); + foreach ($themedata as $direction => $css) { + file_put_contents("{$dirname}/{$direction}.css", $css); + } + } + } + /** * Drops dataroot and remove test database tables * @throws coding_exception @@ -397,6 +427,37 @@ class behat_util extends testing_util { initialise_cfg(); } + /** + * Restore theme CSS stored during behat setup. + */ + public static function restore_saved_themes(): void { + global $CFG; + + $themerev = theme_get_revision(); + + $framework = self::get_framework(); + $storageroot = self::get_dataroot() . "/{$framework}/themedata"; + $themenames = array_keys(\core_component::get_plugin_list('theme')); + $directions = ['ltr', 'rtl']; + + $themeconfigs = array_map(function($themename) { + return \theme_config::load($themename); + }, $themenames); + + foreach ($themeconfigs as $themeconfig) { + $themename = $themeconfig->name; + $themesubrev = theme_get_sub_revision_for_theme($themename); + + $dirname = "{$storageroot}/{$themename}"; + foreach ($directions as $direction) { + $cssfile = "{$dirname}/{$direction}.css"; + if (file_exists($cssfile)) { + $themeconfig->set_css_content_cache(file_get_contents($cssfile)); + } + } + } + } + /** * Pause execution immediately. * diff --git a/lib/outputlib.php b/lib/outputlib.php index e7cb41e7c39..fb4a29c98f9 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -179,12 +179,13 @@ function theme_get_css_filename($themename, $globalrevision, $themerevision, $di * @param theme_config[] $themeconfigs An array of theme_config instances. * @param array $directions Must be a subset of ['rtl', 'ltr']. * @param bool $cache Should the generated files be stored in local cache. + * @return array The built theme content in a multi-dimensional array of name => direction => content */ -function theme_build_css_for_themes($themeconfigs = [], $directions = ['rtl', 'ltr'], $cache = true) { +function theme_build_css_for_themes($themeconfigs = [], $directions = ['rtl', 'ltr'], $cache = true): array { global $CFG; if (empty($themeconfigs)) { - return; + return []; } require_once("{$CFG->libdir}/csslib.php"); @@ -212,7 +213,7 @@ function theme_build_css_for_themes($themeconfigs = [], $directions = ['rtl', 'l css_store_css($themeconfig, $filename, $themecss[$direction]); } } - $themescss[] = $themecss; + $themescss[$themeconfig->name] = $themecss; if ($cache) { // Only update the theme revision after we've successfully created the diff --git a/lib/tests/behat/behat_hooks.php b/lib/tests/behat/behat_hooks.php index c7b53df6b46..115765a97f0 100644 --- a/lib/tests/behat/behat_hooks.php +++ b/lib/tests/behat/behat_hooks.php @@ -367,6 +367,16 @@ class behat_hooks extends behat_base { behat_util::reset_all_data(); error_reporting($errorlevel); + if ($this->running_javascript()) { + // Fetch the user agent. + // This isused to choose between the SVG/Non-SVG versions of themes. + $useragent = $this->getSession()->evaluateScript('return navigator.userAgent;'); + \core_useragent::instance(true, $useragent); + + // Restore the saved themes. + behat_util::restore_saved_themes(); + } + // Assign valid data to admin user (some generator-related code needs a valid user). $user = $DB->get_record('user', array('username' => 'admin')); \core\session\manager::set_user($user);