Skip to content

Commit

Permalink
Merge pull request #222 from aik099/do-not-inject-se-selector
Browse files Browse the repository at this point in the history
Change Selenium Selector resolution principle
  • Loading branch information
aik099 committed Mar 22, 2024
2 parents 488aa8c + 0bfaa2f commit bd6e6e4
Show file tree
Hide file tree
Showing 33 changed files with 389 additions and 243 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,10 +6,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Added the public `Page::getBrowserUrl` method, that returns URL of the Web Browser (overriding allows operating within a frameset).
- Added the protected `Page::setBrowserUrl` method, that sets URL of the Web Browser (overriding allows operating within a frameset).
- Added the public `PageFactory::translateToXPath` method for converting Selenium-style selector (how + using) into XPath.

### Changed
- The `WebElement::waitFor` method now provide `WebElement` class (or used subclass, like `AbstractElementContainer`, etc.) instance to the callback instead of a Mink's `NodeElement` class instance.
- The `Page::waitFor` method now provide `Page` class (or used subclass, like `TypifiedPage`, `BEMPage`, etc.) instance to the callback instead of a Mink's `DocumentElement` class instance.
- The `se` selector handler is no longer registered in the Mink Session (use the `PageFactory::translateToXPath` instead).

### Fixed
...
Expand Down
6 changes: 5 additions & 1 deletion library/QATools/QATools/BEM/BEMPageFactory.php
Expand Up @@ -60,7 +60,11 @@ public function __construct(Session $session, $container_or_config = null, Locat
*/
public function createDecorator(ISearchContext $search_context)
{
$locator_factory = new BEMElementLocatorFactory($search_context, $this->_locatorHelper);
$locator_factory = new BEMElementLocatorFactory(
$search_context,
$this->seleniumSelector,
$this->_locatorHelper
);

return new BEMPropertyDecorator($locator_factory, $this);
}
Expand Down
14 changes: 13 additions & 1 deletion library/QATools/QATools/BEM/Element/Block.php
Expand Up @@ -37,6 +37,13 @@ class Block extends AbstractPart implements IBlock
*/
private $_locator;

/**
* Page factory.
*
* @var IPageFactory
*/
private $_pageFactory;

/**
* Create instance of BEM block.
*
Expand All @@ -51,6 +58,7 @@ public final function __construct($name, array $nodes, IPageFactory $page_factor

$this->_nodes = $nodes;
$this->_locator = $locator;
$this->_pageFactory = $page_factory;

$page_factory->initElements($this, $page_factory->createDecorator($this));
}
Expand Down Expand Up @@ -99,7 +107,11 @@ public function getElements($element_name, $modificator_name = null, $modificato
$modificator_value
);

return $this->findAll('se', $locator);
$how = key($locator);
$using = $locator[$how];
$xpath = $this->_pageFactory->translateToXPath($how, $using);

return $this->findAll('xpath', $xpath);
}

/**
Expand Down
11 changes: 7 additions & 4 deletions library/QATools/QATools/BEM/ElementLocator/BEMElementLocator.php
Expand Up @@ -17,6 +17,7 @@
use QATools\QATools\PageObject\Exception\AnnotationException;
use QATools\QATools\PageObject\ISearchContext;
use QATools\QATools\PageObject\Property;
use QATools\QATools\PageObject\SeleniumSelector;

/**
* Locates BEM blocks/elements.
Expand All @@ -36,16 +37,18 @@ class BEMElementLocator extends DefaultElementLocator
/**
* Creates a new element locator.
*
* @param Property $property Property.
* @param ISearchContext $search_context The context to use when finding the element.
* @param LocatorHelper $locator_helper Locator helper.
* @param Property $property Property.
* @param ISearchContext $search_context The context to use when finding the element.
* @param SeleniumSelector $selenium_selector Selenium selector.
* @param LocatorHelper $locator_helper Locator helper.
*/
public function __construct(
Property $property,
ISearchContext $search_context,
SeleniumSelector $selenium_selector,
LocatorHelper $locator_helper
) {
parent::__construct($property, $search_context);
parent::__construct($property, $search_context, $selenium_selector);

$this->_helper = $locator_helper;
}
Expand Down
Expand Up @@ -15,6 +15,7 @@
use QATools\QATools\PageObject\ElementLocator\IElementLocator;
use QATools\QATools\PageObject\ISearchContext;
use QATools\QATools\PageObject\Property;
use QATools\QATools\PageObject\SeleniumSelector;

/**
* Factory to create BEM block/element locators.
Expand All @@ -34,14 +35,16 @@ class BEMElementLocatorFactory extends DefaultElementLocatorFactory
/**
* Create locator factory instance.
*
* @param ISearchContext $search_context Search context.
* @param LocatorHelper $locator_helper Locator helper.
* @param ISearchContext $search_context Search context.
* @param SeleniumSelector $selenium_selector Selenium selector.
* @param LocatorHelper $locator_helper Locator helper.
*/
public function __construct(
ISearchContext $search_context,
SeleniumSelector $selenium_selector,
LocatorHelper $locator_helper
) {
parent::__construct($search_context);
parent::__construct($search_context, $selenium_selector);
$this->_locatorHelper = $locator_helper;
}

Expand All @@ -54,7 +57,7 @@ public function __construct(
*/
public function createLocator(Property $property)
{
return new BEMElementLocator($property, $this->searchContext, $this->_locatorHelper);
return new BEMElementLocator($property, $this->searchContext, $this->seleniumSelector, $this->_locatorHelper);
}

}
7 changes: 6 additions & 1 deletion library/QATools/QATools/HtmlElements/Element/Select.php
Expand Up @@ -47,7 +47,12 @@ public function isMultiple()
*/
public function getOptions()
{
return $this->wrapOptions($this->getWrappedElement()->findAll('se', array(How::TAG_NAME => 'option')));
return $this->wrapOptions(
$this->getWrappedElement()->findAll(
'xpath',
$this->getPageFactory()->translateToXPath(How::TAG_NAME, 'option')
)
);
}

/**
Expand Down
Expand Up @@ -49,7 +49,7 @@ public function __construct(Session $session, $container_or_config = null)
*/
public function createDecorator(ISearchContext $search_context)
{
$locator_factory = new DefaultElementLocatorFactory($search_context);
$locator_factory = new DefaultElementLocatorFactory($search_context, $this->seleniumSelector);

return new TypifiedPropertyDecorator($locator_factory, $this);
}
Expand Down
4 changes: 4 additions & 0 deletions library/QATools/QATools/PageObject/Container.php
Expand Up @@ -77,6 +77,10 @@ public function __construct(array $values = array())

return $page_url_matcher_registry;
};

