sensiolabs / BehatPageObjectExtension

MIT License
116 stars 48 forks source link

Support extending InlineElement #82

Closed stephenharris closed 7 years ago

stephenharris commented 7 years ago

Currently, inline elements allow you to create elements on a page at runtime, but the instances of these elements are always InlineElement.

This PR aims to allow you to replace that with a child class, so that additional methods can be provided.

This is useful in a situation where you have multiple elements on a page with the same behaviour, but different selector and you want to capture that behaviour in an API. E.g.

class ToDoListRow extends InlineElement
{
    function markAsComplete(){ ... }
    function clickEditLink(){ ... }
    function delete(){ ... }
    function isMarkedComplete(){ ... }
}

The first commit extends the factory in a back-wards compatible way. The second commit is a breaking change by changing the behaviour of Page by passing the name of inline element to the factory (so that it tries to resolve it to a class, rather than using InlineElement).

stephenharris commented 7 years ago

The PR fails some of the existing tests (because of 0b45859).

If this PR is something you'd would consider accepting - either that commit can be removed or, it fallsback to InlineElement when the resolved class name does not exist.

stephenharris commented 7 years ago

On reflection 0b45859 doesn't help the stated use-case, as element names are used as keys. I've reverted it, but the change to the factory is still useful. Here's a mock-up of an example:

class ToDoList extends Element
{
    protected $selector = '.todo-list';
    private $factory = null;

    public function __construct(Session $session, Factory $factory)
    {
        parent::__construct($session, $factory);
        $this->factory = $factory;
    }

    public function getRows()
    {
        $rows = $this->findAll('css', 'tbody tr');
        $tableRows = array();
        foreach ($rows as $row) {
            $tableRows[] = $this->factory->createInlineElement($row->getXpath(), 'ToDoListRow');
        }
        return $tableRows;
    }
}
jakzal commented 7 years ago

Thanks @stephenharris for taking care of this. I'll review this soon.

jakzal commented 7 years ago

@stephenharris thank you so much for working on this. I made slight improvements and sent a new PR: #85

I'd appreciate if you looked at it.