module-webdriver icon indicating copy to clipboard operation
module-webdriver copied to clipboard

Make WebDriver::getLocator (and WebDriver::getStrictLocator) public

Open Byte-Lab opened this issue 8 years ago • 0 comments

What are you trying to achieve?

Write a custom action that uses the WebDriver locator service to locate an element by its selector string. I would like to do this by getting the web driver module with $this->getModule('WebDriver') rather than extending WebDriver to keep my testing architecture consistent with other modules I've written.

What do you get instead?

Unable to use the functions because they're protected.

    /**
     * @param $selector
     * @return WebDriverBy
     * @throws \InvalidArgumentException
     */
    protected function getLocator($selector)
    {
        if ($selector instanceof WebDriverBy) {
            return $selector;
        }
        if (is_array($selector)) {
            return $this->getStrictLocator($selector);
        }
        if (Locator::isID($selector)) {
            return WebDriverBy::id(substr($selector, 1));
        }
        if (Locator::isCSS($selector)) {
            return WebDriverBy::cssSelector($selector);
        }
        if (Locator::isXPath($selector)) {
            return WebDriverBy::xpath($selector);
        }
        throw new \InvalidArgumentException("Only CSS or XPath allowed");
    }

   // ...and

    /**
     * @param array $by
     * @return WebDriverBy
     */
    protected function getStrictLocator(array $by)
    {
        $type = key($by);
        $locator = $by[$type];
        switch ($type) {
            case 'id':
                return WebDriverBy::id($locator);
            case 'name':
                return WebDriverBy::name($locator);
            case 'css':
                return WebDriverBy::cssSelector($locator);
            case 'xpath':
                return WebDriverBy::xpath($locator);
            case 'link':
                return WebDriverBy::linkText($locator);
            case 'class':
                return WebDriverBy::className($locator);
            default:
                throw new MalformedLocatorException(
                    "$by => $locator",
                    "Strict locator can be either xpath, css, id, link, class, name: "
                );
        }
    }

Details

It seems to me that these are services that the WebDriver module should expose, as some public WebDriver functions take WebDriverBy arguments (e.g. WebDriver::findElements). We need some service to get these WebDriverBy arguments, or we won't be able to use the public function calls that are exposed through $this->getModule('WebDriver');. Alternatively, maybe the WebDriver module should expose some public findElement type of function that takes a selector string rather than a WebDriverBy instance.

  • Codeception version: 2.2.10
  • PHP Version: 7.0.10

Apologies if this has already been discussed, I didn't see it on the issues board. And thanks for making such a fantastic tool!

Byte-Lab avatar May 11 '17 16:05 Byte-Lab