Skip to content

Commit

Permalink
Use own exception hierachy
Browse files Browse the repository at this point in the history
  • Loading branch information
OskarStark committed Oct 3, 2024
1 parent 24ac78d commit e9b5b46
Show file tree
Hide file tree
Showing 25 changed files with 186 additions and 75 deletions.
32 changes: 17 additions & 15 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
use Symfony\Component\Panther\DomCrawler\Crawler as PantherCrawler;
use Symfony\Component\Panther\DomCrawler\Form as PantherForm;
use Symfony\Component\Panther\DomCrawler\Link as PantherLink;
use Symfony\Component\Panther\Exception\InvalidArgumentException;
use Symfony\Component\Panther\Exception\LogicException;
use Symfony\Component\Panther\ProcessManager\BrowserManagerInterface;
use Symfony\Component\Panther\ProcessManager\ChromeManager;
use Symfony\Component\Panther\ProcessManager\FirefoxManager;
Expand Down Expand Up @@ -138,18 +140,18 @@ public function start(): void

public function getRequest(): object
{
throw new \LogicException('HttpFoundation Request object is not available when using WebDriver.');
throw new LogicException('HttpFoundation Request object is not available when using WebDriver.');
}

public function getResponse(): object
{
throw new \LogicException('HttpFoundation Response object is not available when using WebDriver.');
throw new LogicException('HttpFoundation Response object is not available when using WebDriver.');
}

public function followRedirects($followRedirects = true): void
{
if (!$followRedirects) {
throw new \InvalidArgumentException('Redirects are always followed when using WebDriver.');
throw new InvalidArgumentException('Redirects are always followed when using WebDriver.');
}
}

Expand All @@ -161,7 +163,7 @@ public function isFollowingRedirects(): bool
public function setMaxRedirects($maxRedirects): void
{
if (-1 !== $maxRedirects) {
throw new \InvalidArgumentException('There are no max redirects when using WebDriver.');
throw new InvalidArgumentException('There are no max redirects when using WebDriver.');
}
}

Expand All @@ -173,28 +175,28 @@ public function getMaxRedirects(): int
public function insulate($insulated = true): void
{
if (!$insulated) {
throw new \InvalidArgumentException('Requests are always insulated when using WebDriver.');
throw new InvalidArgumentException('Requests are always insulated when using WebDriver.');
}
}

public function setServerParameters(array $server): void
{
throw new \InvalidArgumentException('Server parameters cannot be set when using WebDriver.');
throw new InvalidArgumentException('Server parameters cannot be set when using WebDriver.');
}

public function setServerParameter($key, $value): void
{
throw new \InvalidArgumentException('Server parameters cannot be set when using WebDriver.');
throw new InvalidArgumentException('Server parameters cannot be set when using WebDriver.');
}

public function getServerParameter($key, $default = ''): mixed
{
throw new \InvalidArgumentException('Server parameters cannot be retrieved when using WebDriver.');
throw new InvalidArgumentException('Server parameters cannot be retrieved when using WebDriver.');
}

public function getHistory(): History
{
throw new \LogicException('History is not available when using WebDriver.');
throw new LogicException('History is not available when using WebDriver.');
}

