Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added helper find and findAll methods #102

Merged
merged 2 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
355 changes: 0 additions & 355 deletions phpstan-baseline.neon

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ includes:
- vendor/phpstan/phpstan-symfony/extension.neon

parameters:
treatPhpDocTypesAsCertain: false
level: 8
paths:
- src
Expand Down
1 change: 1 addition & 0 deletions src/lib/Browser/Assert/CollectionAssertInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ public function hasElements(): ElementCollectionInterface;

public function countEquals(int $expectedCount): ElementCollectionInterface;

/** @param array<string> $expectedElementTexts */
public function containsElementsWithText(array $expectedElementTexts): ElementCollectionInterface;
}
12 changes: 12 additions & 0 deletions src/lib/Browser/Component/Component.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

use Behat\Mink\Session;
use Facebook\WebDriver\Chrome\ChromeDevToolsDriver;
use Ibexa\Behat\Browser\Element\ElementCollectionInterface;
use Ibexa\Behat\Browser\Element\ElementInterface;
use Ibexa\Behat\Browser\Element\Factory\Debug\Highlighting\ElementFactory as HighlightingDebugElementFactory;
use Ibexa\Behat\Browser\Element\Factory\Debug\Interactive\ElementFactory as InteractiveDebugElementFactory;
use Ibexa\Behat\Browser\Element\Factory\ElementFactory;
Expand Down Expand Up @@ -46,6 +48,16 @@ final protected function getHTMLPage(): RootElementInterface
return $this->elementFactory->createRootElement($this->getSession(), $this->elementFactory);
}

public function find(LocatorInterface $locator): ElementInterface
{
return $this->getHTMLPage()->find($locator);
}

public function findAll(LocatorInterface $locator): ElementCollectionInterface
{
return $this->getHTMLPage()->findAll($locator);
}

