from bfs.bfs10110.bfs10112 import LicensingError
from copy import copy
from decorator import decorator
from errno import ESRCH as bfs10410, EACCES as bfs10412
from helium.bfs10121.bfs10122 import bfs10123
from helium.bfs10121.bfs10134 import bfs10144
from helium.bfs10110.bfs10112 import bfs10145
from helium.bfs10110.bfs10153 import bfs10204, bfs10205
from helium.bfs10344 import bfs10371, bfs10350, bfs10373, bfs10400
from helium.bfs10063.bfs10404 import bfs10406
from helium.bfs10063.bfs10407 import bfs10411
from helium.bfs10063.system import bfs10127, bfs10130, bfs10126, bfs10135, bfs10132
from helium.bfs10063.bfs10113 import lower, predicate, bfs10117
from inspect import getargspec, ismethod, isfunction
from logging import getLogger
from os import access, X_OK
from os.path import exists
from selenium.common.exceptions import UnexpectedAlertPresentException, ElementNotVisibleException, MoveTargetOutOfBoundsException, WebDriverException, StaleElementReferenceException, NoAlertPresentException, NoSuchWindowException
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver import Firefox, Chrome, Ie, DesiredCapabilities, ChromeOptions
from time import sleep, time
import atexit
import re
import collections
@decorator
def bfs10417(bfs10362, self, *args, **bfs10413):
  if (self.driver.bfs10361() and AlertImpl(self.driver).exists()):
    return bfs10362(self, *args, **bfs10413)

  bfs10415 = self.driver.window_handles[:]
  bfs10414 = bfs10362(self, *args, **bfs10413)
  if (not (self.driver.bfs10361() and AlertImpl(self.driver).exists())):
    bfs10416 = [bfs10420 for bfs10420 in self.driver.window_handles if (bfs10420 not in bfs10415) ]
    if bfs10416:
      self.driver.switch_to.window(bfs10416[0])


  return bfs10414

@decorator
def bfs10423(bfs10362, *args, **bfs10421):
  try:
    return bfs10362(*args, **bfs10421)
  except UnexpectedAlertPresentException:
    raise UnexpectedAlertPresentException("This command is not supported when an alert is present. To accept the alert (this usually corresponds to clicking 'OK') use `Alert().accept()`. To dismiss the alert (ie. 'cancel' it), use `Alert().dismiss()`. If the alert contains a text field, you can use write(...) to set its value. Eg.: `write('hi there!')`.")