public function click(Link $link, array $serverParameters = []): Crawler
Expand Down Expand Up @@ -255,18 +257,18 @@ public function refreshCrawler(): PantherCrawler
public function request(string $method, string $uri, array $parameters = [], array $files = [], array $server = [], ?string $content = null, bool $changeHistory = true): PantherCrawler
{
if ('GET' !== $method) {
throw new \InvalidArgumentException('Only the GET method is supported when using WebDriver.');
throw new InvalidArgumentException('Only the GET method is supported when using WebDriver.');
}
if (null !== $content) {
throw new \InvalidArgumentException('Setting a content is not supported when using WebDriver.');
throw new InvalidArgumentException('Setting a content is not supported when using WebDriver.');
}
if (!$changeHistory) {
throw new \InvalidArgumentException('The history always change when using WebDriver.');
throw new InvalidArgumentException('The history always change when using WebDriver.');
}

foreach (['parameters', 'files', 'server'] as $arg) {
if ([] !== $$arg) {
throw new \InvalidArgumentException(\sprintf('The parameter "$%s" is not supported when using WebDriver.', $arg));
throw new InvalidArgumentException(\sprintf('The parameter "$%s" is not supported when using WebDriver.', $arg));
}
}

Expand All @@ -286,7 +288,7 @@ protected function createCrawler(): PantherCrawler

protected function doRequest($request)
{
throw new \LogicException('Not useful in WebDriver mode.');
throw new LogicException('Not useful in WebDriver mode.');
}

public function back(): PantherCrawler
Expand Down Expand Up @@ -315,7 +317,7 @@ public function reload(): PantherCrawler

public function followRedirect(): PantherCrawler
{
throw new \LogicException('Redirects are always followed when using WebDriver.');
throw new LogicException('Redirects are always followed when using WebDriver.');
}

public function restart(): void
Expand Down
18 changes: 10 additions & 8 deletions src/DomCrawler/Crawler.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
use Facebook\WebDriver\WebDriverElement;
use Symfony\Component\CssSelector\CssSelectorConverter;
use Symfony\Component\DomCrawler\Crawler as BaseCrawler;
use Symfony\Component\Panther\Exception\InvalidArgumentException;
use Symfony\Component\Panther\Exception\LogicException;
use Symfony\Component\Panther\ExceptionThrower;

/**
Expand Down Expand Up @@ -206,12 +208,12 @@ public function nodeName(): string
public function text(?string $default = null, bool $normalizeWhitespace = true): string
{
if (!$normalizeWhitespace) {
throw new \InvalidArgumentException('Panther only supports getting normalized text.');
throw new InvalidArgumentException('Panther only supports getting normalized text.');
}

try {
return $this->getElementOrThrow()->getText();
} catch (\InvalidArgumentException $e) {
} catch (InvalidArgumentException $e) {
if (null === $default) {
throw $e;
}
Expand All @@ -230,7 +232,7 @@ public function html(?string $default = null): string
}

return $this->attr('outerHTML', (string) $default);
} catch (\InvalidArgumentException $e) {
} catch (InvalidArgumentException $e) {
if (null === $default) {
throw $e;
}
Expand Down Expand Up @@ -299,7 +301,7 @@ public function link($method = 'get'): Link
{
$element = $this->getElementOrThrow();
if ('get' !== $method) {
throw new \InvalidArgumentException('Only the "get" method is supported in WebDriver mode.');
throw new InvalidArgumentException('Only the "get" method is supported in WebDriver mode.');
}

return new Link($element, $this->webDriver->getCurrentURL());
Expand Down Expand Up @@ -352,7 +354,7 @@ public function registerNamespace($prefix, $namespace): void

public function getNode($position): ?\DOMElement
{
throw new \InvalidArgumentException('The "getNode" method cannot be used in WebDriver mode. Use "getElement" instead.');
throw new InvalidArgumentException('The "getNode" method cannot be used in WebDriver mode. Use "getElement" instead.');
}

public function getElement(int $position): ?WebDriverElement
Expand Down Expand Up @@ -423,7 +425,7 @@ private function getElementOrThrow(): WebDriverElement
{
$element = $this->getElement(0);
if (!$element) {
throw new \InvalidArgumentException('The current node list is empty.');
throw new InvalidArgumentException('The current node list is empty.');
}

return $element;
Expand Down Expand Up @@ -510,12 +512,12 @@ public function findElements(WebDriverBy $locator): array
}

/**
* @throws \LogicException If the CssSelector Component is not available
* @throws LogicException If the CssSelector Component is not available
*/
private function createCssSelectorConverter(): CssSelectorConverter
{
if (!class_exists(CssSelectorConverter::class)) {
throw new \LogicException('To filter with a CSS selector, install the CssSelector component ("composer require symfony/css-selector"). Or use filterXpath instead.');
throw new LogicException('To filter with a CSS selector, install the CssSelector component ("composer require symfony/css-selector"). Or use filterXpath instead.');
}

return new CssSelectorConverter();
Expand Down
20 changes: 11 additions & 9 deletions src/DomCrawler/Field/ChoiceFormField.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
use Facebook\WebDriver\WebDriverSelect;
use Facebook\WebDriver\WebDriverSelectInterface;
use Symfony\Component\DomCrawler\Field\ChoiceFormField as BaseChoiceFormField;
use Symfony\Component\Panther\Exception\InvalidArgumentException;
use Symfony\Component\Panther\Exception\LogicException;
use Symfony\Component\Panther\WebDriver\WebDriverCheckbox;

/**
Expand Down Expand Up @@ -47,12 +49,12 @@ public function select($value): void
/**
* Ticks a checkbox.
*
* @throws \LogicException When the type provided is not correct
* @throws LogicException When the type provided is not correct
*/
public function tick(): void
{
if ('checkbox' !== $type = $this->element->getAttribute('type')) {
throw new \LogicException(\sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->element->getAttribute('name'), $type));
throw new LogicException(\sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->element->getAttribute('name'), $type));
}

$this->setValue(true);
Expand All @@ -61,12 +63,12 @@ public function tick(): void
/**
* Ticks a checkbox.
*
* @throws \LogicException When the type provided is not correct
* @throws LogicException When the type provided is not correct
*/
public function untick(): void
{
if ('checkbox' !== $type = $this->element->getAttribute('type')) {
throw new \LogicException(\sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->element->getAttribute('name'), $type));
throw new LogicException(\sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->element->getAttribute('name'), $type));
}

