Skip to content

Commit 73b35e6

Browse files
committed
Decoupled the DriverInterface from the NodeElement
This avoids a circular dependency. The driver interface now returns an array of XPath for found elements, and Element::find() instantiates the NodeElement for them. The driver is now the low level API which does not depend on any other part of Mink (but used by other parts).
1 parent a5572c4 commit 73b35e6

10 files changed

Lines changed: 362 additions & 126 deletions

File tree

src/Driver/CoreDriver.php

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010

1111
namespace Behat\Mink\Driver;
1212

13-
use Behat\Mink\Element\NodeElement;
1413
use Behat\Mink\Exception\UnsupportedDriverActionException;
1514
use Behat\Mink\KeyModifier;
16-
use Behat\Mink\Session;
1715

1816
/**
1917
* Core driver.
@@ -23,21 +21,6 @@
2321
*/
2422
abstract class CoreDriver implements DriverInterface
2523
{
26-
/**
27-
* @var Session
28-
*/
29-
private $session;
30-
31-
/**
32-
* @return void
33-
*
34-
* @final since 1.11
35-
*/
36-
public function setSession(Session $session)
37-
{
38-
$this->session = $session;
39-
}
40-
4124
/**
4225
* @return void
4326
*/
@@ -99,19 +82,13 @@ public function getContent()
9982
/**
10083
* @param string $xpath
10184
*
102-
* @return NodeElement[]
85+
* @return string[]
10386
*
10487
* @final since 1.11
10588
*/
10689
public function find($xpath)
10790
{
108-
$elements = array();
109-
110-
foreach ($this->findElementXpaths($xpath) as $xpath) {
111-
$elements[] = new NodeElement($xpath, $this, $this->session->getSelectorsHandler());
112-
}
113-
114-
return $elements;
91+
return $this->findElementXpaths($xpath);
11592
}
11693

11794
/**

src/Driver/DriverInterface.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010

1111
namespace Behat\Mink\Driver;
1212

13-
use Behat\Mink\Element\NodeElement;
1413
use Behat\Mink\Exception\DriverException;
1514
use Behat\Mink\Exception\UnsupportedDriverActionException;
1615
use Behat\Mink\KeyModifier;
17-
use Behat\Mink\Session;
1816

1917
/**
2018
* Driver interface.
@@ -23,15 +21,6 @@
2321
*/
2422
interface DriverInterface
2523
{
26-
/**
27-
* Sets driver's current session.
28-
*
29-
* @param Session $session
30-
*
31-
* @return void
32-
*/
33-
public function setSession(Session $session);
34-
3524
/**
3625
* Starts driver.
3726
*
@@ -299,7 +288,7 @@ public function getWindowName();
299288
*
300289
* @param string $xpath
301290
*
302-
* @return NodeElement[]
291+
* @return string[] An array of XPath queries for the found elements
303292
*
304293
* @throws UnsupportedDriverActionException When operation not supported by the driver
305294
* @throws DriverException When the operation cannot be done

src/Element/Element.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,24 @@ abstract class Element implements ElementInterface
3838
*/
3939
private $xpathManipulator;
4040

41+
/**
42+
* @var ElementFactory
43+
*/
44+
private $elementFactory;
45+
4146
/**
4247
* Initialize element.
4348
*
4449
* @param DriverInterface $driver
4550
* @param SelectorsHandler $selectorsHandler
51+
* @param ElementFactory $elementFactory
4652
*/
47-
public function __construct(DriverInterface $driver, SelectorsHandler $selectorsHandler)
53+
public function __construct(DriverInterface $driver, SelectorsHandler $selectorsHandler, ElementFactory $elementFactory)
4854
{
4955
$this->xpathManipulator = new Manipulator();
5056
$this->driver = $driver;
5157
$this->selectorsHandler = $selectorsHandler;
58+
$this->elementFactory = $elementFactory;
5259
}
5360

5461
/**
@@ -109,7 +116,7 @@ public function find($selector, $locator)
109116
{
110117
$items = $this->findAll($selector, $locator);
111118

112-
return count($items) ? current($items) : null;
119+
return count($items) ? $items[0] : null;
113120
}
114121

115122
/**
@@ -129,7 +136,13 @@ public function findAll($selector, $locator)
129136
$xpath = $this->selectorsHandler->selectorToXpath($selector, $locator);
130137
$xpath = $this->xpathManipulator->prepend($xpath, $this->getXpath());
131138

132-
return $this->getDriver()->find($xpath);
139+
$elements = array();
140+
141+
foreach ($this->getDriver()->find($xpath) as $elementXpath) {
142+
$elements[] = $this->elementFactory->createNodeElement($elementXpath, $this->driver, $this->selectorsHandler);
143+
}
144+
145+
return $elements;
133146
}
134147

135148
/**

src/Element/ElementFactory.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Mink package.
5+
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace Behat\Mink\Element;
12+
13+
use Behat\Mink\Driver\DriverInterface;
14+
use Behat\Mink\Selector\SelectorsHandler;
15+
16+
/**
17+
* Factory for element node.
18+
*
19+
* @author Christophe Coevoet <stof@notk.org>
20+
*/
21+
class ElementFactory
22+
{
23+
public function createNodeElement(string $xpath, DriverInterface $driver, SelectorsHandler $selectorsHandler): NodeElement
24+
{
25+
return new NodeElement($xpath, $driver, $selectorsHandler, $this);
26+
}
27+
}

src/Element/NodeElement.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ class NodeElement extends TraversableElement
3131
/**
3232
* Initializes node element.
3333
*
34-
* @param string $xpath element xpath
34+
* @param string $xpath element xpath
3535
* @param DriverInterface $driver
3636
* @param SelectorsHandler $selectorsHandler
37+
* @param ElementFactory $elementFactory
3738
*/
38-
public function __construct($xpath, DriverInterface $driver, SelectorsHandler $selectorsHandler)
39+
public function __construct($xpath, DriverInterface $driver, SelectorsHandler $selectorsHandler, ElementFactory $elementFactory)
3940
{
4041
$this->xpath = $xpath;
4142

42-
parent::__construct($driver, $selectorsHandler);
43+
parent::__construct($driver, $selectorsHandler, $elementFactory);
4344
}
4445

4546
/**

src/Session.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Behat\Mink;
1212

1313
use Behat\Mink\Driver\DriverInterface;
14+
use Behat\Mink\Element\ElementFactory;
1415
use Behat\Mink\Selector\SelectorsHandler;
1516
use Behat\Mink\Element\DocumentElement;
1617

@@ -39,18 +40,21 @@ class Session
3940
*
4041
* @param DriverInterface $driver
4142
* @param SelectorsHandler|null $selectorsHandler
43+
* @param ElementFactory|null $elementFactory
4244
*/
43-
public function __construct(DriverInterface $driver, SelectorsHandler $selectorsHandler = null)
45+
public function __construct(DriverInterface $driver, SelectorsHandler $selectorsHandler = null, ElementFactory $elementFactory = null)
4446
{
45-
$driver->setSession($this);
46-
4747
if (null === $selectorsHandler) {
4848
$selectorsHandler = new SelectorsHandler();
4949
}
5050

51+
if (null === $elementFactory) {
52+
$elementFactory = new ElementFactory();
53+
}
54+
5155
$this->driver = $driver;
5256
$this->selectorsHandler = $selectorsHandler;
53-
$this->page = new DocumentElement($driver, $selectorsHandler);
57+
$this->page = new DocumentElement($driver, $selectorsHandler, $elementFactory);
5458
}
5559

5660
/**

tests/Driver/CoreDriverTest.php

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
namespace Behat\Mink\Tests\Driver;
44

5-
use Behat\Mink\Element\NodeElement;
6-
use Behat\Mink\Selector\SelectorsHandler;
75
use PHPUnit\Framework\TestCase;
86

97
class CoreDriverTest extends TestCase
@@ -27,29 +25,19 @@ public function testCreateNodeElements()
2725
->setMethods(array('findElementXpaths'))
2826
->getMockForAbstractClass();
2927

30-
$session = $this->getMockBuilder('Behat\Mink\Session')
31-
->disableOriginalConstructor()
32-
->getMock();
33-
34-
$session->method('getSelectorsHandler')->willReturn($this->createMock(SelectorsHandler::class));
35-
36-
$driver->setSession($session);
37-
3828
$driver->expects($this->once())
3929
->method('findElementXpaths')
4030
->with('xpath')
4131
->willReturn(array('xpath1', 'xpath2'));
4232

43-
/** @var NodeElement[] $elements */
4433
$elements = $driver->find('xpath');
4534

4635
$this->assertIsArray($elements);
4736

4837
$this->assertCount(2, $elements);
49-
$this->assertContainsOnlyInstancesOf('Behat\Mink\Element\NodeElement', $elements);
5038

51-
$this->assertSame('xpath1', $elements[0]->getXpath());
52-
$this->assertSame('xpath2', $elements[1]->getXpath());
39+
$this->assertSame('xpath1', $elements[0]);
40+
$this->assertSame('xpath2', $elements[1]);
5341
}
5442

5543
/**

0 commit comments

Comments
 (0)