/** * @dataProvider getSelectorTests * @group legacy */ public function testEscapedSelectors($fixtureFile, $selector, $locator, $expectedExactCount, $expectedPartialCount = null) { // Escape the locator as Mink 1.x expects the caller of the NamedSelector to handle it $escaper = new Escaper(); $locator = $escaper->escapeLiteral($locator); $this->testSelectors($fixtureFile, $selector, $locator, $expectedExactCount, $expectedPartialCount); }
/** * Returns the behat selector and locator for a given mahara selector and locator * * @param string $selectortype The mahara selector type, which includes mahara selectors * @param string $element The locator we look for in that kind of selector * @param Session $session The Mink opened session * @return array Contains the selector and the locator expected by Mink. */ public static function get_behat_selector($selectortype, $element, Behat\Mink\Session $session) { $escaper = new Escaper(); // CSS and XPath selectors locator is one single argument. if ($selectortype == 'css_element' || $selectortype == 'xpath_element') { $selector = str_replace('_element', '', $selectortype); $locator = $element; } else { // Named selectors uses arrays as locators including the type of named selector. $locator = array($selectortype, $escaper->escapeLiteral($element)); $selector = 'named'; } return array($selector, $locator); }
/** * Finds DOM nodes in the page using named selectors. * * The point of using this method instead of Mink ones is the spin * method of BehatBase::find() that looks for the element until it * is available or it timeouts, this avoids the false failures received * when selenium tries to execute commands on elements that are not * ready to be used. * * All steps that requires elements to be available before interact with * them should use one of the find* methods. * * The methods calls requires a {'find_' . $elementtype}($locator) * format, like find_link($locator), find_select($locator), * find_button($locator)... * * @link http://mink.behat.org/#named-selectors * @throws Exception * @param string $name The name of the called method * @param mixed $arguments * @return NodeElement */ public function __call($name, $arguments) { if (substr($name, 0, 5) !== 'find_') { throw new Exception('The "' . $name . '" method does not exist'); } // Only the named selector identifier. $cleanname = substr($name, 5); // All named selectors shares the interface. if (count($arguments) !== 1) { throw new Exception('The "' . $cleanname . '" named selector needs the locator as it\'s single argument'); } // Redirecting execution to the find method with the specified selector. // It will detect if it's pointing to an unexisting named selector. return $this->find('named', array($cleanname, $this->escaper->escapeLiteral($arguments[0]))); }
/** * @param Element $element * @param string $value * @param bool $multiple */ private function selectOptionOnElement(Element $element, $value, $multiple = false) { $escapedValue = $this->xpathEscaper->escapeLiteral($value); // The value of an option is the normalized version of its text when it has no value attribute $optionQuery = sprintf('.//option[@value = %s or (not(@value) and normalize-space(.) = %s)]', $escapedValue, $escapedValue); $option = $element->element('xpath', $optionQuery); if ($multiple || !$element->attribute('multiple')) { if (!$option->selected()) { $option->click(); } return; } // Deselect all options before selecting the new one $this->deselectAllOptions($element); $option->click(); }
/** * Translates provided locator into XPath. * * @param mixed $locator Current selector locator. * * @return string * @throws ElementException When used selector is broken or not implemented. */ public function translateToXPath($locator) { if (!$locator || !is_array($locator)) { throw new ElementException('Incorrect Selenium selector format', ElementException::TYPE_INCORRECT_SELECTOR); } list($selector, $locator) = each($locator); $locator = trim($locator); if ($selector == How::CLASS_NAME) { $locator = $this->_xpathEscaper->escapeLiteral(' ' . $locator . ' '); return "descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), " . $locator . ')]'; } elseif ($selector == How::CSS) { return $this->_cssSelector->translateToXPath($locator); } elseif ($selector == How::ID) { return 'descendant-or-self::*[@id = ' . $this->_xpathEscaper->escapeLiteral($locator) . ']'; } elseif ($selector == How::NAME) { return 'descendant-or-self::*[@name = ' . $this->_xpathEscaper->escapeLiteral($locator) . ']'; } elseif ($selector == How::ID_OR_NAME) { $locator = $this->_xpathEscaper->escapeLiteral($locator); return 'descendant-or-self::*[@id = ' . $locator . ' or @name = ' . $locator . ']'; } elseif ($selector == How::TAG_NAME) { return 'descendant-or-self::' . $locator; } elseif ($selector == How::LINK_TEXT) { $locator = $this->_xpathEscaper->escapeLiteral($locator); return 'descendant-or-self::a[./@href][normalize-space(string(.)) = ' . $locator . ']'; } elseif ($selector == How::LABEL) { $locator = $this->_xpathEscaper->escapeLiteral($locator); $xpath_pieces = array(); $xpath_pieces[] = 'descendant-or-self::*[@id = (//label[normalize-space(string(.)) = ' . $locator . ']/@for)]'; $xpath_pieces[] = 'descendant-or-self::label[normalize-space(string(.)) = ' . $locator . ']//input'; return implode('|', $xpath_pieces); } elseif ($selector == How::PARTIAL_LINK_TEXT) { $locator = $this->_xpathEscaper->escapeLiteral($locator); return 'descendant-or-self::a[./@href][contains(normalize-space(string(.)), ' . $locator . ')]'; } elseif ($selector == How::XPATH) { return $locator; } /*case How::LINK_TEXT: case How::PARTIAL_LINK_TEXT:*/ throw new ElementException(sprintf('Selector type "%s" not yet implemented', $selector), ElementException::TYPE_UNKNOWN_SELECTOR); }
/** * @param string $locator * @param string $selector * @param Element $container * * @return NodeElement * * @throws ElementNotFoundException */ protected function findElement($locator, $selector = 'xpath', Element $container = null) { $escaper = new Escaper(); if (null !== $container) { $field = $container->find($selector, $locator); } else { $field = $this->getSession()->getPage()->find($selector, $locator); } if (null === $field) { throw new ElementNotFoundException($this->getSession(), 'element', 'xpath', $escaper->escapeLiteral($locator)); } return $field; }
/** * @dataProvider getXpathLiterals */ public function testXpathLiteral($string, $expected) { $escaper = new Escaper(); $this->assertEquals($expected, $escaper->escapeLiteral($string)); }