$this->setValue(false);
Expand Down Expand Up @@ -108,13 +110,13 @@ public function getValue(): array|string|null
*
* @param string|array|bool $value The value of the field
*
* @throws \InvalidArgumentException When value type provided is not correct
* @throws InvalidArgumentException When value type provided is not correct
*/
public function setValue($value): void
{
if (\is_bool($value)) {
if ('checkbox' !== $this->type) {
throw new \InvalidArgumentException(\sprintf('Invalid argument of type "%s"', \gettype($value)));
throw new InvalidArgumentException(\sprintf('Invalid argument of type "%s"', \gettype($value)));
}

if ($value) {
Expand Down Expand Up @@ -183,18 +185,18 @@ public function disableValidation(): static
/**
* Initializes the form field.
*
* @throws \LogicException When node type is incorrect
* @throws LogicException When node type is incorrect
*/
protected function initialize(): void
{
$tagName = $this->element->getTagName();
if ('input' !== $tagName && 'select' !== $tagName) {
throw new \LogicException(\sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $tagName));
throw new LogicException(\sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $tagName));
}

$type = strtolower((string) $this->element->getAttribute('type'));
if ('input' === $tagName && 'checkbox' !== $type && 'radio' !== $type) {
throw new \LogicException(\sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $type));
throw new LogicException(\sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $type));
}

$this->type = 'select' === $tagName ? 'select' : $type;
Expand Down
7 changes: 4 additions & 3 deletions src/DomCrawler/Field/FileFormField.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Symfony\Component\Panther\DomCrawler\Field;

use Symfony\Component\DomCrawler\Field\FileFormField as BaseFileFormField;
use Symfony\Component\Panther\Exception\LogicException;

/**
* @author Robert Freigang <[email protected]>
Expand Down Expand Up @@ -61,18 +62,18 @@ public function setFilePath(string $path): void
/**
* Initializes the form field.
*
* @throws \LogicException When node type is incorrect
* @throws LogicException When node type is incorrect
*/
protected function initialize(): void
{
$tagName = $this->element->getTagName();
if ('input' !== $tagName) {
throw new \LogicException(\sprintf('A FileFormField can only be created from an input tag (%s given).', $tagName));
throw new LogicException(\sprintf('A FileFormField can only be created from an input tag (%s given).', $tagName));
}

$type = strtolower($this->element->getAttribute('type'));
if ('file' !== $type) {
throw new \LogicException(\sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $type));
throw new LogicException(\sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $type));
}

$value = $this->element->getAttribute('value');
Expand Down
9 changes: 5 additions & 4 deletions src/DomCrawler/Field/InputFormField.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Symfony\Component\Panther\DomCrawler\Field;

use Symfony\Component\DomCrawler\Field\InputFormField as BaseInputFormField;
use Symfony\Component\Panther\Exception\LogicException;