class APIImpl(object):
  def __init__(self, bfs10422, bfs10424, bfs10425=None):
    self.bfs10422 = bfs10422
    self.license = bfs10424
    self.bfs10425 = bfs10425
    self.driver = None

  def bfs10426(self, url=None):
    capabilities = DesiredCapabilities.FIREFOX.copy()
    capabilities['unexpectedAlertBehaviour'] = 'ignore'
    firefox = Firefox(capabilities=capabilities)
    return self.bfs10427(firefox, url)

  def bfs10436(self, url=None):
    bfs10430 = self.bfs10432()
    bfs10431 = ChromeOptions()
    bfs10431.add_argument('--test-type')
    bfs10433 = {'chrome_options': bfs10431}
    if exists(bfs10430):
      if (not access(bfs10430, X_OK)):
        try:
          bfs10411(bfs10430)
        except:
          raise RuntimeError(('The Chrome driver located at %s is not executable.' % bfs10430))


      getLogger(__name__).info('Using Chrome driver located at %s.', bfs10430)
      bfs10433['executable_path'] = bfs10430
    else:
      getLogger(__name__).warn('Could not find Chrome driver at expected location %s.', bfs10430)

    bfs10144()
    bfs10435 = Chrome(**bfs10433)
    atexit.register((lambda : self.bfs10434(bfs10435.service)))
    return self.bfs10427(bfs10435, url)

  def bfs10432(self):
    if bfs10127():
      bfs10440 = 'chromedriver.exe'
    elif bfs10130():
      bfs10440 = ('chromedriver' + ('_x64' if bfs10135() else ''))
    else:
      assert bfs10126()
      bfs10440 = 'chromedriver'

    return self.bfs10422.bfs10437(bfs10132(), 'webdrivers', bfs10440)

  def bfs10434(self, service):
    if hasattr(service, 'process'):
      try:
        service.process.kill()
      except OSError as e:
        if (e.errno not in (bfs10410, bfs10412)):
          raise 




  def bfs10443(self, url=None):
    bfs10441 = self.bfs10422.bfs10437('win', 'webdrivers', 'IEDriverServer.exe')
    capabilities = DesiredCapabilities.INTERNETEXPLORER.copy()
    capabilities['ignoreZoomSetting'] = True
    bfs10433 = {'capabilities': capabilities}
    if exists(bfs10441):
      getLogger(__name__).info('Using IE driver located at %s.', bfs10441)
      bfs10433['executable_path'] = bfs10441
    else:
      getLogger(__name__).warn('Could not find IE driver at expected location %s.', bfs10441)

    bfs10442 = Ie(**bfs10433)
    atexit.register((lambda : self.bfs10434(bfs10442.iedriver)))
    return self.bfs10427(bfs10442, url)

  def bfs10427(self, bfs10444, url=None):
    try:
      self.bfs10445(bfs10444)
    except LicensingError:
      bfs10444.quit()
      raise 

    if (url is not None):
      self.bfs10447(url)

    return self.bfs10446()

  @bfs10417
  @bfs10423
  def bfs10447(self, url):
    if ('://' not in url):
      url = ('http://' + url)

    self.driver.get(url)

  def bfs10445(self, driver):
    self.bfs10450(driver)
    self.driver = bfs10350(driver)

  def bfs10450(self, driver):
    try:
      self.license.bfs10452(bfs10204(self.bfs10425))
    except bfs10145:
      try:
        self.license.bfs10452(bfs10205(self.bfs10425, driver))
      except bfs10145:
        raise LicensingError('Unfortunately, Helium could not verify your license key. Please activate your internet connection and try again.')



  def bfs10446(self):
    if (self.driver is not None):
      return self.driver.unwrap()


  @bfs10417
  @bfs10423
  def bfs10455(self, text, into=None):
    if (into is not None):
      from helium.api import GUIElement
      if isinstance(into, GUIElement):
        into = into.bfs10451


    self.bfs10453(self.bfs10454, self.bfs10456, text, into=into)

  def bfs10454(self, text, into=None):
    if into:
      if isinstance(into, str):
        into = TextFieldImpl(self.driver, into)

      def bfs10461(bfs10457):
        if (hasattr(bfs10457, 'clear') and isinstance(bfs10457.clear, collections.Callable)):
          bfs10457.clear()

        bfs10457.send_keys(text)

      self.bfs10460(into, bfs10461)
    else:
      self.driver.switch_to.active_element.send_keys(text)


  def bfs10456(self, text, into=None):
    if (into is None):
      into = AlertImpl(self.driver)

    if (not isinstance(into, AlertImpl)):
      raise UnexpectedAlertPresentException(('into=%r is not allowed when an alert is present.' % into))

    into.bfs10461(text)

  def bfs10453(self, bfs10462, bfs10464, *args, **bfs10463):
    if (self.driver.bfs10360() or (not AlertImpl(self.driver).exists())):
      try:
        return bfs10462(*args, **bfs10463)
      except UnexpectedAlertPresentException:
        if (self.driver.bfs10360() and (not AlertImpl(self.driver).exists())):
          raise RuntimeError("An alert dialog was open but was closed by an expected exception. This normally happens when you called set_driver(...) with a Firefox driver you instantiated yourself without first setting selenium.webdriver.common.desired_capabilities.DesiredCapabilities.FIREFOX['unexpectedAlertBehaviour'] to 'ignore'. If this is not the case, please file a bug report at http://heliumhq.com.")



    return bfs10464(*args, **bfs10463)

  @bfs10417
  @bfs10423
  def bfs10465(self, key):
    self.driver.switch_to.active_element.send_keys(key)

  def bfs10470(self, element):
    element = self.bfs10466(element)
    click = (lambda bfs10467: bfs10467.click())
    self.bfs10471(element, click, click)

  def bfs10466(self, bfs10457):
    from helium.api import HTMLElement
    if isinstance(bfs10457, str):
      bfs10457 = bfs10472(self.driver, bfs10457)
    elif isinstance(bfs10457, HTMLElement):
      bfs10457 = bfs10457.bfs10451

    return bfs10457

  @bfs10417
  @bfs10423
  def bfs10471(self, element, bfs10473, bfs10474):
    offset = None
    from helium.api import Point
    if isinstance(element, Point):
      (element, offset) = self.bfs10476(element)

    if (offset is not None):
      bfs10354 = (lambda bfs10475: bfs10474(self.driver.bfs10354().move_to_element_with_offset(bfs10475, *offset)).perform())
    else:
      bfs10354 = (lambda bfs10477: bfs10473(bfs10477))

    self.bfs10460(element, bfs10354)

  def bfs10476(self, bfs10500):
    element = bfs10371(self.driver.execute_script(('return document.elementFromPoint(%r, %r);' % (bfs10500.x, bfs10500.y))))
    offset = (bfs10500 - (element.location.bfs10212, element.location.bfs10211))
    if ((offset == (0, 0)) and self.driver.bfs10360()):
      offset = (1, 1)

    return (element, offset)

  def bfs10502(self, element):
    element = self.bfs10466(element)
    self.bfs10471(element, (lambda bfs10501: self.driver.bfs10354().double_click(bfs10501).perform()), (lambda bfs10503: bfs10503.double_click()))

  def bfs10505(self, element, to):
    self.bfs10504(element)
    self.bfs10506(to)

  def bfs10504(self, element):
    element = self.bfs10466(element)
    self.bfs10471(element, (lambda bfs10507: self.driver.bfs10354().click_and_hold(bfs10507).perform()), (lambda bfs10511: bfs10511.click_and_hold()))

  def bfs10506(self, element):
    element = self.bfs10466(element)
    self.bfs10471(element, (lambda bfs10510: self.driver.bfs10354().move_to_element(bfs10510).release().perform()), (lambda bfs10512: bfs10512.release()))

  @bfs10423
  def bfs10514(self, predicate):
    return [predicate.bfs10513(bfs10515) for bfs10515 in predicate.bfs10451.find_all()]

  def bfs10517(self, num_pixels):
    self.bfs10516(0, num_pixels)

  def bfs10520(self, num_pixels):
    self.bfs10516(0, (-num_pixels))

  def bfs10521(self, num_pixels):
    self.bfs10516(num_pixels, 0)

  def bfs10523(self, num_pixels):
    self.bfs10516((-num_pixels), 0)

  @bfs10423
  def bfs10516(self, bfs10522, bfs10524):
    self.driver.execute_script('window.scrollBy(arguments[0], arguments[1]);', bfs10522, bfs10524)

  def bfs10526(self, element):
    element = self.bfs10466(element)
    self.bfs10471(element, (lambda bfs10525: self.driver.bfs10354().move_to_element(bfs10525).perform()), (lambda bfs10527: bfs10527))

  def bfs10532(self, element):
    element = self.bfs10466(element)
    self.bfs10471(element, (lambda bfs10530: self.driver.bfs10354().context_click(bfs10530).perform()), (lambda bfs10531: bfs10531.context_click()))

  @bfs10417
  @bfs10423
  def bfs10533(self, combo_box, value):
    from helium.api import ComboBox
    if isinstance(combo_box, str):
      combo_box = ComboBoxImpl(self.driver, combo_box)
    elif isinstance(combo_box, ComboBox):
      combo_box = combo_box.bfs10451

    def bfs10534(web_element):
      Select(web_element).select_by_visible_text(value)

    self.bfs10460(combo_box, bfs10534)

  def bfs10460(self, bfs10535, bfs10354):
    if (hasattr(bfs10535, 'perform') and isinstance(bfs10535.perform, collections.Callable)):
      self.driver.bfs10352 = bfs10535.perform(bfs10354)
    else:
      if isinstance(bfs10535, WebElement):
        bfs10535 = bfs10371(bfs10535)

      bfs10354(bfs10535)
      self.driver.bfs10352 = bfs10535


  @bfs10423
  def bfs10543(self, file_path, to):
    to = self.bfs10466(to)
    drag_and_drop = bfs10536(self.driver, file_path)
    drag_and_drop.begin()
    try:
      drag_and_drop.bfs10540()
      self.bfs10460(to, (lambda bfs10537: drag_and_drop.bfs10541(bfs10537)))
    finally:
      drag_and_drop.end()


  def bfs10545(self, file_path, to=None):
    if (to is None):
      to = bfs10542(self.driver)
    elif isinstance(to, str):
      to = bfs10542(self.driver, to)

    bfs10544 = (lambda bfs10546: bfs10546.send_keys(file_path))
    self.bfs10471(to, bfs10544, bfs10544)

  def bfs10551(self):
    self.bfs10453(self.bfs10547, self.bfs10550)

  def bfs10547(self):
    self.driver.refresh()

  def bfs10550(self):
    AlertImpl(self.driver).accept()
    self.bfs10547()

  def bfs10556(self, condition_fn, timeout_secs=10, interval_secs=0.5):
    if ismethod(condition_fn):
      bfs10552 = (condition_fn.__self__ is not None)
      bfs10553 = getargspec(condition_fn).args
      bfs10555 = (len(bfs10553) - (1 if bfs10552 else 0))
    else:
      if (not isfunction(condition_fn)):
        condition_fn = condition_fn.__call__

      bfs10553 = getargspec(condition_fn).args
      bfs10555 = len(bfs10553)

    bfs10554 = (condition_fn if bfs10555 else (lambda driver: condition_fn()))
    wait = WebDriverWait(self.bfs10446(), timeout_secs, poll_frequency=interval_secs)
    wait.until(bfs10554)

  @bfs10423
  def bfs10560(self, window):
    from helium.api import Window
    if isinstance(window, str):
      window = WindowImpl(self.driver, window)
    elif isinstance(window, Window):
      window = window.bfs10451

    self.driver.switch_to.window(window.handle)

  def bfs10557(self):
    self.driver.quit()

  @bfs10423
  def bfs10562(self, element):
    from helium.api import HTMLElement, Text
    if isinstance(element, str):
      element = Text(element)

    if isinstance(element, HTMLElement):
      element = element.bfs10451

    if hasattr(element, 'first_occurrence'):
      element = element.first_occurrence

    if isinstance(element, bfs10371):
      element = element.unwrap()

    bfs10561 = element.get_attribute('style')
    self.driver.execute_script("arguments[0].setAttribute('style', 'border: 2px solid red; font-weight: bold;');", element)
    self.driver.execute_script("var target = arguments[0];var previousStyle = arguments[1];setTimeout(function() {target.setAttribute('style', previousStyle);}, 2000);", element, bfs10561)