$this['selenium_selector'] = function () {
return new SeleniumSelector();
};
}

}
Expand Up @@ -17,6 +17,7 @@
use QATools\QATools\PageObject\Exception\ElementException;
use QATools\QATools\PageObject\ISearchContext;
use QATools\QATools\PageObject\Property;
use QATools\QATools\PageObject\SeleniumSelector;

/**
* Class, that locates WebElements.
Expand All @@ -40,16 +41,28 @@ class DefaultElementLocator implements IElementLocator
*/
protected $property;

/**
* Selenium selector.
*
* @var SeleniumSelector
*/
protected $seleniumSelector;

/**
* Creates a new element locator.
*
* @param Property $property Property.
* @param ISearchContext $search_context The context to use when finding the element.
* @param Property $property Property.
* @param ISearchContext $search_context The context to use when finding the element.
* @param SeleniumSelector $selenium_selector Selenium selector.
*/
public function __construct(Property $property, ISearchContext $search_context)
{
public function __construct(
Property $property,
ISearchContext $search_context,
SeleniumSelector $selenium_selector
) {
$this->property = $property;
$this->searchContext = $search_context;
$this->seleniumSelector = $selenium_selector;
}

/**
Expand Down Expand Up @@ -85,7 +98,11 @@ public function findAll()
$elements = array();

foreach ( $this->getSelectors() as $selector ) {
$elements = array_merge($elements, $this->searchContext->findAll('se', $selector));
$how = key($selector);
$using = $selector[$how];
$xpath = $this->seleniumSelector->translateToXPath($how, $using);

$elements = array_merge($elements, $this->searchContext->findAll('xpath', $xpath));
}

$element_count = count($elements);
Expand Down Expand Up @@ -164,7 +181,7 @@ public function __toString()
$selectors = $this->getSelectors();

foreach ( $selectors as $selector ) {
$exported_selectors[] = array('se' => $selector);
$exported_selectors[] = $selector;
}

return var_export($exported_selectors, true);
Expand Down
Expand Up @@ -13,6 +13,7 @@

use QATools\QATools\PageObject\ISearchContext;
use QATools\QATools\PageObject\Property;
use QATools\QATools\PageObject\SeleniumSelector;

/**
* Factory, that creates locators for finding WebElements.
Expand All @@ -29,14 +30,23 @@ class DefaultElementLocatorFactory implements IElementLocatorFactory
*/
protected $searchContext;

/**
* Selenium selector.
*
* @var SeleniumSelector
*/
protected $seleniumSelector;

/**
* Create locator factory instance.
*
* @param ISearchContext $search_context Search context.
* @param ISearchContext $search_context Search context.
* @param SeleniumSelector $selenium_selector Selenium selector.
*/
public function __construct(ISearchContext $search_context)
public function __construct(ISearchContext $search_context, SeleniumSelector $selenium_selector)
{
$this->searchContext = $search_context;
$this->seleniumSelector = $selenium_selector;
}

/**
Expand All @@ -48,7 +58,7 @@ public function __construct(ISearchContext $search_context)
*/
public function createLocator(Property $property)
{
return new WaitingElementLocator($property, $this->searchContext);
return new WaitingElementLocator($property, $this->searchContext, $this->seleniumSelector);
}

}
Expand Up @@ -15,6 +15,7 @@
use QATools\QATools\PageObject\Annotation\TimeoutAnnotation;
use QATools\QATools\PageObject\ISearchContext;
use QATools\QATools\PageObject\Property;
use QATools\QATools\PageObject\SeleniumSelector;

