Skip to content

Commit 618c3d1

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). The ElementFinder is responsible for instantiating the NodeElement.
1 parent 4a14114 commit 618c3d1

10 files changed

Lines changed: 25 additions & 102 deletions

File tree

src/Driver/CoreDriver.php

Lines changed: 2 additions & 25 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
* Core driver.
@@ -24,21 +22,6 @@
2422
*/
2523
abstract class CoreDriver implements DriverInterface
2624
{
27-
/**
28-
* @var Session
29-
*/
30-
private $session;
31-
32-
/**
33-
* @return void
34-
*
35-
* @final since 1.11
36-
*/
37-
public function setSession(Session $session)
38-
{
39-
$this->session = $session;
40-
}
41-
4225
/**
4326
* @return void
4427
*
@@ -282,7 +265,7 @@ public function getWindowName()
282265
/**
283266
* @param string $xpath
284267
*
285-
* @return NodeElement[]
268+
* @return string[]
286269
*
287270
* @throws UnsupportedDriverActionException When operation not supported by the driver
288271
* @throws DriverException When the operation cannot be done
@@ -291,13 +274,7 @@ public function getWindowName()
291274
*/
292275
public function find(string $xpath)
293276
{
294-
$elements = array();
295-
296-
foreach ($this->findElementXpaths($xpath) as $xpath) {
297-
$elements[] = new NodeElement($xpath, $this, $this->session->getElementFinder());
298-
}
299-
300-
return $elements;
277+
return $this->findElementXpaths($xpath);
301278
}
302279

303280
/**

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
use JetBrains\PhpStorm\Language;
1917

2018
/**
@@ -24,15 +22,6 @@
2422
*/
2523
interface DriverInterface
2624
{
27-
/**
28-
* Sets driver's current session.
29-
*
30-
* @param Session $session
31-
*
32-
* @return void
33-
*/
34-
public function setSession(Session $session);
35-
3625
/**
3726
* Starts driver.
3827
*
@@ -300,7 +289,7 @@ public function getWindowName();
300289
*
301290
* @param string $xpath
302291
*
303-
* @return NodeElement[]
292+
* @return string[] An array of XPath queries for the found elements
304293
*
305294
* @throws UnsupportedDriverActionException When operation not supported by the driver
306295
* @throws DriverException When the operation cannot be done

src/Element/Element.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public function find(string $selector, $locator)
8888
{
8989
$items = $this->findAll($selector, $locator);
9090

91-
return count($items) ? current($items) : null;
91+
return count($items) ? $items[0] : null;
9292
}
9393

9494
/**

src/Element/ElementFinder.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ public function __construct(DriverInterface $driver, SelectorsHandler $selectors
4343
/**
4444
* @param string|array $locator
4545
*
46-
* @return NodeElement[]
46+
* @return list<NodeElement>
4747
*/
48-
public function findAll(string $selector, $locator, string $parentXpath)
48+
public function findAll(string $selector, $locator, string $parentXpath): array
4949
{
5050
if ('named' === $selector) {
5151
$items = $this->findAll('named_exact', $locator, $parentXpath);
@@ -59,6 +59,12 @@ public function findAll(string $selector, $locator, string $parentXpath)
5959
$xpath = $this->selectorsHandler->selectorToXpath($selector, $locator);
6060
$xpath = $this->xpathManipulator->prepend($xpath, $parentXpath);
6161

62-
return $this->driver->find($xpath);
62+
$elements = array();
63+
64+
foreach ($this->driver->find($xpath) as $elementXpath) {
65+
$elements[] = new NodeElement($elementXpath, $this->driver, $this);
66+
}
67+
68+
return $elements;
6369
}
6470
}

src/Element/NodeElement.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class NodeElement extends TraversableElement
3030
/**
3131
* Initializes node element.
3232
*
33-
* @param string $xpath element xpath
33+
* @param string $xpath element xpath
3434
* @param DriverInterface $driver
3535
* @param ElementFinder $elementFinder
3636
*/

src/Session.php

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
use Behat\Mink\Driver\DriverInterface;
1414
use Behat\Mink\Element\ElementFinder;
15-
use Behat\Mink\Selector\SelectorsHandler;
1615
use Behat\Mink\Element\DocumentElement;
16+
use Behat\Mink\Selector\SelectorsHandler;
1717

1818
/**
1919
* Mink session.
@@ -30,18 +30,12 @@ class Session
3030
* @var DocumentElement
3131
*/
3232
private $page;
33-
/**
34-
* @var ElementFinder
35-
*/
36-
private $elementFinder;
3733

3834
public function __construct(DriverInterface $driver, ?SelectorsHandler $selectorsHandler = null)
3935
{
4036
$this->driver = $driver;
41-
$this->elementFinder = new ElementFinder($driver, $selectorsHandler ?? new SelectorsHandler());
42-
$this->page = new DocumentElement($driver, $this->elementFinder);
43-
44-
$driver->setSession($this);
37+
$elementFinder = new ElementFinder($driver, $selectorsHandler ?? new SelectorsHandler());
38+
$this->page = new DocumentElement($driver, $elementFinder);
4539
}
4640

4741
/**
@@ -131,14 +125,6 @@ public function getPage()
131125
return $this->page;
132126
}
133127

134-
/**
135-
* @internal
136-
*/
137-
public function getElementFinder(): ElementFinder
138-
{
139-
return $this->elementFinder;
140-
}
141-
142128
/**
143129
* Visit specified URL and automatically start session if not already running.
144130
*

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\ElementFinder;
6-
use Behat\Mink\Element\NodeElement;
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('getElementFinder')->willReturn($this->createMock(ElementFinder::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
/**

tests/Element/ElementFinderTest.php

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,6 @@ public function testNotFound()
6363

6464
public function testFound()
6565
{
66-
$element1 = $this->createStub(NodeElement::class);
67-
$element1->method('getXpath')->willReturn('element1');
68-
69-
$element2 = $this->createStub(NodeElement::class);
70-
$element2->method('getXpath')->willReturn('element2');
71-
7266
$this->selectorsHandler->expects($this->once())
7367
->method('selectorToXpath')
7468
->with('css', 'h3 > a')
@@ -82,7 +76,7 @@ public function testFound()
8276
$this->driver->expects($this->once())
8377
->method('find')
8478
->with('full_xpath')
85-
->will($this->returnValue(array($element1, $element2)));
79+
->will($this->returnValue(array('element1', 'element2')));
8680

8781
$results = $this->finder->findAll('css', 'h3 > a', 'parent_xpath');
8882

@@ -94,12 +88,6 @@ public function testFound()
9488

9589
public function testNamedFound()
9690
{
97-
$element1 = $this->createStub(NodeElement::class);
98-
$element1->method('getXpath')->willReturn('element1');
99-
100-
$element2 = $this->createStub(NodeElement::class);
101-
$element2->method('getXpath')->willReturn('element2');
102-
10391
$this->selectorsHandler->expects($this->once())
10492
->method('selectorToXpath')
10593
->with('named_exact', 'test')
@@ -113,7 +101,7 @@ public function testNamedFound()
113101
$this->driver->expects($this->once())
114102
->method('find')
115103
->with('full_xpath')
116-
->will($this->returnValue(array($element1, $element2)));
104+
->will($this->returnValue(array('element1', 'element2')));
117105

118106
$results = $this->finder->findAll('named', 'test', 'parent_xpath');
119107

@@ -125,12 +113,6 @@ public function testNamedFound()
125113

126114
public function testNamedPartialFallback()
127115
{
128-
$element1 = $this->createStub(NodeElement::class);
129-
$element1->method('getXpath')->willReturn('element1');
130-
131-
$element2 = $this->createStub(NodeElement::class);
132-
$element2->method('getXpath')->willReturn('element2');
133-
134116
$this->selectorsHandler->expects($this->exactly(2))
135117
->method('selectorToXpath')
136118
->will($this->returnValueMap(array(
@@ -149,7 +131,7 @@ public function testNamedPartialFallback()
149131
->method('find')
150132
->willReturnMap(array(
151133
array('full_xpath', array()),
152-
array('full_partial_xpath', array($element1, $element2)),
134+
array('full_partial_xpath', array('element1', 'element2')),
153135
));
154136

155137
$results = $this->finder->findAll('named', 'test', 'parent_xpath');

tests/Element/NodeElementTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function testElementIsValid()
5252
->expects($this->once())
5353
->method('find')
5454
->with($elementXpath)
55-
->willReturn(array($this->createStub(NodeElement::class)));
55+
->willReturn(array($elementXpath));
5656

5757
$this->assertTrue($node->isValid());
5858
}
@@ -78,7 +78,7 @@ public function testElementIsNotValidWithMultipleFound()
7878
->expects($this->once())
7979
->method('find')
8080
->with('some xpath')
81-
->willReturn(array($this->createStub(NodeElement::class), $this->createStub(NodeElement::class)));
81+
->willReturn(array('some xpath', 'some other xpath'));
8282

8383
$this->assertFalse($node->isValid(), 'more then 1 element found is invalid element');
8484
}

tests/SessionTest.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ class SessionTest extends TestCase
1414
* @var DriverInterface&MockObject
1515
*/
1616
private $driver;
17-
/**
18-
* @var SelectorsHandler
19-
*/
20-
private $selectorsHandler;
2117

2218
/**
2319
* Session.
@@ -32,8 +28,7 @@ class SessionTest extends TestCase
3228
protected function prepareSession(): void
3329
{
3430
$this->driver = $this->getMockBuilder('Behat\Mink\Driver\DriverInterface')->getMock();
35-
$this->selectorsHandler = $this->getMockBuilder('Behat\Mink\Selector\SelectorsHandler')->getMock();
36-
$this->session = new Session($this->driver, $this->selectorsHandler);
31+
$this->session = new Session($this->driver);
3732
}
3833

3934
public function testGetDriver()

0 commit comments

Comments
 (0)