Behat/Mink — pull request #385 by bevanr (2013-10-08 03:53:58+00:00)
Title: Allow exact matching with named selectors

As per #265 and #320, this implements a second parameter for `findLink()`, `findButton()` and `findField()` which allows exact-matching of named selectors.

The implementation uses a new class `ExactSelector`, which is registered in `SelectorsHandler` as a new selector with ID `exact`. Thus neither the `ElementInterface` nor `Element` classes need to be modified. `ExactSelector` inherits from `NamedSelector` and uses different default values for the `$selectors` property (which must now be `protected` instead of `private`).

I tried creating an abstract class with the methods that two subclasses (for each of partial and exact matching) could inherit from, however I was not able to understand this _Fatal error: Cannot instantiate abstract class Behat\Mink\Selector\NamedSelector in vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/ContainerBuilder.php on line 963_.

I considered modifying the `Element` and `TraversableElement`'s `find*()` methods to receive the `$exact` parameter, but a lot of this code assumes that there is one valid selector for any "find" and that the locator for any two selector engines are not compatible. So this would have been hacky and possibly introduce wide spread undesired effects.

However, when I looked for ways to implement this in such a way that Mink would look first for an exact match, and then for a partial match if no exact match is found (which is not really possible in pure xpath), it became apparent if that the assumption is to be maintained, then such a feature would be very hacky, at best.

This introduces the problem of backwards compatibility, since refactoring or removing `SelectorsHandler` would break code that consumes `registerSelector()` and other API methods of `SelectorsHandler`.

A further problem is that such a feature would break backwards compatibility of scenarios which assume partial matching if the mink extension `MinkContext` methods start preferring exact matches over partial matches. If we refactor or remove `SelectorsHandler` we can manage this by requiring custom `FeatureContext` classes call `$this->getSession()->getSelectorsHandler()->setMatching('exact,partial');` or something from a `@BeforeScenario` method.

So to move forward:
* How important is it to maintain support and backwards compatibility of `SelectorsHandler` and it's API methods?
* How important is it to maintain backwards compatibility for scenarios that partially match by name but might break if exact-matches were preferred?
* How can I run the test suite against this repository to check I have not introduced errors?
* What approach is most likely to be accepted into the upstream repository?