Skip to content

Commit

Permalink
Enhancement: Allow nesting of elements
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Nov 23, 2018
1 parent 3e695fb commit ab55033
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 1 deletion.
43 changes: 42 additions & 1 deletion doc/guide/working_with_elements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,48 @@ Accessing custom elements is much like accessing inline ones:
Page factory takes care of creating custom elements and their class names
follow the same rules as Page class names.

Elements can be nested, so similar to how elements can be retrieved from a `Page`, elements can also be
retrieved from an element:


.. code-block:: php
<?php
namespace Page\Element;
use SensioLabs\Behat\PageObjectExtension\PageObject\Element;
use SensioLabs\Behat\PageObjectExtension\PageObject\InlineElement;
use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
class Header extends Element
{
/**
* @var array|string $selector
*/
protected $selector = '.header';
protected $elements = [
'Logo' => '#logo',
];
/**
* @return SearchForm
*/
public function searchForm()
{
return $this->getElement(SearchForm::class);
}
/**
* @return InlineElement
*/
public function logo()
{
return $this->getElement('Logo')'
}
}
Element is an instance of a
`NodeElement <http://mink.behat.org/api/behat/mink/element/nodeelement.html>`_,
so similarly to pages, we can take advantage of existing `Mink <http://mink.behat.org/>`_
Expand All @@ -145,4 +187,3 @@ a full list of available methods:
* `NodeElement <http://mink.behat.org/api/behat/mink/element/nodeelement.html>`_
* `TraversableElement <http://mink.behat.org/api/behat/mink/element/traversableelement.html>`_
* `Element <http://mink.behat.org/api/behat/mink/element/element.html>`_

23 changes: 23 additions & 0 deletions spec/PageObject/ElementSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ class MyElement extends BaseElement
{
public $selector = array('xpath' => '//div[@id="my-box"]');

protected $elements = [
'Logo' => 'img#logo',
];

public function callGetPage($name)
{
return $this->getPage($name);
}

public function callGetElement($name)
{
return $this->getElement($name);
}

public function callGetName()
{
return $this->getName();
Expand Down Expand Up @@ -78,6 +87,20 @@ function it_creates_a_page(Factory $factory, Page $page)
$this->callGetPage('Home')->shouldReturn($page);
}

function it_creates_an_element(Factory $factory, BaseElement $element)
{
$factory->createElement('Button')->willReturn($element);

$this->callGetElement('Button')->shouldReturn($element);
}

function it_creates_an_inline_element(Factory $factory, BaseElement $element)
{
$factory->createElement('img#logo')->willReturn($element);

$this->callGetElement('Logo')->shouldReturn($element);
}

function it_returns_the_element_name()
{
$this->callGetName()->shouldReturn('MyElement');
Expand Down
46 changes: 46 additions & 0 deletions src/PageObject/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace SensioLabs\Behat\PageObjectExtension\PageObject;

use Behat\Mink\Element\NodeElement;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Selector\SelectorsHandler;
use Behat\Mink\Session;

Expand All @@ -13,6 +14,11 @@ abstract class Element extends NodeElement implements PageObject
*/
protected $selector = array('xpath' => '//');

/**
* @var array
*/
protected $elements = array();

/**
* @var Factory
*/
Expand Down Expand Up @@ -40,6 +46,22 @@ public function __call($name, $arguments)
throw new \BadMethodCallException($message);
}

/**
* @param string $name
*
* @return Element
*/
public function getElement($name)
{
$element = $this->createElement($name);

if (!$this->has('xpath', $element->getXpath())) {
throw new ElementNotFoundException(sprintf('"%s" element is not present on the page', $name));
}

return $element;
}

/**
* @param string $name
*
Expand All @@ -50,6 +72,30 @@ protected function getPage($name)
return $this->factory->createPage($name);
}

/**
* @param string $name
*
* @return boolean
*/
protected function hasElement($name)
{
return $this->has('xpath', $this->createElement($name)->getXpath());
}

/**
* @param string $name
*
* @return Element
*/
protected function createElement($name)
{
if (isset($this->elements[$name])) {
return $this->factory->createInlineElement($this->elements[$name]);
}

return $this->factory->createElement($name);
}

/**
* @return string
*/
Expand Down

0 comments on commit ab55033

Please sign in to comment.