class bfs10536(object):
  def __init__(self, driver, file_path):
    self.driver = driver
    self.file_path = file_path
    self.bfs10563 = None
    self.bfs10565 = None

  def begin(self):
    self.bfs10564()
    try:
      self.bfs10563.send_keys(self.file_path)
    except:
      self.end()
      raise 


  def bfs10564(self):
    self.bfs10563 = self.driver.execute_script("var input = document.createElement('input');input.type = 'file';input.style.display = 'block';input.style.opacity = '1';input.style.visibility = 'visible';input.style.height = '1px';input.style.width = '1px';if (document.body.childElementCount > 0) {   document.body.insertBefore(input, document.body.childNodes[0]);} else {   document.body.appendChild(input);}return input;")

  def bfs10540(self):
    self.bfs10566('dragenter', to='document.body')
    self.bfs10565 = self.bfs10567('dragover', 'document', interval_msecs=300)
    self.bfs10565.start()

  def bfs10566(self, bfs10571, to):
    (bfs10570, args) = self.bfs10572(bfs10571, to)
    self.driver.execute_script(bfs10570, *args)

  def bfs10567(self, bfs10573, to, interval_msecs):
    (bfs10574, args) = self.bfs10572(bfs10573, to)
    return bfs10576(self.driver, bfs10574, args, interval_msecs)

  def bfs10572(self, bfs10575, to):
    bfs10577 = "var files = arguments[0].files;var items = [];var types = [];for (var i = 0; i < files.length; i++) {   items[i] = {kind: 'file', type: files[i].type};   types[i] = 'Files';}var event = document.createEvent('CustomEvent');event.initCustomEvent(arguments[1], true, true, 0);event.dataTransfer = {\tfiles: files,\titems: items,\ttypes: types};arguments[2].dispatchEvent(event);"
    if isinstance(to, str):
      bfs10577 = bfs10577.replace('arguments[2]', to)
      args = (self.bfs10563, bfs10575)
    else:
      args = (self.bfs10563, bfs10575, to.unwrap())

    return (bfs10577, args)

  def bfs10541(self, target):
    self.bfs10565.stop()
    self.bfs10566('drop', to=target)

  def end(self):
    if (self.bfs10563 is not None):
      self.driver.execute_script('arguments[0].parentNode.removeChild(arguments[0]);', self.bfs10563)

    self.bfs10563 = None