public function setElementFactory(ElementFactoryInterface $elementFactory): void
{
$this->elementFactory = $elementFactory;
Expand Down
18 changes: 8 additions & 10 deletions src/lib/Browser/Element/BaseElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,18 @@

namespace Ibexa\Behat\Browser\Element;

use Behat\Mink\Element\ElementInterface as MinkElementInterface;
use Ibexa\Behat\Browser\Element\Condition\ConditionInterface;
use Ibexa\Behat\Browser\Element\Factory\ElementFactoryInterface;
use Ibexa\Behat\Browser\Exception\TimeoutException;
use Ibexa\Behat\Browser\Locator\LocatorInterface;
use Traversable;

class BaseElement implements BaseElementInterface
abstract class BaseElement implements BaseElementInterface
{
/** @var int */
protected $timeout = 1;
protected int $timeout = 1;

/** @var \Behat\Mink\Element\TraversableElement */
protected $decoratedElement;

/** @var \Ibexa\Behat\Browser\Element\Factory\ElementFactoryInterface */
private $elementFactory;
private ElementFactoryInterface $elementFactory;

public function __construct(ElementFactoryInterface $elementFactory)
{
Expand Down Expand Up @@ -83,7 +79,7 @@ public function find(LocatorInterface $locator): ElementInterface
{
return $this->waitUntil(
function () use ($locator) {
$foundMinkElements = $this->decoratedElement->findAll($locator->getType(), $locator->getSelector());
$foundMinkElements = $this->getDecoratedElement()->findAll($locator->getType(), $locator->getSelector());

foreach ($foundMinkElements as $foundMinkElement) {
$wrappedElement = $this->elementFactory->createElement($this->elementFactory, $locator, $foundMinkElement);
Expand Down Expand Up @@ -116,7 +112,7 @@ private function internalFindAll(LocatorInterface $locator): Traversable
{
try {
$minkElements = $this->waitUntil(function () use ($locator) {
$minkElements = $this->decoratedElement->findAll($locator->getType(), $locator->getSelector());
$minkElements = $this->getDecoratedElement()->findAll($locator->getType(), $locator->getSelector());
foreach ($minkElements as $minkElement) {
if (!$minkElement->isValid()) {
return false;
Expand All @@ -138,4 +134,6 @@ private function internalFindAll(LocatorInterface $locator): Traversable
}
}
}

abstract protected function getDecoratedElement(): MinkElementInterface;
}
5 changes: 5 additions & 0 deletions src/lib/Browser/Element/BaseElementInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,10 @@ public function findAll(LocatorInterface $locator): ElementCollectionInterface;

public function waitUntilCondition(ConditionInterface $condition): BaseElementInterface;

/**
* @param callable(mixed): mixed $callback
*
* @return mixed
*/
public function waitUntil(callable $callback, string $errorMessage);
}
12 changes: 9 additions & 3 deletions src/lib/Browser/Element/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@

final class Element extends BaseElement implements ElementInterface
{
/** @var \Ibexa\Behat\Browser\Locator\LocatorInterface */
private $locator;
private LocatorInterface $locator;

private NodeElement $decoratedElement;

public function __construct(ElementFactoryInterface $elementFactory, LocatorInterface $locator, NodeElement $baseElement)
{
Expand Down Expand Up @@ -116,7 +117,7 @@ public function assert(): ElementAssertInterface

public function isValid(): bool
{
return null !== $this->decoratedElement ? $this->decoratedElement->isValid() : false;
return $this->decoratedElement->isValid();
}

public function selectOption(string $option): void
Expand Down Expand Up @@ -153,4 +154,9 @@ public function execute(ActionInterface $action): void
{
$action->execute($this);
}

protected function getDecoratedElement(): NodeElement
{
return $this->decoratedElement;
}
}
18 changes: 9 additions & 9 deletions src/lib/Browser/Element/ElementCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@

class ElementCollection implements ElementCollectionInterface
{
/** @var ElementInterface[]|\Traversable */
/** @var iterable<ElementInterface> */
private $elements;

/**
* @var \Ibexa\Behat\Browser\Locator\LocatorInterface
*/
private $locator;
private LocatorInterface $locator;

public function __construct(LocatorInterface $locator, iterable $elements)
{
Expand All @@ -38,9 +35,6 @@ public function setElements(array $elements): void
$this->elements = $elements;
}

/**
* @return \Ibexa\Behat\Browser\Element\ElementInterface[]
*/
public function getIterator(): Traversable
{
if (is_array($this->elements)) {
Expand All @@ -64,7 +58,7 @@ public function getByCriterion(CriterionInterface $criterion): ElementInterface
}

/**
* @param callable Callable accepting a NodeElement parameter
* @param callable(ElementInterface): bool $callable
*/
public function getBy(callable $callable): ElementInterface
{
Expand Down Expand Up @@ -208,6 +202,11 @@ public function assert(): CollectionAssertInterface
return new CollectionAssert($this->locator, $this);
}

/**
* @param callable(ElementInterface $element): bool $callable
*
* @return iterable<ElementInterface>
*/
private function internalFilter(callable $callable): iterable
{
foreach ($this->elements as $element) {
Expand All @@ -217,6 +216,7 @@ private function internalFilter(callable $callable): iterable
}
}

/** @return iterable<ElementInterface> */
private function internalFilterBy(CriterionInterface $criterion): iterable
{
foreach ($this->elements as $element) {
Expand Down
14 changes: 13 additions & 1 deletion src/lib/Browser/Element/ElementCollectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
interface ElementCollectionInterface extends \Countable, \IteratorAggregate
{
/**
* @return \Ibexa\Behat\Browser\Element\ElementInterface[]
* @return Traversable<ElementInterface>
*/
public function getIterator(): Traversable;

/**
* @param array<ElementInterface> $elements
*/
public function setElements(array $elements): void;

public function getByCriterion(CriterionInterface $criterion): ElementInterface;
Expand All @@ -44,10 +47,19 @@ public function any(): bool;

public function single(): ElementInterface;

/**
* @param callable(ElementInterface): mixed $callable
*
* @return array<mixed>
*/
public function map(callable $callable): array;

/** @return array<mixed> */
public function mapBy(MapperInterface $mapper): array;

/**
* @param callable(ElementInterface): bool $callable
*/
public function filter(callable $callable): ElementCollectionInterface;

public function filterBy(CriterionInterface $criterion): ElementCollectionInterface;
Expand Down
1 change: 1 addition & 0 deletions src/lib/Browser/Element/Mapper/MapperInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@

interface MapperInterface
{
/** @return mixed */
public function map(ElementInterface $element);
}
12 changes: 9 additions & 3 deletions src/lib/Browser/Element/RootElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@

final class RootElement extends BaseElement implements RootElementInterface
{
/** @vat \Behat\Mink\Session */
private $session;
private Session $session;

private DocumentElement $decoratedElement;

public function __construct(ElementFactoryInterface $elementFactory, Session $session, DocumentElement $baseElement)
{
Expand All @@ -42,6 +43,11 @@ private function isDraggingLibraryLoaded(): bool

public function executeJavaScript(string $script): string
{
return (string) $this->session->evaluateScript($script) ?? '';
return $this->session->evaluateScript($script) ?? '';
}

protected function getDecoratedElement(): DocumentElement
{
return $this->decoratedElement;
}
}
4 changes: 2 additions & 2 deletions src/lib/Browser/Locator/BaseLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

abstract class BaseLocator implements LocatorInterface
{
protected $selector;
protected string $selector;

protected $identifier;
protected string $identifier;

public function __construct(string $identifier, string $selector)
{
Expand Down
6 changes: 3 additions & 3 deletions src/lib/Browser/Page/LoginPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public function logout(): void

public function loginSuccessfully($username, $password): void
{
$this->getHTMLPage()->find($this->getLocator('username'))->setValue($username);
$this->getHTMLPage()->find($this->getLocator('password'))->setValue($password);
$this->getHTMLPage()->findAll($this->getLocator('button'))
$this->find($this->getLocator('username'))->setValue($username);
$this->find($this->getLocator('password'))->setValue($password);
$this->findAll($this->getLocator('button'))
->filterBy(new LogicalOrCriterion([
new ElementTextCriterion('Login'),
new ElementTextCriterion('Log in'),
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Browser/Page/Preview/FolderPreview.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function setExpectedPreviewData(array $data)

public function verifyPreviewData()
{
$this->getHTMLPage()->find($this->getLocator('title'))->assert()->textEquals($this->expectedPageTitle);
$this->find($this->getLocator('title'))->assert()->textEquals($this->expectedPageTitle);
}

public function supports(string $contentTypeIdentifier, string $viewType): bool
Expand Down
Loading