public function _findClickable($page, $link)
    {
        if (is_array($link) or ($link instanceof WebDriverBy)) {
            return $this->matchFirstOrFail($page, $link);
        }

        // try to match by strict locators, CSS Ids or XPath
        if (Locator::isPrecise($link)) {
            return $this->matchFirstOrFail($page, $link);
        }

        $locator = Crawler::xpathLiteral(trim($link));

        // narrow
        $xpath = Locator::combine(
            ".//a[normalize-space(.)=$locator]",
            ".//button[normalize-space(.)=$locator]",
            ".//a/img[normalize-space(@alt)=$locator]/ancestor::a",
            ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][normalize-space(@value)=$locator]"
        );

        $els = $page->findElements(WebDriverBy::xpath($xpath));
        if (count($els)) {
            return reset($els);
        }

        // wide
        $xpath = Locator::combine(
            ".//a[./@href][((contains(normalize-space(string(.)), $locator)) or contains(./@title, $locator) or .//img[contains(./@alt, $locator)])]",
            ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][contains(./@value, $locator)]",
            ".//input[./@type = 'image'][contains(./@alt, $locator)]",
            ".//button[contains(normalize-space(string(.)), $locator)]",
            ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][./@name = $locator or ./@title = $locator]",
            ".//button[./@name = $locator or ./@title = $locator]"
        );

        $els = $page->findElements(WebDriverBy::xpath($xpath));
        if (count($els)) {
            return reset($els);
        }

        return null;
    }
public function _findClickable($page, $link)
    {
        if (is_array($link) or ($link instanceof WebDriverBy)) {
            return $this->matchFirstOrFail($page, $link);
        }

        // try to match by strict locators, CSS Ids or XPath
        if (Locator::isPrecise($link)) {
            return $this->matchFirstOrFail($page, $link);
        }

        $locator = Crawler::xpathLiteral(trim($link));

        // narrow
        $xpath = Locator::combine(
            ".//a[normalize-space(.)=$locator]",
            ".//button[normalize-space(.)=$locator]",
            ".//a/img[normalize-space(@alt)=$locator]/ancestor::a",
            ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][normalize-space(@value)=$locator]"
        );

        $els = $page->findElements(WebDriverBy::xpath($xpath));
        if (count($els)) {
            return reset($els);
        }

        // wide
        $xpath = Locator::combine(
            ".//a[./@href][((contains(normalize-space(string(.)), $locator)) or contains(./@title, $locator) or .//img[contains(./@alt, $locator)])]",
            ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][contains(./@value, $locator)]",
            ".//input[./@type = 'image'][contains(./@alt, $locator)]",
            ".//button[contains(normalize-space(string(.)), $locator)]",
            ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][./@name = $locator or ./@title = $locator]",
            ".//button[./@name = $locator or ./@title = $locator]"
        );

        $els = $page->findElements(WebDriverBy::xpath($xpath));
        if (count($els)) {
            return reset($els);
        }

        return null;
    }
public function _findClickable ( $ page , $ link ) { if ( is_array ( $ link ) or ( $ link instanceof WebDriverBy ) ) { return $ this -> matchFirstOrFail ( $ page , $ link ) ; } // try to match by strict locators, CSS Ids or XPath if ( Locator :: isPrecise ( $ link ) ) { return $ this -> matchFirstOrFail ( $ page , $ link ) ; } $ locator = Crawler :: xpathLiteral ( trim ( $ link ) ) ; // narrow $ xpath = Locator :: combine ( ".//a[normalize-space(.)=$locator]" , ".//button[normalize-space(.)=$locator]" , ".//a/img[normalize-space(@alt)=$locator]/ancestor::a" , ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][normalize-space(@value)=$locator]" ) ; $ els = $ page -> findElements ( WebDriverBy :: xpath ( $ xpath ) ) ; if ( count ( $ els ) ) { return reset ( $ els ) ; } // wide $ xpath = Locator :: combine ( ".//a[./@href][((contains(normalize-space(string(.)), $locator)) or contains(./@title, $locator) or .//img[contains(./@alt, $locator)])]" , ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][contains(./@value, $locator)]" , ".//input[./@type = 'image'][contains(./@alt, $locator)]" , ".//button[contains(normalize-space(string(.)), $locator)]" , ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][./@name = $locator or ./@title = $locator]" , ".//button[./@name = $locator or ./@title = $locator]" ) ; $ els = $ page -> findElements ( WebDriverBy :: xpath ( $ xpath ) ) ; if ( count ( $ els ) ) { return reset ( $ els ) ; } return null ; }
Locates a clickable element.

Use it in Helpers or GroupObject or Extension classes:

```php
<?php
$module = $this->getModule('WebDriver');
$page = $module->webDriver;

// search a link or button on a page
$el = $module->_findClickable($page, 'Click Me');

// search a link or button within an element
$topBar = $module->_findElements('.top-bar')[0];
$el = $module->_findClickable($topBar, 'Click Me');

```
@api
@param RemoteWebDriver $page WebDriver instance or an element to search within
@param $link a link text or locator to click
@return WebDriverElement
Locates a clickable element .