class bfs10576(object):
  def __init__(self, driver, bfs10600, args, interval_msecs):
    self.driver = driver
    self.bfs10600 = bfs10600
    self.args = args
    self.interval_msecs = interval_msecs
    self.bfs10601 = None

  def start(self):
    bfs10602 = ('var originalArguments = arguments;return setInterval(function() {\targuments = originalArguments;\t%s}, %d);' % (self.bfs10600, self.interval_msecs))
    self.bfs10601 = self.driver.execute_script(bfs10602, *self.args)

  def stop(self):
    self.driver.execute_script('clearInterval(arguments[0]);', self.bfs10601)
    self.bfs10601 = None


class bfs10603(object):
  def __init__(self, driver):
    self.bfs10605 = None
    self.bfs10604 = driver

  def find_all(self):
    if self.bfs10606():
      yield self
    else:
      for bfs10610 in self.bfs10607():
        yield self.bfs10611(bfs10610)



  def bfs10606(self):
    return (self.bfs10605 is not None)

  def bfs10607(self):
    raise NotImplementedError()

  def bfs10611(self, bfs10612):
    bfs10613 = copy(self)
    bfs10613.bfs10605 = bfs10612
    return bfs10613

  def exists(self):
    try:
      next(self.find_all())
    except StopIteration:
      return False
    else:
      return True


  @property
  def first_occurrence(self):
    if (not self.bfs10606()):
      self.bfs10615()

    return self.bfs10605

  def bfs10615(self):
    self.perform((lambda bfs10614: None))

  def perform(self, bfs10354):
    from helium.api import Config
    bfs10616 = (time() + Config.implicit_wait_secs)
    bfs10617 = self.bfs10621(bfs10354)
    while ((bfs10617 is None) and (time() < bfs10616)):
      bfs10617 = self.bfs10621(bfs10354)

    if (bfs10617 is not None):
      return bfs10617

    raise LookupError()

  def bfs10621(self, bfs10354):
    for bfs10620 in self.find_all():
      bfs10622 = bfs10620.first_occurrence
      try:
        bfs10354(bfs10622)
      except Exception as e:
        if self.bfs10624(e):
          continue
        else:
          raise 

      else:
        self.bfs10605 = bfs10622
        return bfs10622



  def bfs10624(self, exception):
    if isinstance(exception, ElementNotVisibleException):
      return True

    if isinstance(exception, MoveTargetOutOfBoundsException):
      return True

    if isinstance(exception, WebDriverException):
      msg = exception.msg
      if (('Element is not clickable at point' in msg) and ('Other element would receive the click' in msg)):
        getLogger(__name__).info('Ignoring exception %r while trying to click element. It could be that the element has moved.', msg, exc_info=True)
        return True


    return False


