<commit_before>from copy import copy, Error

import re
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
from selenium.webdriver.common.by import By

from ...exception import Error
from ...xpath_support import XpathSupport


class Locator(object):
    WD_FINDERS = [
        'class',
        'class_name',
        'css',
        'id',
        'link',
        'link_text',
        'name',
        'partial_link_text',
        'tag_name',
        'xpath'
    ]

    # Regular expressions that can be reliably converted to xpath `contains`
    # expressions in order to optimize the .
    CONVERTABLE_REGEXP = re.compile(r'\A'
                                    r'([^\[\]\\^$.|?*+()]*)'  # leading literal characters
                                    r'[^|]*?'  # do not try to convert expressions with alternates
                                    r'([^\[\]\\^$.|?*+()]*)'  # trailing literal characters
                                    r'\Z',
                                    re.X)

    def __init__(self, query_scope, selector, selector_builder, element_validator):
        self.query_scope = query_scope  # either element or browser
        self.selector = copy(selector)
        self.selector_builder = selector_builder
        self.element_validator = element_validator

    def locate(self):
        try:
            e = self._by_id()  # short-circuit if :id is given
            if e:
                return e

            if len(self.selector) == 1:
                element = self._find_first_by_one()
            else:
                element = self._find_first_by_multiple()

            # This actually only applies when finding by xpath/css -
            # browser.text_field(xpath="//input[@type='radio']")
            # We don't need to validate the element if we built the xpath ourselves.
            # It is also used to alter behavior of methods locating more than one type of element
            # (e.g. text_field locates both input and textarea)
            if element:
                return self.element_validator.validate(element, self.selector)
        except (NoSuchElementException, StaleElementReferenceException):
            return None

    def locate_all(self):
        if len(self.selector) == 1:
            return self._find_all_by_one()
        else:
            return self._find_all_by_multiple()

    # private

    def _by_id(self):
        selector = copy(self.selector)
        attr_id = selector.pop('id', None)
        if not isinstance(attr_id, str):
            return None

        tag_name = selector.pop('tag_name', None)
        if selector:  # Multiple attributes
            return None

        element = self.query_scope.wd.find_element_by_id(attr_id)
        if tag_name and not self.element_validator.validate(element, {'tag_name': tag_name}):
            return None

        return element

    def _find_first_by_one(self):
        how, what = self.selector.items()[0]
        self.selector_builder.check_type(how, what)

        if how in self.WD_FINDERS:
            return self._wd_find_first_by(how, what)
        else:
            return self._find_first_by_multiple()

    def _find_first_by_multiple(self):
        selector = self.selector_builder.normalized_selector

        idx = selector.pop('index', None)
        visible = selector.pop('visible', None)

        built_selector = self.selector_builder.build(selector)

        if built_selector:
            # could build xpath/css for selector
            if idx or visible:
                idx = idx or 0
                elements = self.query_scope.wd.find_elements(*built_selector)
                if visible:
                    elements = [el for el in elements if visible == el.is_displayed()]
                return elements[idx] if elements else None
            else:
                return self.query_scope.wd.find_element(*built_selector)
        else:
            # can't use xpath, probably a regexp in there
            if idx or visible:
                idx = idx or 0
                elements = self._wd_find_by_regexp_selector(selector, 'select')
                if visible:
                    elements = [el for el in elements if visible == el.is_displayed()]
                return elements[idx] if elements else None
            else:
                return self._wd_find_by_regexp_selector(selector, 'find')

    def _find_all_by_one(self):
        how, what = self.selector.items().first
        self.selector_builder.check_type(how, what)

        if how in self.WD_FINDERS:
            return self._wd_find_all_by(how, what)
        else:
            return self._find_all_by_multiple()

    def _find_all_by_multiple(self):
        selector = self.selector_builder.normalized_selector
        visible = selector.pop('visible')

        if 'index' in selector:
            raise ValueError("can't locate all elements by index")

        how, what = self.selector_builder.build(selector)
        if how:
            found = self.query_scope.wd.find_elements(how, what)
        else:
            found = self._wd_find_by_regexp_selector(selector, 'select')
        if visible:
            return [el for el in found if visible == el.is_displayed()]
        else:
            return found

    def _wd_find_all_by(self, how, what):
        if isinstance(what, str):
            return self.query_scope.wd.find_elements(how, what)
        else:
            return [el for el in self._all_elements if what.search(self._fetch_value(el, how))]
<commit_msg>translate locators to selenium WD<commit_after>from copy import copy, Error

import re
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
from selenium.webdriver.common.by import By

from ...exception import Error
from ...xpath_support import XpathSupport


