diff --git a/lib/behat/behat_field_manager.php b/lib/behat/behat_field_manager.php index 31701e92d82..27fbafab4ae 100644 --- a/lib/behat/behat_field_manager.php +++ b/lib/behat/behat_field_manager.php @@ -51,19 +51,8 @@ class behat_field_manager { // There are moodle form elements that are not directly related with // a basic HTML form field, we should also take care of them. - try { - // The DOM node. - $fieldnode = $context->find_field($label); - } catch (ElementNotFoundException $fieldexception) { - - // Looking for labels that points to filemanagers. - try { - $fieldnode = $context->find_filemanager($label); - } catch (ElementNotFoundException $filemanagerexception) { - // We want the generic 'field' exception. - throw $fieldexception; - } - } + // The DOM node. + $fieldnode = $context->find_field($label); // The behat field manager. return self::get_form_field($fieldnode, $context->getSession()); diff --git a/lib/behat/classes/behat_config_util.php b/lib/behat/classes/behat_config_util.php index ba3bced7493..a37e62d617d 100644 --- a/lib/behat/classes/behat_config_util.php +++ b/lib/behat/classes/behat_config_util.php @@ -466,10 +466,14 @@ class behat_config_util { // Remove selectors from step definitions. $themes = $this->get_list_of_themes(); + $selectortypes = ['partial', 'exact']; foreach ($themes as $theme) { - $selectorclass = self::get_behat_theme_selector_override_classname($theme); - if (isset($allcontexts[$selectorclass])) { - unset($allcontexts[$selectorclass]); + foreach ($selectortypes as $selectortype) { + // Don't include selector classes. + $selectorclass = self::get_behat_theme_selector_override_classname($theme, $selectortype); + if (isset($allcontexts[$selectorclass])) { + unset($allcontexts[$selectorclass]); + } } } @@ -838,13 +842,18 @@ class behat_config_util { * Return context name of behat_theme selector to use. * * @param string $themename name of the theme. + * @param string $selectortype The type of selector (partial or exact at this stage) * @param bool $includeclass if class should be included. * @return string */ - public static final function get_behat_theme_selector_override_classname($themename, $includeclass = false) { + public static final function get_behat_theme_selector_override_classname($themename, $selectortype, $includeclass = false) { global $CFG; - $overridebehatclassname = 'behat_theme_'.$themename.'_behat_selectors'; + if ($selectortype !== 'partial' && $selectortype !== 'exact') { + throw new coding_exception("Unknown selector override type '{$selectortype}'"); + } + + $overridebehatclassname = "behat_theme_{$themename}_behat_{$selectortype}_selectors"; if ($includeclass) { $themeoverrideselector = $CFG->dirroot . DIRECTORY_SEPARATOR . 'theme' . DIRECTORY_SEPARATOR . $themename . @@ -1238,11 +1247,14 @@ class behat_config_util { $this->overriddenthemescontexts[$context] = $path; } - // Don't include behat_selectors. - if ($context === self::get_behat_theme_selector_override_classname($theme)) { - unset($this->contexts[$context]); - unset($themesuitecontexts[$context]); - continue; + $selectortypes = ['partial', 'exact']; + foreach ($selectortypes as $selectortype) { + // Don't include selector classes. + if ($context === self::get_behat_theme_selector_override_classname($theme, $selectortype)) { + unset($this->contexts[$context]); + unset($themesuitecontexts[$context]); + continue; + } } // Add theme specific contexts with suffix to steps definitions. @@ -1262,4 +1274,4 @@ class behat_config_util { return array(array_keys($themecontexts), $themesuitecontexts); } -} \ No newline at end of file +} diff --git a/lib/behat/classes/behat_selectors.php b/lib/behat/classes/behat_selectors.php index 65b41d61f98..0074cbf20a4 100644 --- a/lib/behat/classes/behat_selectors.php +++ b/lib/behat/classes/behat_selectors.php @@ -34,116 +34,6 @@ */ class behat_selectors { - /** - * @var Allowed types when using text selectors arguments. - */ - protected static $allowedtextselectors = array( - 'activity' => 'activity', - 'block' => 'block', - 'css_element' => 'css_element', - 'dialogue' => 'dialogue', - 'fieldset' => 'fieldset', - 'list_item' => 'list_item', - 'question' => 'question', - 'region' => 'region', - 'section' => 'section', - 'table' => 'table', - 'table_row' => 'table_row', - 'xpath_element' => 'xpath_element', - 'form_row' => 'form_row' - ); - - /** - * @var Allowed types when using selector arguments. - */ - protected static $allowedselectors = array( - 'activity' => 'activity', - 'block' => 'block', - 'button' => 'button', - 'checkbox' => 'checkbox', - 'css_element' => 'css_element', - 'dialogue' => 'dialogue', - 'field' => 'field', - 'fieldset' => 'fieldset', - 'file' => 'file', - 'filemanager' => 'filemanager', - 'link' => 'link', - 'link_or_button' => 'link_or_button', - 'list_item' => 'list_item', - 'optgroup' => 'optgroup', - 'option' => 'option', - 'question' => 'question', - 'radio' => 'radio', - 'region' => 'region', - 'section' => 'section', - 'select' => 'select', - 'table' => 'table', - 'table_row' => 'table_row', - 'text' => 'text', - 'xpath_element' => 'xpath_element', - 'form_row' => 'form_row' - ); - - /** - * Behat by default comes with XPath, CSS and named selectors, - * named selectors are a mapping between names (like button) and - * xpaths that represents that names and includes a placeholder that - * will be replaced by the locator. These are Moodle's own xpaths. - * - * @var XPaths for moodle elements. - */ - protected static $moodleselectors = array( - 'activity' => << << << << << << << << << << << << $xpath) { - $session->getSelectorsHandler()->getSelector('named_partial')->registerNamedXpath($name, $xpath); - } - } - /** * Allowed selectors getter. * * @return array */ public static function get_allowed_selectors() { - return self::$allowedselectors; + return array_merge( + behat_partial_named_selector::get_allowed_selectors(), + behat_exact_named_selector::get_allowed_selectors() + ); } /** @@ -195,15 +75,9 @@ XPATH * @return array */ public static function get_allowed_text_selectors() { - return self::$allowedtextselectors; - } - - /** - * Moodle selectors attribute accessor. - * - * @return array - */ - protected static function get_moodle_selectors() { - return self::$moodleselectors; + return array_merge( + behat_partial_named_selector::get_allowed_text_selectors(), + behat_exact_named_selector::get_allowed_text_selectors() + ); } } diff --git a/lib/behat/classes/exact_named_selector.php b/lib/behat/classes/exact_named_selector.php new file mode 100644 index 00000000000..61f3b5b739b --- /dev/null +++ b/lib/behat/classes/exact_named_selector.php @@ -0,0 +1,61 @@ +. + +/** + * Moodle-specific named exact selectors. + * + * @package core + * @category test + * @copyright 2016 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Moodle selectors manager. + * + * @package core + * @copyright 2016 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_exact_named_selector extends \Behat\Mink\Selector\ExactNamedSelector { + /** + * @var Allowed types when using text selectors arguments. + */ + protected static $allowedtextselectors = []; + + /** + * @var Allowed types when using selector arguments. + */ + protected static $allowedselectors = []; + + /** + * Allowed selectors getter. + * + * @return array + */ + public static function get_allowed_selectors() { + return static::$allowedselectors; + } + + /** + * Allowed text selectors getter. + * + * @return array + */ + public static function get_allowed_text_selectors() { + return static::$allowedtextselectors; + } +} diff --git a/lib/behat/classes/partial_named_selector.php b/lib/behat/classes/partial_named_selector.php new file mode 100644 index 00000000000..9123e176ee4 --- /dev/null +++ b/lib/behat/classes/partial_named_selector.php @@ -0,0 +1,195 @@ +. + +/** + * Moodle-specific selectors. + * + * @package core + * @category test + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Moodle selectors manager. + * + * @package core + * @category test + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_partial_named_selector extends \Behat\Mink\Selector\PartialNamedSelector { + + /** + * Creates selector instance. + */ + public function __construct() { + foreach (self::$customselectors as $alias => $selectors) { + $this->registerNamedXpath($alias, implode(' | ', $selectors)); + } + + foreach (static::$moodleselectors as $name => $xpath) { + $this->registerNamedXpath($name, $xpath); + } + + // Call the constructor after adding any new selector or replacement values. + parent::__construct(); + } + + /** + * @var Allowed types when using text selectors arguments. + */ + protected static $allowedtextselectors = array( + 'activity' => 'activity', + 'block' => 'block', + 'css_element' => 'css_element', + 'dialogue' => 'dialogue', + 'fieldset' => 'fieldset', + 'list_item' => 'list_item', + 'question' => 'question', + 'region' => 'region', + 'section' => 'section', + 'table' => 'table', + 'table_row' => 'table_row', + 'xpath_element' => 'xpath_element', + 'form_row' => 'form_row', + ); + + /** + * @var Allowed types when using selector arguments. + */ + protected static $allowedselectors = array( + 'activity' => 'activity', + 'block' => 'block', + 'button' => 'button', + 'checkbox' => 'checkbox', + 'css_element' => 'css_element', + 'dialogue' => 'dialogue', + 'field' => 'field', + 'fieldset' => 'fieldset', + 'file' => 'file', + 'filemanager' => 'filemanager', + 'link' => 'link', + 'link_or_button' => 'link_or_button', + 'list_item' => 'list_item', + 'optgroup' => 'optgroup', + 'option' => 'option', + 'question' => 'question', + 'radio' => 'radio', + 'region' => 'region', + 'section' => 'section', + 'select' => 'select', + 'table' => 'table', + 'table_row' => 'table_row', + 'text' => 'text', + 'xpath_element' => 'xpath_element', + 'form_row' => 'form_row', + ); + + /** + * Behat by default comes with XPath, CSS and named selectors, + * named selectors are a mapping between names (like button) and + * xpaths that represents that names and includes a placeholder that + * will be replaced by the locator. These are Moodle's own xpaths. + * + * @var XPaths for moodle elements. + */ + protected static $moodleselectors = array( + 'activity' => << << << << << << << << << << << [ + 'upstream' => << <<getEnvironment()); // We need the Mink session to do it and we do it only before the first scenario. - $behatselectorclass = 'behat_selectors'; - if ($suitename !== 'default') { - $overriddenselectorclass = behat_config_util::get_behat_theme_selector_override_classname($suitename, true); + $namedpartialclass = 'behat_partial_named_selector'; + $namedexactclass = 'behat_exact_named_selector'; - // If override slector exist, then set it as default behat selectors class. - if (class_exists($overriddenselectorclass)) { - $behatselectorclass = $overriddenselectorclass; + if ($suitename !== 'default') { + // If override selector exist, then set it as default behat selectors class. + $overrideclass = behat_config_util::get_behat_theme_selector_override_classname($suitename, 'named_partial', true); + if (class_exists($overrideclass)) { + $namedpartialclass = $overrideclass; + } + + // If override selector exist, then set it as default behat selectors class. + $overrideclass = behat_config_util::get_behat_theme_selector_override_classname($suitename, 'named_exact', true); + if (class_exists($overrideclass)) { + $namedexactclass = $overrideclass; } } - - $behatselectorclass = new $behatselectorclass(); - $behatselectorclass::register_moodle_selectors($session); + $this->getSession()->getSelectorsHandler()->registerSelector('named_partial', new $namedpartialclass()); + $this->getSession()->getSelectorsHandler()->registerSelector('named_exact', new $namedexactclass()); } // Reset mink session between the scenarios. @@ -619,4 +627,3 @@ class behat_hooks extends behat_base { * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class behat_stop_exception extends \Exception { -}