class bfs10623(bfs10603):
  def __init__(self, driver, below=None, to_right_of=None, above=None, to_left_of=None):
    super(bfs10623, self).__init__(driver)
    self.below = self.bfs10625(below)
    self.to_right_of = self.bfs10625(to_right_of)
    self.above = self.bfs10625(above)
    self.to_left_of = self.bfs10625(to_left_of)
    self.bfs10626 = bfs10123()

  def bfs10625(self, element):
    if isinstance(element, str):
      return TextImpl(self.bfs10604, element)

    from helium.api import HTMLElement
    if isinstance(element, HTMLElement):
      return element.bfs10451

    return element

  @property
  def width(self):
    return self.first_occurrence.location.width

  @property
  def height(self):
    return self.first_occurrence.location.height

  @property
  def x(self):
    return self.first_occurrence.location.bfs10212

  @property
  def y(self):
    return self.first_occurrence.location.bfs10211

  @property
  def top_left(self):
    from helium.api import Point
    return Point(self.x, self.y)

  @property
  def web_element(self):
    return self.first_occurrence.unwrap()

  def bfs10607(self):
    self.bfs10627()
    bfs10631 = self.bfs10630()
    try:
      for bfs10632 in bfs10373(self.bfs10604):
        for bfs10633 in self.bfs10635():
          if self.bfs10634(bfs10633, bfs10631):
            yield bfs10633



    except bfs10400:
      pass


  def bfs10627(self):
    window_handles = self.bfs10604.window_handles
    try:
      bfs10636 = self.bfs10604.current_window_handle
    except NoSuchWindowException:
      bfs10637 = True
    else:
      bfs10637 = (bfs10636 not in window_handles)

    if bfs10637:
      self.bfs10604.switch_to_window(window_handles[0])


  def bfs10630(self):
    bfs10617 = []
    if self.below:
      bfs10617.append(list(map((lambda bfs10641: bfs10641.location.is_above), self.below.bfs10607())))

    if self.to_right_of:
      bfs10617.append(list(map((lambda bfs10640: bfs10640.location.is_to_left_of), self.to_right_of.bfs10607())))

    if self.above:
      bfs10617.append(list(map((lambda bfs10642: bfs10642.location.is_below), self.above.bfs10607())))

    if self.to_left_of:
      bfs10617.append(list(map((lambda bfs10643: bfs10643.location.is_to_right_of), self.to_left_of.bfs10607())))

    return bfs10617

  def bfs10634(self, bfs10645, bfs10644):
    return (bfs10645.is_displayed() and self.bfs10646(bfs10645, bfs10644))

  def bfs10646(self, element, bfs10647):
    for bfs10650 in bfs10647:
      bfs10651 = False
      for bfs10653 in bfs10650:
        if bfs10653(element.location):
          bfs10651 = True
          break


      if (not bfs10651):
        return False


    return True

  def bfs10635(self):
    raise NotImplementedError()

  def bfs10652(self):
    return (self.first_occurrence.get_attribute('disabled') is None)


class SImpl(bfs10623):
  def __init__(self, driver, bfs10654, **bfs10656):
    super(SImpl, self).__init__(driver, **bfs10656)
    self.bfs10654 = bfs10654

  def bfs10635(self):
    wrap = (lambda bfs10655: list(map(bfs10371, bfs10655)))
    if self.bfs10654.startswith('@'):
      return wrap(self.bfs10604.find_elements_by_name(self.bfs10654[1:]))

    if self.bfs10654.startswith('//'):
      return wrap(self.bfs10604.find_elements_by_xpath(self.bfs10654))

    return wrap(self.bfs10604.find_elements_by_css_selector(self.bfs10654))


class bfs10657(bfs10623):
  def bfs10635(self):
    bfs10660 = self.bfs10661()
    getLogger(__name__).debug('Looking for HTML element using xpath: %s.', bfs10660)
    return self.bfs10662(list(map(bfs10371, self.bfs10604.find_elements_by_xpath(bfs10660))))

  def bfs10662(self, bfs10663):
    bfs10665 = []
    for bfs10664 in bfs10663:
      try:
        key = self.bfs10666(bfs10664)
      except StaleElementReferenceException:
        pass
      else:
        bfs10665.append((key, bfs10664))


    bfs10670 = (lambda bfs10667: bfs10667[0])
    bfs10665.sort(key=bfs10670)
    bfs10671 = (lambda bfs10672: bfs10672[1])
    return list(map(bfs10671, bfs10665))

  def bfs10661(self):
    raise NotImplementedError()

  def bfs10666(self, web_element):
    return (self.bfs10604.bfs10355(web_element) + 1)


class bfs10674(bfs10657):
  def __init__(self, driver, text=None, **bfs10673):
    super(bfs10674, self).__init__(driver, **bfs10673)
    self.search_text = text

  def bfs10661(self):
    bfs10675 = (('//' + self.bfs10677()) + predicate(self.bfs10626.bfs10113('.', self.search_text)))
    return ('%s[not(self::script)][not(.%s)]' % (bfs10675, bfs10675))

  def bfs10677(self):
    return '*'