/**
* Class, that locates WebElements that might not be present at the moment.
Expand All @@ -34,12 +35,16 @@ class WaitingElementLocator extends DefaultElementLocator
/**
* Creates a new element locator.
*
* @param Property $property Property.
* @param ISearchContext $search_context The context to use when finding the element.
* @param Property $property Property.
* @param ISearchContext $search_context The context to use when finding the element.
* @param SeleniumSelector $selenium_selector Selenium selector.
*/
public function __construct(Property $property, ISearchContext $search_context)
{
parent::__construct($property, $search_context);
public function __construct(
Property $property,
ISearchContext $search_context,
SeleniumSelector $selenium_selector
) {
parent::__construct($property, $search_context, $selenium_selector);

/** @var TimeoutAnnotation[] $annotations */
$annotations = $property->getAnnotationsFromPropertyOrClass('@timeout');
Expand Down
10 changes: 10 additions & 0 deletions library/QATools/QATools/PageObject/IPageFactory.php
Expand Up @@ -85,4 +85,14 @@ public function getPage($class_name);
*/
public function opened(Page $page);

/**
* Translates provided how/using combo into XPath.
*
* @param string $how How class constant.
* @param string $using Using value.
*
* @return string
*/
public function translateToXPath($how, $using);

}
45 changes: 23 additions & 22 deletions library/QATools/QATools/PageObject/PageFactory.php
Expand Up @@ -87,6 +87,13 @@ class PageFactory implements IPageFactory
*/
protected $pageUrlMatcherRegistry;

/**
* Selenium selector.
*
* @var SeleniumSelector
*/
protected $seleniumSelector;

/**
* The current config.
*
Expand Down Expand Up @@ -118,14 +125,15 @@ public function __construct(Session $session, $container_or_config = null)
$container_or_config = $this->_createContainer();
}

$this->_setSession($session);
$this->_session = $session;
$this->config = $container_or_config['config'];

$this->_setAnnotationManager($container_or_config['annotation_manager']);
$this->urlFactory = $container_or_config['url_factory'];
$this->urlNormalizer = $container_or_config['url_normalizer'];
$this->pageLocator = $container_or_config['page_locator'];
$this->pageUrlMatcherRegistry = $container_or_config['page_url_matcher_registry'];
$this->seleniumSelector = $container_or_config['selenium_selector'];
}

/**
Expand Down Expand Up @@ -173,31 +181,11 @@ private function _setAnnotationManager(AnnotationManager $manager)
*/
public function createDecorator(ISearchContext $search_context)
{
$locator_factory = new DefaultElementLocatorFactory($search_context);
$locator_factory = new DefaultElementLocatorFactory($search_context, $this->seleniumSelector);

return new DefaultPropertyDecorator($locator_factory, $this);
}

/**
* Sets session.
*
* @param Session $session Session.
*
* @return self
*/
private function _setSession(Session $session)
{
$selectors_handler = $session->getSelectorsHandler();

if ( !$selectors_handler->isSelectorRegistered('se') ) {
$selectors_handler->registerSelector('se', new SeleniumSelector());
}

$this->_session = $session;

return $this;
}

/**
* Returns session.
*
Expand Down Expand Up @@ -326,4 +314,17 @@ public function getPage($class_name)
return new $resolved_page_class($this);
}

/**
* Translates provided how/using combo into XPath.
*
* @param string $how How class constant.
* @param string $using Using value.
*
* @return string
*/
public function translateToXPath($how, $using)
{
return $this->seleniumSelector->translateToXPath($how, $using);
}

}

0 comments on commit bd6e6e4

Please sign in to comment.