From cc1ce2e9b292f4c0d17a66caa78be728aa69f7c9 Mon Sep 17 00:00:00 2001 From: Jeffrey Guo Date: Tue, 22 Jul 2014 12:27:05 +1200 Subject: [PATCH 1/8] added more methods to get child and sibling elements --- src/Behat/Mink/Element/NodeElement.php | 86 ++++++++++++++++++- src/Behat/Mink/Element/TraversableElement.php | 26 +++++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/src/Behat/Mink/Element/NodeElement.php b/src/Behat/Mink/Element/NodeElement.php index 1f867ed0d..a7d85a75d 100644 --- a/src/Behat/Mink/Element/NodeElement.php +++ b/src/Behat/Mink/Element/NodeElement.php @@ -54,7 +54,91 @@ public function getParent() { return $this->find('xpath', '..'); } - + + /** + * Returns All child elements(including descendant) to the current one. + * + * @return NodeElements|null + */ + public function getAllChildren() + { + return $this->findAll('xpath', 'descendant::*'); + } + + /** + * Returns All direct child elements(NOT including deeper descendant) to the current one. + * + * @return NodeElements|null + */ + public function getDirectChildren() + { + return $this->findAll('xpath', 'child::*'); + } + + /** + * Returns the first child element to the current one. + * + * @return NodeElement|null + */ + public function getFirstChild() + { + $elements = $this->findAll('xpath', 'child::*'); + return $elements[0]; + } + + /** + * Returns the last direct child element to the current one. + * + * @return NodeElement|null + */ + public function getLastChild() + { + $elements = $this->findAll('xpath', 'child::*'); + return $elements[count($elements) - 1]; + } + + /** + * Returns all preceding sibling elements to the current one. + * + * @return NodeElements|null + */ + public function getPreviousSiblings() + { + return $this->findAll('xpath', 'preceding-sibling::*'); + } + + /** + * Returns the preceding sibling element close to the current one. + * + * @return NodeElement|null + */ + public function getPreviousSibling() + { + $elements = $this->findAll('xpath', 'preceding-sibling::*'); + return $elements[count($elements) - 1]; + } + + /** + * Returns all following sibling elements to the current one. + * + * @return NodeElements|null + */ + public function getNextSiblings() + { + return $this->findAll('xpath', 'following-sibling::*'); + } + + /** + * Returns the following sibling element close to the current one. + * + * @return NodeElement|null + */ + public function getNextSibling() + { + $elements = $this->findAll('xpath', 'following-sibling::*'); + return $elements[0]; + } + /** * Returns current node tag name. * diff --git a/src/Behat/Mink/Element/TraversableElement.php b/src/Behat/Mink/Element/TraversableElement.php index 27843d2dd..37dd2d0fa 100644 --- a/src/Behat/Mink/Element/TraversableElement.php +++ b/src/Behat/Mink/Element/TraversableElement.php @@ -32,7 +32,31 @@ public function findById($id) return $this->find('named', array('id', $id)); } - + + /** + * Finds element by its name. + * + * @param string name element name + * @return NodeElement|NodeElements|null + */ + public function findByName($name) + { + $name = $this->getSelectorsHandler()->xpathLiteral($name); + return $this->find('xpath', ".//*[@name=$name]"); + } + + /** + * Finds elements by its tag. + * + * @param string tag element tag + * @return NodeElements|null + */ + public function findByTag($tag) + { + $tag = $this->getSelectorsHandler()->xpathLiteral($tag); + return $this->findAll('css', $tag); + } + /** * Checks whether element has a link with specified locator. * From 96f97b147214d19cd496611573e8c4086f49cdd0 Mon Sep 17 00:00:00 2001 From: Jeffrey Guo Date: Wed, 23 Jul 2014 21:41:36 +1200 Subject: [PATCH 2/8] Added id_or_name to namedSelector.php and corrected indentation --- src/Behat/Mink/Element/NodeElement.php | 166 +++++++++--------- src/Behat/Mink/Element/TraversableElement.php | 49 +++--- src/Behat/Mink/Selector/NamedSelector.php | 4 + 3 files changed, 109 insertions(+), 110 deletions(-) diff --git a/src/Behat/Mink/Element/NodeElement.php b/src/Behat/Mink/Element/NodeElement.php index a7d85a75d..17c1e9878 100644 --- a/src/Behat/Mink/Element/NodeElement.php +++ b/src/Behat/Mink/Element/NodeElement.php @@ -54,91 +54,87 @@ public function getParent() { return $this->find('xpath', '..'); } - - /** - * Returns All child elements(including descendant) to the current one. - * - * @return NodeElements|null - */ - public function getAllChildren() - { - return $this->findAll('xpath', 'descendant::*'); - } - - /** - * Returns All direct child elements(NOT including deeper descendant) to the current one. - * - * @return NodeElements|null - */ - public function getDirectChildren() - { - return $this->findAll('xpath', 'child::*'); - } - - /** - * Returns the first child element to the current one. - * - * @return NodeElement|null - */ - public function getFirstChild() - { - $elements = $this->findAll('xpath', 'child::*'); - return $elements[0]; - } - - /** - * Returns the last direct child element to the current one. - * - * @return NodeElement|null - */ - public function getLastChild() - { - $elements = $this->findAll('xpath', 'child::*'); - return $elements[count($elements) - 1]; - } - - /** - * Returns all preceding sibling elements to the current one. - * - * @return NodeElements|null - */ - public function getPreviousSiblings() - { - return $this->findAll('xpath', 'preceding-sibling::*'); - } - - /** - * Returns the preceding sibling element close to the current one. - * - * @return NodeElement|null - */ - public function getPreviousSibling() - { - $elements = $this->findAll('xpath', 'preceding-sibling::*'); - return $elements[count($elements) - 1]; - } - - /** - * Returns all following sibling elements to the current one. - * - * @return NodeElements|null - */ - public function getNextSiblings() - { - return $this->findAll('xpath', 'following-sibling::*'); - } - - /** - * Returns the following sibling element close to the current one. - * - * @return NodeElement|null - */ - public function getNextSibling() - { - $elements = $this->findAll('xpath', 'following-sibling::*'); - return $elements[0]; - } - + + /** + * Returns All child elements(including descendant) to the current one. + * + * @return NodeElement[]|null + */ + public function getAllChildren() + { + return $this->findAll('xpath', 'descendant::*'); + } + + /** + * Returns All direct child elements(NOT including deeper descendant) to the current one. + * + * @return NodeElement[]|null + */ + public function getDirectChildren() + { + return $this->findAll('xpath', 'child::*'); + } + + /** + * Returns the first child element to the current one. + * + * @return static|null + */ + public function getFirstChild() + { + return $this->find('xpath', 'child::*[1]'); + } + + /** + * Returns the last direct child element to the current one. + * + * @return static|null + */ + public function getLastChild() + { + return $this->find('xpath', 'child::*[last()]'); + } + + /** + * Returns all preceding sibling elements to the current one. + * + * @return NodeElement[]|null + */ + public function getPreviousSiblings() + { + return $this->findAll('xpath', 'preceding-sibling::*'); + } + + /** + * Returns the preceding sibling element close to the current one. + * + * @return static|null + */ + public function getPreviousSibling() + { + return $this->find('xpath', 'preceding-sibling::*[1]'); + } + + /** + * Returns all following sibling elements to the current one. + * + * @return NodeElement[]|null + */ + public function getNextSiblings() + { + return $this->findAll('xpath', 'following-sibling::*'); + } + + /** + * Returns the following sibling element close to the current one. + * + * @return static|null + */ + public function getNextSibling() + { + return $this->find('xpath', 'following-sibling::*[1]'); + } + /** * Returns current node tag name. * diff --git a/src/Behat/Mink/Element/TraversableElement.php b/src/Behat/Mink/Element/TraversableElement.php index 37dd2d0fa..7a8c2c3e8 100644 --- a/src/Behat/Mink/Element/TraversableElement.php +++ b/src/Behat/Mink/Element/TraversableElement.php @@ -32,31 +32,30 @@ public function findById($id) return $this->find('named', array('id', $id)); } - - /** - * Finds element by its name. - * - * @param string name element name - * @return NodeElement|NodeElements|null - */ - public function findByName($name) - { - $name = $this->getSelectorsHandler()->xpathLiteral($name); - return $this->find('xpath', ".//*[@name=$name]"); - } - - /** - * Finds elements by its tag. - * - * @param string tag element tag - * @return NodeElements|null - */ - public function findByTag($tag) - { - $tag = $this->getSelectorsHandler()->xpathLiteral($tag); - return $this->findAll('css', $tag); - } - + + /** + * Finds element by its name. + * + * @param string name element name + * @return NodeElement|null + */ + public function findByName($name) + { + $name = $this->getSelectorsHandler()->xpathLiteral($name); + return $this->find('named', array('id_or_name', $name)); + } + + /** + * Finds elements by its tag. + * + * @param string tag element tag + * @return NodeElement[]|null + */ + public function findByTag($tag) + { + return $this->findAll('css', $tag); + } + /** * Checks whether element has a link with specified locator. * diff --git a/src/Behat/Mink/Selector/NamedSelector.php b/src/Behat/Mink/Selector/NamedSelector.php index a7e8d193c..b2498af36 100644 --- a/src/Behat/Mink/Selector/NamedSelector.php +++ b/src/Behat/Mink/Selector/NamedSelector.php @@ -153,6 +153,10 @@ class NamedSelector implements SelectorInterface ,'id' => << << Date: Wed, 23 Jul 2014 21:57:14 +1200 Subject: [PATCH 3/8] Removed white space in id_or_name --- src/Behat/Mink/Selector/NamedSelector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Behat/Mink/Selector/NamedSelector.php b/src/Behat/Mink/Selector/NamedSelector.php index b2498af36..500644afd 100644 --- a/src/Behat/Mink/Selector/NamedSelector.php +++ b/src/Behat/Mink/Selector/NamedSelector.php @@ -156,7 +156,7 @@ class NamedSelector implements SelectorInterface ,'id_or_name' => << Date: Thu, 24 Jul 2014 08:48:56 +1200 Subject: [PATCH 4/8] Added replacement nameMatch for new method findByName and updated comments format --- src/Behat/Mink/Element/NodeElement.php | 12 ++++++------ src/Behat/Mink/Element/TraversableElement.php | 6 +++--- src/Behat/Mink/Selector/NamedSelector.php | 5 +++-- tests/Selector/NamedSelectorTest.php | 2 ++ 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Behat/Mink/Element/NodeElement.php b/src/Behat/Mink/Element/NodeElement.php index 17c1e9878..6a79e934f 100644 --- a/src/Behat/Mink/Element/NodeElement.php +++ b/src/Behat/Mink/Element/NodeElement.php @@ -56,9 +56,9 @@ public function getParent() } /** - * Returns All child elements(including descendant) to the current one. + * Returns All child elements (including descendant) to the current one. * - * @return NodeElement[]|null + * @return static[]|null */ public function getAllChildren() { @@ -66,9 +66,9 @@ public function getAllChildren() } /** - * Returns All direct child elements(NOT including deeper descendant) to the current one. + * Returns All direct child elements (NOT including deeper descendant) to the current one. * - * @return NodeElement[]|null + * @return static[]|null */ public function getDirectChildren() { @@ -98,7 +98,7 @@ public function getLastChild() /** * Returns all preceding sibling elements to the current one. * - * @return NodeElement[]|null + * @return static[]|null */ public function getPreviousSiblings() { @@ -118,7 +118,7 @@ public function getPreviousSibling() /** * Returns all following sibling elements to the current one. * - * @return NodeElement[]|null + * @return static[]|null */ public function getNextSiblings() { diff --git a/src/Behat/Mink/Element/TraversableElement.php b/src/Behat/Mink/Element/TraversableElement.php index 7a8c2c3e8..b2834a512 100644 --- a/src/Behat/Mink/Element/TraversableElement.php +++ b/src/Behat/Mink/Element/TraversableElement.php @@ -37,19 +37,19 @@ public function findById($id) * Finds element by its name. * * @param string name element name - * @return NodeElement|null + * @return static|null */ public function findByName($name) { $name = $this->getSelectorsHandler()->xpathLiteral($name); - return $this->find('named', array('id_or_name', $name)); + return $this->find('named', array('name', $name)); } /** * Finds elements by its tag. * * @param string tag element tag - * @return NodeElement[]|null + * @return static[]|null */ public function findByTag($tag) { diff --git a/src/Behat/Mink/Selector/NamedSelector.php b/src/Behat/Mink/Selector/NamedSelector.php index 500644afd..5af43c456 100644 --- a/src/Behat/Mink/Selector/NamedSelector.php +++ b/src/Behat/Mink/Selector/NamedSelector.php @@ -32,6 +32,7 @@ class NamedSelector implements SelectorInterface '%altMatch%' => 'contains(./@alt, %locator%)', '%relMatch%' => 'contains(./@rel, %locator%)', '%labelAttributeMatch%' => 'contains(./@label, %locator%)', + '%nameMatch%' => './@name = %locator%', // complex replacements '%inputTypeWithoutPlaceholderFilter%' => "%lowercaseType% = 'radio' or %lowercaseType% = 'checkbox' or %lowercaseType% = 'file'", @@ -154,8 +155,8 @@ class NamedSelector implements SelectorInterface .//*[%idMatch%] XPATH - ,'id_or_name' => << << array('test.html', 'table', 'the-table', 2, 3), 'id' => array('test.html', 'id', 'bad-link-text', 1), + + 'name' => array('test.html', 'name', 'element-name', 1), ); } From 0f20bfe5376a1924d32dc4b22065adfbcea6fb00 Mon Sep 17 00:00:00 2001 From: Jeffrey Guo Date: Thu, 24 Jul 2014 12:14:11 +1200 Subject: [PATCH 5/8] Corrected the element name for nameselector test --- tests/Selector/NamedSelectorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Selector/NamedSelectorTest.php b/tests/Selector/NamedSelectorTest.php index bc983e85e..70f5f7743 100644 --- a/tests/Selector/NamedSelectorTest.php +++ b/tests/Selector/NamedSelectorTest.php @@ -142,7 +142,7 @@ public function getSelectorTests() 'id' => array('test.html', 'id', 'bad-link-text', 1), - 'name' => array('test.html', 'name', 'element-name', 1), + 'name' => array('test.html', 'name', 'the-field', 1), ); } From d832fd6babcc83c0f72dea94129a3d76d866b779 Mon Sep 17 00:00:00 2001 From: Jeffrey Guo Date: Thu, 24 Jul 2014 12:55:26 +1200 Subject: [PATCH 6/8] Updated expected result from 1 to 11 for `name` test --- tests/Selector/NamedSelectorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Selector/NamedSelectorTest.php b/tests/Selector/NamedSelectorTest.php index 70f5f7743..1dfe62389 100644 --- a/tests/Selector/NamedSelectorTest.php +++ b/tests/Selector/NamedSelectorTest.php @@ -142,7 +142,7 @@ public function getSelectorTests() 'id' => array('test.html', 'id', 'bad-link-text', 1), - 'name' => array('test.html', 'name', 'the-field', 1), + 'name' => array('test.html', 'name', 'the-field', 11), ); } From ef96fdb4ad165076095b70f4074e5d8cbd6d3303 Mon Sep 17 00:00:00 2001 From: Jeffrey Guo Date: Fri, 25 Jul 2014 13:02:25 +1200 Subject: [PATCH 7/8] Update name selector for partial search --- src/Behat/Mink/Selector/ExactNamedSelector.php | 1 + src/Behat/Mink/Selector/PartialNamedSelector.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Behat/Mink/Selector/ExactNamedSelector.php b/src/Behat/Mink/Selector/ExactNamedSelector.php index 03315a9cf..12a21b806 100644 --- a/src/Behat/Mink/Selector/ExactNamedSelector.php +++ b/src/Behat/Mink/Selector/ExactNamedSelector.php @@ -23,6 +23,7 @@ public function __construct() $this->registerReplacement('%altMatch%', './@alt = %locator%'); $this->registerReplacement('%relMatch%', './@rel = %locator%'); $this->registerReplacement('%labelAttributeMatch%', './@label = %locator%'); + $this->registerReplacement('%nameMatch%', './@name = %locator%'); parent::__construct(); } diff --git a/src/Behat/Mink/Selector/PartialNamedSelector.php b/src/Behat/Mink/Selector/PartialNamedSelector.php index b864a2265..5903899e3 100644 --- a/src/Behat/Mink/Selector/PartialNamedSelector.php +++ b/src/Behat/Mink/Selector/PartialNamedSelector.php @@ -25,6 +25,7 @@ public function __construct() $this->registerReplacement('%altMatch%', 'contains(./@alt, %locator%)'); $this->registerReplacement('%relMatch%', 'contains(./@rel, %locator%)'); $this->registerReplacement('%labelAttributeMatch%', 'contains(./@label, %locator%)'); + $this->registerReplacement('%nameMatch%', 'contains(./@name, %locator%)'); parent::__construct(); } From ca4a9e63ef78d031c71a0b794f9f2282113a8e42 Mon Sep 17 00:00:00 2001 From: Jeffrey Guo Date: Fri, 25 Jul 2014 13:21:23 +1200 Subject: [PATCH 8/8] partial search for findByName --- src/Behat/Mink/Selector/NamedSelector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Behat/Mink/Selector/NamedSelector.php b/src/Behat/Mink/Selector/NamedSelector.php index 5af43c456..431217ea1 100644 --- a/src/Behat/Mink/Selector/NamedSelector.php +++ b/src/Behat/Mink/Selector/NamedSelector.php @@ -32,7 +32,7 @@ class NamedSelector implements SelectorInterface '%altMatch%' => 'contains(./@alt, %locator%)', '%relMatch%' => 'contains(./@rel, %locator%)', '%labelAttributeMatch%' => 'contains(./@label, %locator%)', - '%nameMatch%' => './@name = %locator%', + '%nameMatch%' => 'contains(./@name, %locator%)', // complex replacements '%inputTypeWithoutPlaceholderFilter%' => "%lowercaseType% = 'radio' or %lowercaseType% = 'checkbox' or %lowercaseType% = 'file'",