class TextImpl(bfs10674):
  def __init__(self, driver, text=None, include_free_text=True, **bfs10676):
    super(TextImpl, self).__init__(driver, text, **bfs10676)
    self.include_free_text = include_free_text

  @property
  def value(self):
    return self.first_occurrence.text

  def bfs10661(self):
    bfs10700 = [(super(TextImpl, self).bfs10661() + '[not(self::option)]'), ButtonImpl(self.bfs10604, self.search_text).bfs10702(), LinkImpl(self.bfs10604, self.search_text).bfs10661()]
    if self.include_free_text:
      bfs10700.append(bfs10701(self.bfs10604, self.search_text).bfs10661())

    return ' | '.join(bfs10700)


class bfs10701(bfs10674):
  def bfs10677(self):
    return 'text()'

  def bfs10661(self):
    return (super(bfs10701, self).bfs10661() + '/..')


class LinkImpl(bfs10674):
  def bfs10677(self):
    return 'a'

  def bfs10661(self):
    return ((((((super(LinkImpl, self).bfs10661() + ' | ') + '//a') + predicate(self.bfs10626.bfs10113('@title', self.search_text))) + ' | ') + "//*[@role='link']") + predicate(self.bfs10626.bfs10113('.', self.search_text)))


class ListItemImpl(bfs10674):
  def bfs10677(self):
    return 'li'


class ButtonImpl(bfs10674):
  def bfs10677(self):
    return 'button'

  def is_enabled(self):
    bfs10703 = self.first_occurrence.get_attribute('aria-disabled')
    return (self.bfs10652() and ((not bfs10703) or (bfs10703.lower() == 'false')))

  def bfs10661(self):
    bfs10705 = self.bfs10626.bfs10113('@aria-label', self.search_text)
    bfs10704 = self.bfs10626.bfs10113('.', self.search_text)
    bfs10706 = bfs10117(bfs10705, bfs10704)
    return ' | '.join([super(ButtonImpl, self).bfs10661(), self.bfs10702(), ("//*[@role='button']" + bfs10706), ('//button' + predicate(bfs10705))])

  def bfs10702(self):
    if self.search_text:
      bfs10707 = self.bfs10626.bfs10113('@value', self.search_text)
      bfs10711 = self.bfs10626.bfs10113('@label', self.search_text)
      bfs10710 = self.bfs10626.bfs10113('@aria-label', self.search_text)
      bfs10712 = self.bfs10626.bfs10113('@title', self.search_text)
      bfs10714 = bfs10117(bfs10707, bfs10711, bfs10710, bfs10712)
    else:
      bfs10714 = ''

    return ("//input[@type='submit' or @type='button']" + bfs10714)


class ImageImpl(bfs10657):
  def __init__(self, driver, alt, **bfs10713):
    super(ImageImpl, self).__init__(driver, **bfs10713)
    self.alt = alt

  def bfs10661(self):
    return ('//img' + predicate(self.bfs10626.bfs10113('@alt', self.alt)))


