Traversing Pages¶
Most usages of Mink will involve working with the page opened in your browser. This is done thanks to the powerful Element API. This API allows to traverse the page (similar to the DOM in Javascript), manipulate page elements and to interact with them, which will be covered in the next chapters.
DocumentElement and NodeElement¶
The Element API consists of 2 main classes. The DocumentElement instance
represents the page being displayed in the browser, while the NodeElement
class is used to represent any element inside the page. Both classes share
a common set of methods to traverse the page (defined in TraversableElement).
The DocumentElement instance is accessible through the Session::getPage method:
$page = $session->getPage();
// You can now manipulate the page.
Note
The DocumentElement instance represents the <html> node in the
DOM. It is equivalent to document.documentElement in the Javascript
DOM API.
Traversal Methods¶
Elements have 2 main traversal methods: ElementInterface::findAll returns
an array of NodeElement instances matching the provided selector
inside the current element while ElementInterface::find returns the first
match or null when there is none.
The TraversableElement class also provides a bunch of shortcut methods
on top of find() to make it easier to achieve many common use cases:
ElementInterface::has- Checks whether a child element matches the given selector but without returning it.
TraversableElement::findById- Looks for a child element with the given id.
TraversableElement::findLink- Looks for a link with the given text, title, id or
altattribute (for images used inside links). TraversableElement::findButton- Looks for a button with the given text, title, id,
nameattribute oraltattribute (for images used inside links). TraversableElement::findField- Looks for a field (
input,textareaorselect) with the given label, placeholder, id ornameattribute.
Note
These shortcuts return a single element. If you need to find all
matches, you will need to use findAll with the named selector.
Nested Traversing¶
Every find*() method will return a Behat\Mink\Element\NodeElement instance
and findAll() will return an array of such instances. The fun part is
that you can use the same methods of traversing on such elements as well:
$registerForm = $page->find('css', 'form.register');
if (null === $registerForm) {
throw new \Exception('The element is not found');
}
// find some field INSIDE form with class="register"
$field = $registerForm->findField('Email');
Selectors¶
The ElementInterface::find and ElementInterface::findAll methods
support several kinds of selectors to find elements.
CSS Selector¶
The css selector type lets you use CSS expressions to search for elements
on the page:
$title = $page->find('css', 'h1');
$buttonIcon = $page->find('css', '.btn > .icon');
XPath Selector¶
The xpath selector type lets you use XPath queries to search for elements
on the page:
$anchorsWithoutUrl = $page->findAll('xpath', '//a[not(@href)]');
Caution
This selector searches for an element inside the current node (which
is <html> for the page object). This means that trying to pass it
the XPath of an element retrieved with ElementInterface::getXpath
will not work (this query includes the query for the root node). To check
whether an element object still exists on the browser page, use ElementInterface::isValid
instead.
Named Selectors¶
Named selectors provide a set of reusable queries for common needs. For conditions
based on the content of elements, the named selector will try to find an
exact match first. It will then fallback to partial matching if there
is no result for the exact match. The named_exact selector type can be
used to force using only exact matching. The named_partial selector type
can be used to apply partial matching without preferring exact matches.
For the named selector type, the second argument of the find() method
is an array with 2 elements: the name of the query to use and the value to
search with this query:
$topLink = $page->find('named', array('link', $escapedValue));
The following queries are supported by the named selector:
id- Searches for an element by its id.
id_or_name- Searches for an element by its id or name.
link- Searches for a link by its id, title, img alt, rel or text.
button- Searches for a button by its name, id, text, img alt or title.
link_or_button- Searches for both links and buttons.
content- Searches for a specific page content (text).
field- Searches for a form field by its id, name, label or placeholder.
select- Searches for a select field by its id, name or label.
checkbox- Searches for a checkbox by its id, name, or label.
radio- Searches for a radio button by its id, name, or label.
file- Searches for a file input by its id, name, or label.
optgroup- Searches for an optgroup by its label.
option- Searches for an option by its content or value.
fieldset- Searches for a fieldset by its id or legend.
table- Searches for a table by its id or caption.
Custom Selector¶
Mink lets you register your own selector types through implementing the Behat\Mink\Selector\SelectorInterface.
It should then be registered in the SelectorsHandler which is the registry
of available selectors.
The recommended way to register a custom selector is to do it when building
your Session:
$selector = new \App\MySelector();
$handler = new \Behat\Mink\Selector\SelectorsHandler();
$handler->registerSelector('mine', $selector);
$driver = // ...
$session = new \Behat\Mink\Session($driver, $handler);