/**
* @author Kévin Dunglas <[email protected]>
Expand Down Expand Up @@ -42,22 +43,22 @@ public function setValue($value): void
/**
* Initializes the form field.
*
* @throws \LogicException When node type is incorrect
* @throws LogicException When node type is incorrect
*/
protected function initialize(): void
{
$tagName = $this->element->getTagName();
if ('input' !== $tagName && 'button' !== $tagName) {
throw new \LogicException(\sprintf('An InputFormField can only be created from an input or button tag (%s given).', $tagName));
throw new LogicException(\sprintf('An InputFormField can only be created from an input or button tag (%s given).', $tagName));
}

$type = strtolower((string) $this->element->getAttribute('type'));
if ('checkbox' === $type) {
throw new \LogicException('Checkboxes should be instances of ChoiceFormField.');
throw new LogicException('Checkboxes should be instances of ChoiceFormField.');
}

if ('file' === $type) {
throw new \LogicException('File inputs should be instances of FileFormField.');
throw new LogicException('File inputs should be instances of FileFormField.');
}
}
}
5 changes: 3 additions & 2 deletions src/DomCrawler/Field/TextareaFormField.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Symfony\Component\Panther\DomCrawler\Field;

use Symfony\Component\DomCrawler\Field\TextareaFormField as BaseTextareaFormField;
use Symfony\Component\Panther\Exception\LogicException;

/**
* @author Kévin Dunglas <[email protected]>
Expand All @@ -30,13 +31,13 @@ public function setValue(?string $value): void
/**
* Initializes the form field.
*
* @throws \LogicException When node type is incorrect
* @throws LogicException When node type is incorrect
*/
protected function initialize(): void
{
$tagName = $this->element->getTagName();
if ('textarea' !== $tagName) {
throw new \LogicException(\sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $tagName));
throw new LogicException(\sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $tagName));
}
}
}
10 changes: 6 additions & 4 deletions src/DomCrawler/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
use Symfony\Component\Panther\DomCrawler\Field\FileFormField;
use Symfony\Component\Panther\DomCrawler\Field\InputFormField;
use Symfony\Component\Panther\DomCrawler\Field\TextareaFormField;
use Symfony\Component\Panther\Exception\LogicException;
use Symfony\Component\Panther\Exception\RuntimeException;
use Symfony\Component\Panther\ExceptionThrower;
use Symfony\Component\Panther\WebDriver\WebDriverCheckbox;

Expand Down Expand Up @@ -60,7 +62,7 @@ private function setElement(WebDriverElement $element): void
try {
$form = $this->webDriver->findElement(WebDriverBy::id($formId));
} catch (NoSuchElementException $e) {
throw new \LogicException(\sprintf('The selected node has an invalid form attribute (%s).', $formId));
throw new LogicException(\sprintf('The selected node has an invalid form attribute (%s).', $formId));
}

$this->element = $form;
Expand All @@ -72,11 +74,11 @@ private function setElement(WebDriverElement $element): void
try {
$element = $element->findElement(WebDriverBy::xpath('..'));
} catch (NoSuchElementException $e) {
throw new \LogicException('The selected node does not have a form ancestor.');
throw new LogicException('The selected node does not have a form ancestor.');
}
} while ('form' !== $element->getTagName());
} elseif ('form' !== $tagName = $element->getTagName()) {
throw new \LogicException(\sprintf('Unable to submit on a "%s" tag.', $tagName));
throw new LogicException(\sprintf('Unable to submit on a "%s" tag.', $tagName));
}

$this->element = $element;
Expand Down Expand Up @@ -323,7 +325,7 @@ private function getValue(WebDriverElement $element)
{
if (null === $webDriverSelect = $this->getWebDriverSelect($element)) {
if (!$this->webDriver instanceof JavaScriptExecutor) {
throw new \RuntimeException('To retrieve this value, the browser must support JavaScript.');
throw new RuntimeException('To retrieve this value, the browser must support JavaScript.');
}

return $this->webDriver->executeScript('return arguments[0].value', [$element]);
Expand Down
Loading

0 comments on commit e9b5b46

Please sign in to comment.