class bfs10715(bfs10623):
  bfs10717 = 1.5
  def __init__(self, driver, label=None, **bfs10716):
    super(bfs10715, self).__init__(driver, **bfs10716)
    self.label = label

  def bfs10635(self):
    if (not self.label):
      bfs10720 = self.bfs10722()
    else:
      bfs10721 = TextImpl(self.bfs10604, self.label, include_free_text=False).bfs10635()
      if bfs10721:
        bfs10720 = list(self.bfs10723(self.bfs10722(), bfs10721))
      else:
        bfs10720 = self.bfs10724()


    return sorted(bfs10720, key=self.bfs10604.bfs10355)

  def bfs10722(self, bfs10725=None):
    if (bfs10725 is None):
      bfs10725 = self.bfs10661()

    return list(map(bfs10371, self.bfs10604.find_elements_by_xpath(bfs10725)))

  def bfs10724(self):
    bfs10727 = [bfs10113.strip().lstrip('/') for bfs10113 in self.bfs10661().split('|')]
    bfs10726 = ('//text()' + predicate(self.bfs10626.bfs10113('.', self.label)))
    bfs10113 = ' | '.join([(((bfs10726 + '/following::') + bfs10730) + '[1]') for bfs10730 in bfs10727])
    return self.bfs10722(bfs10113)

  def bfs10661(self):
    raise NotImplementedError()

  def bfs10731(self):
    return 'to_right_of'

  def bfs10733(self):
    return 'below'

  def bfs10723(self, bfs10732, bfs10734):
    for (label, bfs10735) in self.bfs10736(bfs10732, bfs10734):
      yield bfs10735
      bfs10734.remove(label)
      bfs10732.remove(bfs10735)

    bfs10740 = self.bfs10737(bfs10732, bfs10734)
    bfs10740 = self.bfs10741(bfs10740)
    self.bfs10742(bfs10740)
    for bfs10744 in list(bfs10740.values()):
      assert (len(bfs10744) <= 1)
      if bfs10744:
        yield next(iter(bfs10744))



  def bfs10736(self, bfs10743, bfs10745):
    for label in bfs10745:
      if (label.tag_name == 'label'):
        bfs10746 = label.get_attribute('for')
        if bfs10746:
          for bfs10750 in bfs10743:
            bfs10747 = bfs10750.get_attribute('id')
            if (bfs10747.lower() == bfs10746.lower()):
              yield (label, bfs10750)






  def bfs10737(self, bfs10751, bfs10752):
    bfs10754 = {}
    for label in bfs10752:
      for bfs10753 in bfs10751:
        if self.bfs10755(bfs10753, label):
          if (label not in bfs10754):
            bfs10754[label] = set()

          bfs10754[label].add(bfs10753)



    return bfs10754

  def bfs10755(self, bfs10756, label):
    if bfs10756.location.bfs10254(label.location):
      return True

    bfs10757 = self.bfs10731()
    bfs10760 = self.bfs10733()
    return ((label.location.bfs10303(bfs10756.location) <= 150) and (bfs10756.location.bfs10271(bfs10757, label.location) or bfs10756.location.bfs10271(bfs10760, label.location)))

  def bfs10741(self, bfs10762):
    bfs10761 = bfs10406(bfs10762)
    self.bfs10742(bfs10761)
    return bfs10406(bfs10761)

  def bfs10742(self, bfs10763):
    for (bfs10765, bfs10764) in list(bfs10763.items()):
      if bfs10764:
        bfs10763[bfs10765] = set([self.bfs10766(bfs10765, bfs10764)])



  def bfs10766(self, bfs10770, bfs10767):
    bfs10771 = iter(bfs10767)
    bfs10772 = next(bfs10771)
    bfs10773 = self.bfs10775(bfs10772, bfs10770)
    for element in bfs10771:
      bfs10774 = self.bfs10775(element, bfs10770)
      if (bfs10774 < bfs10773):
        bfs10772 = element
        bfs10773 = bfs10774


    return bfs10772

  def bfs10775(self, bfs10776, bfs11000):
    bfs10777 = bfs10776.location
    bfs11001 = bfs11000.location
    if bfs10777.bfs10271(self.bfs10733(), bfs11001):
      bfs11002 = self.bfs10717
    else:
      bfs11002 = 1

    return (bfs11002 * bfs10777.bfs10303(bfs11001))


class bfs11004(bfs10623):
  def __init__(self, driver, *args, **bfs10433):
    super(bfs11004, self).__init__(driver, **bfs10433)
    self.args = ([driver] + list(args))
    self.bfs10433 = bfs10433
    self.bfs11003 = None

  @property
  def bfs11005(self):
    if (self.bfs11003 is None):
      self.bfs10615()

    return self.bfs11003

  def find_all(self):
    bfs11007 = []
    for element in self.bfs11006():
      for bfs11010 in element.find_all():
        if (self.bfs11003 is None):
          self.bfs11003 = element

        if (bfs11010 not in bfs11007):
          yield bfs11010
          bfs11007.append(bfs11010)




  def bfs11006(self):
    for bfs11012 in self.bfs11011():
      yield bfs11012(*self.args, **self.bfs10433)


  def bfs11011(self):
    raise NotImplementedError()


class bfs10472(bfs11004):
  def __init__(self, driver, text, **bfs11013):
    super(bfs10472, self).__init__(driver, text, **bfs11013)

  def bfs11011(self):
    return [ButtonImpl, TextImpl, ImageImpl]


class TextFieldImpl(bfs11004):
  def __init__(self, driver, label=None, **bfs11014):
    super(TextFieldImpl, self).__init__(driver, label, **bfs11014)

  def bfs11011(self):
    return [bfs11015, bfs11016, bfs11020]

  @property
  def value(self):
    return self.bfs11005.value

  def is_enabled(self):
    return self.bfs11005.is_enabled()

  def is_editable(self):
    return self.bfs11005.is_editable()


class bfs11016(bfs10715):
  @property
  def value(self):
    return (self.first_occurrence.get_attribute('value') or '')

  def is_enabled(self):
    return self.bfs10652()

  def is_editable(self):
    return (self.first_occurrence.get_attribute('readOnly') is None)

  def bfs10661(self):
    return (("//input[%s='text' or %s='email' or %s='password' or %s='number' or %s='tel' or string-length(@type)=0]" % ((lower('@type'),) * 5)) + " | //textarea | //*[@contenteditable='true']")


class bfs11020(bfs10715):
  @property
  def value(self):
    return self.first_occurrence.text

  def is_enabled(self):
    return self.bfs10652()

  def is_editable(self):
    return (self.first_occurrence.get_attribute('readOnly') is None)

  def bfs10661(self):
    return "//*[@role='textbox']"