class Locator(object):
    WD_FINDERS = {
        'class': By.CLASS_NAME,
        'class_name': By.CLASS_NAME,
        'css': By.CSS_SELECTOR,
        'id': By.ID,
        'link': By.LINK_TEXT,
        'link_text': By.LINK_TEXT,
        'name': By.NAME,
        'partial_link_text': By.PARTIAL_LINK_TEXT,
        'tag_name': By.TAG_NAME,
        'xpath': By.XPATH
    }

    # Regular expressions that can be reliably converted to xpath `contains`
    # expressions in order to optimize the .
    CONVERTABLE_REGEXP = re.compile(r'\A'
                                    r'([^\[\]\\^$.|?*+()]*)'  # leading literal characters
                                    r'[^|]*?'  # do not try to convert expressions with alternates
                                    r'([^\[\]\\^$.|?*+()]*)'  # trailing literal characters
                                    r'\Z',
                                    re.X)

    def __init__(self, query_scope, selector, selector_builder, element_validator):
        self.query_scope = query_scope  # either element or browser
        self.selector = copy(selector)
        self.selector_builder = selector_builder
        self.element_validator = element_validator

    def locate(self):
        try:
            e = self._by_id()  # short-circuit if :id is given
            if e:
                return e

            if len(self.selector) == 1:
                element = self._find_first_by_one()
            else:
                element = self._find_first_by_multiple()

            # This actually only applies when finding by xpath/css -
            # browser.text_field(xpath="//input[@type='radio']")
            # We don't need to validate the element if we built the xpath ourselves.
            # It is also used to alter behavior of methods locating more than one type of element
            # (e.g. text_field locates both input and textarea)
            if element:
                return self.element_validator.validate(element, self.selector)
        except (NoSuchElementException, StaleElementReferenceException):
            return None

    def locate_all(self):
        if len(self.selector) == 1:
            return self._find_all_by_one()
        else:
            return self._find_all_by_multiple()

    # private

    def _by_id(self):
        selector = copy(self.selector)
        attr_id = selector.pop('id', None)
        if not isinstance(attr_id, str):
            return None

        tag_name = selector.pop('tag_name', None)
        if selector:  # Multiple attributes
            return None

        element = self.query_scope.wd.find_element_by_id(attr_id)
        if tag_name and not self.element_validator.validate(element, {'tag_name': tag_name}):
            return None

        return element

    def _find_first_by_one(self):
        how, what = self.selector.items()[0]
        self.selector_builder.check_type(how, what)

        if how in self.WD_FINDERS:
            return self._wd_find_first_by(self.WD_FINDERS.get(how), what)
        else:
            return self._find_first_by_multiple()

    def _find_first_by_multiple(self):
        selector = self.selector_builder.normalized_selector

        idx = selector.pop('index', None)
        visible = selector.pop('visible', None)

        built_selector = self.selector_builder.build(selector)

        if built_selector:
            # could build xpath/css for selector
            if idx or visible:
                idx = idx or 0
                elements = self.query_scope.wd.find_elements(*built_selector)
                if visible:
                    elements = [el for el in elements if visible == el.is_displayed()]
                return elements[idx] if elements else None
            else:
                return self.query_scope.wd.find_element(*built_selector)
        else:
            # can't use xpath, probably a regexp in there
            if idx or visible:
                idx = idx or 0
                elements = self._wd_find_by_regexp_selector(selector, 'select')
                if visible:
                    elements = [el for el in elements if visible == el.is_displayed()]
                return elements[idx] if elements else None
            else:
                return self._wd_find_by_regexp_selector(selector, 'find')

    def _find_all_by_one(self):
        how, what = self.selector.items().first
        self.selector_builder.check_type(how, what)

        if how in self.WD_FINDERS:
            return self._wd_find_all_by(self.WD_FINDERS.get(how), what)
        else:
            return self._find_all_by_multiple()

    def _find_all_by_multiple(self):
        selector = self.selector_builder.normalized_selector
        visible = selector.pop('visible')

        if 'index' in selector:
            raise ValueError("can't locate all elements by index")

        how, what = self.selector_builder.build(selector)
        if how:
            found = self.query_scope.wd.find_elements(how, what)
        else:
            found = self._wd_find_by_regexp_selector(selector, 'select')
        if visible:
            return [el for el in found if visible == el.is_displayed()]
        else:
            return found

    def _wd_find_all_by(self, how, what):
        if isinstance(what, str):
            return self.query_scope.wd.find_elements(how, what)
        else:
            return [el for el in self._all_elements if what.search(self._fetch_value(el, how))]

{'fraction_non_alphanumeric': 0.08802692171448813, 'fraction_numerical': 0.000885582713425434, 'mean_word_length': 1.9570568211573711, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6121757', 'n_tokens_mistral': 3154, 'n_tokens_neox': 3037, 'n_words': 818}