class bfs11015(bfs10657):
  def __init__(self, driver, label, **bfs11017):
    super(bfs11015, self).__init__(driver, **bfs11017)
    self.label = label

  @property
  def value(self):
    return (self.first_occurrence.get_attribute('value') or '')

  def is_enabled(self):
    return self.bfs10652()

  def is_editable(self):
    return (self.first_occurrence.get_attribute('readOnly') is None)

  def bfs10661(self):
    return ('(%s)%s' % (bfs11016(self.label).bfs10661(), predicate(self.bfs10626.bfs10113('@placeholder', self.label))))


class bfs10542(bfs10715):
  def bfs10661(self):
    return "//input[@type='file']"


class ComboBoxImpl(bfs11004):
  def __init__(self, driver, label=None, **bfs11021):
    super(ComboBoxImpl, self).__init__(driver, label, **bfs11021)

  def bfs11011(self):
    return [bfs11023, bfs11022]

  def is_editable(self):
    return (self.first_occurrence.tag_name != 'select')

  @property
  def value(self):
    bfs11024 = self.bfs11025.first_selected_option
    if bfs11024:
      return bfs11024.text

    return None

  @property
  def options(self):
    return [bfs11026.text for bfs11026 in self.bfs11025.options]

  @property
  def bfs11025(self):
    return Select(self.web_element)


class bfs11023(bfs10715):
  def bfs10661(self):
    return '//select | //input[@list]'


class bfs11022(bfs10674):
  def bfs10677(self):
    return 'option'

  def bfs10661(self):
    bfs11027 = super(bfs11022, self).bfs10661()
    return (bfs11027 + '/ancestor::select[1]')

  def bfs10635(self):
    bfs11031 = super(bfs11022, self).bfs10635()
    bfs11030 = []
    for bfs11032 in bfs11031:
      for bfs11033 in Select(bfs11032.unwrap()).all_selected_options:
        if self.bfs10626.text(bfs11033.text, self.search_text):
          bfs11030.append(bfs11032)
          break



    return bfs11030


class CheckBoxImpl(bfs10715):
  def is_enabled(self):
    return self.bfs10652()

  def is_checked(self):
    return (self.first_occurrence.get_attribute('checked') is not None)

  def bfs10661(self):
    return "//input[@type='checkbox']"

  def bfs10731(self):
    return 'to_left_of'

  def bfs10733(self):
    return 'to_right_of'


class RadioButtonImpl(bfs10715):
  def is_selected(self):
    return (self.first_occurrence.get_attribute('checked') is not None)

  def bfs10661(self):
    return "//input[@type='radio']"

  def bfs10731(self):
    return 'to_left_of'

  def bfs10733(self):
    return 'to_right_of'


class WindowImpl(bfs10603):
  def __init__(self, driver, title=None):
    super(WindowImpl, self).__init__(driver)
    self.bfs11034 = title

  def bfs10607(self):
    bfs11036 = []
    for handle in self.bfs10604.window_handles:
      window = WindowImpl.bfs11035(self.bfs10604, handle)
      if (self.bfs11034 is None):
        bfs11036.append((0, window))
      else:
        title = window.title
        if title.startswith(self.bfs11034):
          bfs11037 = (len(title) - len(self.bfs11034))
          bfs11036.append((bfs11037, window))



    bfs11037 = (lambda bfs11040: bfs11040[0])
    bfs11036.sort(key=bfs11037)
    for (bfs11037, window) in bfs11036:
      yield window


  @property
  def title(self):
    return self.first_occurrence.title

  @property
  def handle(self):
    return self.first_occurrence.handle

  class bfs11035(object):
    def __init__(self, driver, handle):
      self.driver = driver
      self.handle = handle
      self.bfs11042 = None

    @property
    def title(self):
      with self:
        return self.driver.title


    def __enter__(self):
      self.bfs11042 = self.driver.current_window_handle
      if (self.driver.current_window_handle != self.handle):
        self.driver.switch_to.window(self.handle)


    def __exit__(self, *bfs11041):
      if (self.driver.current_window_handle != self.bfs11042):
        self.driver.switch_to.window(self.bfs11042)




class AlertImpl(bfs10603):
  def __init__(self, driver, search_text=None):
    super(AlertImpl, self).__init__(driver)
    self.search_text = search_text

  def bfs10607(self):
    bfs11043 = self.bfs10604.switch_to.alert
    try:
      text = bfs11043.text
      if ((self.search_text is None) or text.startswith(self.search_text)):
        yield bfs11043

    except NoAlertPresentException:
      pass


  @property
  def text(self):
    return self.first_occurrence.text

  def accept(self):
    first_occurrence = self.first_occurrence
    try:
      first_occurrence.accept()
    except WebDriverException as e:
      msg = e.msg
      if (msg and re.match('a\\.document\\.getElementsByTagName\\([^\\)]*\\)\\[0\\] is undefined', msg)):
        getLogger(__name__).warn('Got %r when trying to accept alert. Trying again after 0.25s.', e)
        sleep(0.25)
        first_occurrence.accept()
      else:
        raise 



  def dismiss(self):
    self.first_occurrence.dismiss()

  def bfs10461(self, text):
    self.first_occurrence.send_keys(text)


