from bfs.bfs10101.bfs10102 import LicensingError
from copy import copy
from decorator import decorator
from errno import ESRCH as bfs10324, EACCES as bfs10325
from helium.bfs10112.bfs10113 import bfs10114
from helium.bfs10112.bfs10127 import bfs10135
from helium.bfs10101.bfs10102 import bfs10136
from helium.bfs10101.bfs10144 import bfs10167, bfs10172
from helium.bfs10271 import bfs10311, bfs10274, bfs10312
from helium.bfs10060.bfs10320 import bfs10321
from helium.bfs10060.bfs10323 import bfs10322
from helium.bfs10060.system import bfs10120, bfs10121, bfs10117, bfs10125, bfs10122
from helium.bfs10060.bfs10104 import lower, predicate, bfs10111
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 bfs10332(bfs10030, self, *args, **bfs10066):
  if (self.driver.bfs10302() and AlertImpl(self.driver).exists()):
    return bfs10030(self, *args, **bfs10066)

  bfs10327 = self.driver.window_handles[:]
  bfs10063 = bfs10030(self, *args, **bfs10066)
  if (not (self.driver.bfs10302() and AlertImpl(self.driver).exists())):
    bfs10326 = [bfs10330 for bfs10330 in self.driver.window_handles if (bfs10330 not in bfs10327) ]
    if bfs10326:
      self.driver.switch_to.window(bfs10326[0])


  return bfs10063

@decorator
def bfs10331(bfs10030, *args, **bfs10066):
  try:
    return bfs10030(*args, **bfs10066)
  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, bfs10333, bfs10334, bfs10335=None):
    self.bfs10333 = bfs10333
    self.license = bfs10334
    self.bfs10335 = bfs10335
    self.driver = None

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

  def bfs10344(self, url=None):
    bfs10340 = self.bfs10342()
    bfs10341 = ChromeOptions()
    bfs10341.add_argument('--test-type')
    bfs10066 = {'chrome_options': bfs10341}
    if exists(bfs10340):
      if (not access(bfs10340, X_OK)):
        try:
          bfs10322(bfs10340)
        except:
          raise RuntimeError(('The Chrome driver located at %s is not executable.' % bfs10340))


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

    bfs10135()
    bfs10343 = Chrome(**bfs10066)
    atexit.register((lambda : self.bfs10345(bfs10343.service)))
    return self.bfs10337(bfs10343, url)

  def bfs10342(self):
    if bfs10120():
      bfs10346 = 'chromedriver.exe'
    elif bfs10121():
      bfs10346 = ('chromedriver' + ('_x64' if bfs10125() else '')
)
    else:
      assert bfs10117()
      bfs10346 = 'chromedriver'

    return self.bfs10333.bfs10347(bfs10122(), 'webdrivers', bfs10346)

  def bfs10345(self, service):
    if hasattr(service, 'process'):
      try:
        service.process.kill()
      except OSError as e:
        if (e.errno not in (bfs10324, bfs10325)):
          raise 




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

    bfs10350 = Ie(**bfs10066)
    atexit.register((lambda : self.bfs10345(bfs10350.iedriver)))
    return self.bfs10337(bfs10350, url)

  def bfs10337(self, bfs10354, url=None):
    try:
      self.bfs10353(bfs10354)
    except LicensingError:
      bfs10354.quit()
      raise 

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

    return self.bfs10357()

  @bfs10332
  @bfs10331
  def bfs10355(self, url):
    if ('://' not in url):
      url = ('http://' + url)

    self.driver.get(url)

  def bfs10353(self, driver):
    self.bfs10356(driver)
    self.driver = bfs10274(driver)

  def bfs10356(self, driver):
    try:
      self.license.bfs10360(bfs10167(self.bfs10335))
    except bfs10136:
      try:
        self.license.bfs10360(bfs10172(self.bfs10335, driver))
      except bfs10136:
        raise LicensingError('Unfortunately, Helium could not verify your license key. Please activate your internet connection and try again.')



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


  @bfs10332
  @bfs10331
  def bfs10365(self, text, into=None):
    if (into is not None):
      from helium.api import GUIElement
      if isinstance(into, GUIElement):
        into = into.bfs10361


    self.bfs10362(self.bfs10364, self.bfs10363, text, into=into)

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

      def bfs10366(bfs10367):
        if (hasattr(bfs10367, 'clear') and isinstance(bfs10367.clear, collections.Callable)):
          bfs10367.clear()

        bfs10367.send_keys(text)

      self.bfs10370(into, bfs10366)
    else:
      self.driver.switch_to.active_element.send_keys(text)


  def bfs10363(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.bfs10366(text)

  def bfs10362(self, bfs10371, bfs10372, *args, **bfs10066):
    if (self.driver.bfs10303() or (not AlertImpl(self.driver).exists())):
      try:
        return bfs10371(*args, **bfs10066)
      except UnexpectedAlertPresentException:
        if (self.driver.bfs10303() 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 bfs10372(*args, **bfs10066)

  @bfs10332
  @bfs10331
  def bfs10373(self, key):
    self.driver.switch_to.active_element.send_keys(key)

  def bfs10375(self, element):
    element = self.bfs10374(element)
    click = (lambda bfs10367: bfs10367.click())
    self.bfs10376(element, click, click)

  def bfs10374(self, bfs10367):
    from helium.api import HTMLElement
    if isinstance(bfs10367, str):
      bfs10367 = bfs10377(self.driver, bfs10367)
    elif isinstance(bfs10367, HTMLElement):
      bfs10367 = bfs10367.bfs10361

    return bfs10367

  @bfs10332
  @bfs10331
  def bfs10376(self, element, bfs10400, bfs10401):
    offset = None
    from helium.api import Point
    if isinstance(element, Point):
      (element, offset) = self.bfs10402(element)

    if (offset is not None):
      bfs10277 = (lambda bfs10367: bfs10401(self.driver.bfs10277().move_to_element_with_offset(bfs10367, *offset)).perform())
    else:
      bfs10277 = (lambda bfs10367: bfs10400(bfs10367))

    self.bfs10370(element, bfs10277)

  def bfs10402(self, bfs10223):
    element = bfs10311(self.driver.execute_script(('return document.elementFromPoint(%r, %r);' % (bfs10223.x, bfs10223.y))))
    offset = (bfs10223 - (element.location.bfs10176, element.location.bfs10200))
    if ((offset == (0, 0)) and self.driver.bfs10303()):
      offset = (1, 1)

    return (element, offset)

  def bfs10404(self, element):
    element = self.bfs10374(element)
    self.bfs10376(element, (lambda bfs10367: self.driver.bfs10277().double_click(bfs10367).perform()), (lambda bfs10277: bfs10277.double_click()))

  def bfs10406(self, element, to):
    self.bfs10403(element)
    self.bfs10405(to)

  def bfs10403(self, element):
    element = self.bfs10374(element)
    self.bfs10376(element, (lambda bfs10367: self.driver.bfs10277().click_and_hold(bfs10367).perform()), (lambda bfs10277: bfs10277.click_and_hold()))

  def bfs10405(self, element):
    element = self.bfs10374(element)
    self.bfs10376(element, (lambda bfs10367: self.driver.bfs10277().move_to_element(bfs10367).release().perform()), (lambda bfs10277: bfs10277.release()))

  @bfs10331
  def bfs10410(self, predicate):
    return [predicate.bfs10407(bfs10411) for bfs10411 in predicate.bfs10361.find_all()]

  def bfs10413(self, num_pixels):
    self.bfs10412(0, num_pixels)

  def bfs10415(self, num_pixels):
    self.bfs10412(0, (-num_pixels))

  def bfs10414(self, num_pixels):
    self.bfs10412(num_pixels, 0)

  def bfs10416(self, num_pixels):
    self.bfs10412((-num_pixels), 0)

  @bfs10331
  def bfs10412(self, bfs10420, bfs10417):
    self.driver.execute_script('window.scrollBy(arguments[0], arguments[1]);', bfs10420, bfs10417)

  def bfs10421(self, element):
    element = self.bfs10374(element)
    self.bfs10376(element, (lambda bfs10367: self.driver.bfs10277().move_to_element(bfs10367).perform()), (lambda bfs10277: bfs10277))

  def bfs10423(self, element):
    element = self.bfs10374(element)
    self.bfs10376(element, (lambda bfs10367: self.driver.bfs10277().context_click(bfs10367).perform()), (lambda bfs10277: bfs10277.context_click()))

  @bfs10332
  @bfs10331
  def bfs10424(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.bfs10361

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

    self.bfs10370(combo_box, bfs10422)

  def bfs10370(self, bfs10425, bfs10277):
    if (hasattr(bfs10425, 'perform') and isinstance(bfs10425.perform, collections.Callable)):
      self.driver.bfs10275 = bfs10425.perform(bfs10277)
    else:
      if isinstance(bfs10425, WebElement):
        bfs10425 = bfs10311(bfs10425)

      bfs10277(bfs10425)
      self.driver.bfs10275 = bfs10425


  @bfs10331
  def bfs10432(self, file_path, to):
    to = self.bfs10374(to)
    drag_and_drop = bfs10427(self.driver, file_path)
    drag_and_drop.begin()
    try:
      drag_and_drop.bfs10426()
      self.bfs10370(to, (lambda bfs10367: drag_and_drop.bfs10430(bfs10367)))
    finally:
      drag_and_drop.end()


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

    bfs10433 = (lambda bfs10367: bfs10367.send_keys(file_path))
    self.bfs10376(to, bfs10433, bfs10433)

  def bfs10440(self):
    self.bfs10362(self.bfs10434, self.bfs10436)

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

  def bfs10436(self):
    AlertImpl(self.driver).accept()
    self.bfs10434()

  def bfs10443(self, condition_fn, timeout_secs=10, interval_secs=0.5):
    if ismethod(condition_fn):
      bfs10437 = (condition_fn.__self__ is not None)
      bfs10441 = getargspec(condition_fn).args
      bfs10442 = (len(bfs10441) - (1 if bfs10437 else 0)
)
    else:
      if (not isfunction(condition_fn)):
        condition_fn = condition_fn.__call__

      bfs10441 = getargspec(condition_fn).args
      bfs10442 = len(bfs10441)

    bfs10107 = (condition_fn if bfs10442 else (lambda driver: condition_fn()))

    wait = WebDriverWait(self.bfs10357(), timeout_secs, poll_frequency=interval_secs)
    wait.until(bfs10107)

  @bfs10331
  def bfs10444(self, window):
    from helium.api import Window
    if isinstance(window, str):
      window = WindowImpl(self.driver, window)
    elif isinstance(window, Window):
      window = window.bfs10361

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

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

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

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

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

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

    bfs10447 = 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, bfs10447)


class bfs10427(object):
  def __init__(self, driver, file_path):
    self.driver = driver
    self.file_path = file_path
    self.bfs10450 = None
    self.bfs10452 = None

  def begin(self):
    self.bfs10451()
    try:
      self.bfs10450.send_keys(self.file_path)
    except:
      self.end()
      raise 


  def bfs10451(self):
    self.bfs10450 = 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 bfs10426(self):
    self.bfs10453('dragenter', to='document.body')
    self.bfs10452 = self.bfs10454('dragover', 'document', interval_msecs=300)
    self.bfs10452.start()

  def bfs10453(self, bfs10456, to):
    (bfs10455, args) = self.bfs10457(bfs10456, to)
    self.driver.execute_script(bfs10455, *args)

  def bfs10454(self, bfs10456, to, interval_msecs):
    (bfs10455, args) = self.bfs10457(bfs10456, to)
    return bfs10461(self.driver, bfs10455, args, interval_msecs)

  def bfs10457(self, bfs10456, to):
    bfs10455 = "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):
      bfs10455 = bfs10455.replace('arguments[2]', to)
      args = (self.bfs10450, bfs10456)
    else:
      args = (self.bfs10450, bfs10456, to.unwrap())

    return (bfs10455, args)

  def bfs10430(self, target):
    self.bfs10452.stop()
    self.bfs10453('drop', to=target)

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

    self.bfs10450 = None


class bfs10461(object):
  def __init__(self, driver, bfs10455, args, interval_msecs):
    self.driver = driver
    self.bfs10455 = bfs10455
    self.args = args
    self.interval_msecs = interval_msecs
    self.bfs10460 = None

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

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


class bfs10464(object):
  def __init__(self, driver):
    self.bfs10463 = None
    self.bfs10465 = driver

  def find_all(self):
    if self.bfs10466():
      yield self
    else:
      for bfs10467 in self.bfs10471():
        yield self.bfs10470(bfs10467)



  def bfs10466(self):
    return (self.bfs10463 is not None)

  def bfs10471(self):
    raise NotImplementedError()

  def bfs10470(self, bfs10467):
    bfs10063 = copy(self)
    bfs10063.bfs10463 = bfs10467
    return bfs10063

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


  @property
  def first_occurrence(self):
    if (not self.bfs10466()):
      self.bfs10472()

    return self.bfs10463

  def bfs10472(self):
    self.perform((lambda bfs10070: None))

  def perform(self, bfs10277):
    from helium.api import Config
    bfs10473 = (time() + Config.implicit_wait_secs)
    bfs10063 = self.bfs10474(bfs10277)
    while ((bfs10063 is None) and (time() < bfs10473)):
      bfs10063 = self.bfs10474(bfs10277)

    if (bfs10063 is not None):
      return bfs10063

    raise LookupError()

  def bfs10474(self, bfs10277):
    for bfs10411 in self.find_all():
      bfs10467 = bfs10411.first_occurrence
      try:
        bfs10277(bfs10467)
      except Exception as e:
        if self.bfs10476(e):
          continue
        else:
          raise 

      else:
        self.bfs10463 = bfs10467
        return bfs10467



  def bfs10476(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 bfs10475(bfs10464):
  def __init__(self, driver, below=None, to_right_of=None, above=None, to_left_of=None):
    super(bfs10475, self).__init__(driver)
    self.below = self.bfs10477(below)
    self.to_right_of = self.bfs10477(to_right_of)
    self.above = self.bfs10477(above)
    self.to_left_of = self.bfs10477(to_left_of)
    self.bfs10500 = bfs10114()

  def bfs10477(self, element):
    if isinstance(element, str):
      return TextImpl(self.bfs10465, element)

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

    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.bfs10176

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

  @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 bfs10471(self):
    self.bfs10501()
    bfs10503 = self.bfs10502()
    for bfs10070 in bfs10312(self.bfs10465):
      for bfs10467 in self.bfs10504():
        if self.bfs10506(bfs10467, bfs10503):
          yield bfs10467




  def bfs10501(self):
    window_handles = self.bfs10465.window_handles
    try:
      bfs10505 = self.bfs10465.current_window_handle
    except NoSuchWindowException:
      bfs10507 = True
    else:
      bfs10507 = (bfs10505 not in window_handles)

    if bfs10507:
      self.bfs10465.switch_to_window(window_handles[0])


  def bfs10502(self):
    bfs10063 = []
    if self.below:
      bfs10063.append(list(map((lambda bfs10367: bfs10367.location.is_above), self.below.bfs10471())))

    if self.to_right_of:
      bfs10063.append(list(map((lambda bfs10367: bfs10367.location.is_to_left_of), self.to_right_of.bfs10471())))

    if self.above:
      bfs10063.append(list(map((lambda bfs10367: bfs10367.location.is_below), self.above.bfs10471())))

    if self.to_left_of:
      bfs10063.append(list(map((lambda bfs10367: bfs10367.location.is_to_right_of), self.to_left_of.bfs10471())))

    return bfs10063

  def bfs10506(self, bfs10467, bfs10503):
    return (bfs10467.is_displayed() and self.bfs10511(bfs10467, bfs10503))

  def bfs10511(self, element, bfs10503):
    for bfs10510 in bfs10503:
      bfs10512 = False
      for bfs10513 in bfs10510:
        if bfs10513(element.location):
          bfs10512 = True
          break


      if (not bfs10512):
        return False


    return True

  def bfs10504(self):
    raise NotImplementedError()

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


class SImpl(bfs10475):
  def __init__(self, driver, bfs10301, **bfs10066):
    super(SImpl, self).__init__(driver, **bfs10066)
    self.bfs10301 = bfs10301

  def bfs10504(self):
    wrap = (lambda bfs10514: list(map(bfs10311, bfs10514)))
    if self.bfs10301.startswith('@'):
      return wrap(self.bfs10465.find_elements_by_name(self.bfs10301[1:]))

    if self.bfs10301.startswith('//'):
      return wrap(self.bfs10465.find_elements_by_xpath(self.bfs10301))

    return wrap(self.bfs10465.find_elements_by_css_selector(self.bfs10301))


class bfs10516(bfs10475):
  def bfs10504(self):
    bfs10517 = self.bfs10520()
    getLogger(__name__).debug('Looking for HTML element using xpath: %s.', bfs10517)
    return self.bfs10521(list(map(bfs10311, self.bfs10465.find_elements_by_xpath(bfs10517))))

  def bfs10521(self, bfs10523):
    bfs10522 = []
    for bfs10524 in bfs10523:
      try:
        key = self.bfs10525(bfs10524)
      except StaleElementReferenceException:
        pass
      else:
        bfs10522.append((key, bfs10524))


    bfs10527 = (lambda bfs10252: bfs10252[0])
    bfs10522.sort(key=bfs10527)
    bfs10526 = (lambda bfs10252: bfs10252[1])
    return list(map(bfs10526, bfs10522))

  def bfs10520(self):
    raise NotImplementedError()

  def bfs10525(self, web_element):
    return (self.bfs10465.bfs10300(web_element) + 1)


class bfs10530(bfs10516):
  def __init__(self, driver, text=None, **bfs10066):
    super(bfs10530, self).__init__(driver, **bfs10066)
    self.search_text = text

  def bfs10520(self):
    bfs10531 = (('//' + self.bfs10532()) + predicate(self.bfs10500.bfs10104('.', self.search_text)))
    return ('%s[not(self::script)][not(.%s)]' % (bfs10531, bfs10531))

  def bfs10532(self):
    return '*'


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

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

  def bfs10520(self):
    bfs10534 = [(super(TextImpl, self).bfs10520() + '[not(self::option)]'), ButtonImpl(self.bfs10465, self.search_text).bfs10533(), LinkImpl(self.bfs10465, self.search_text).bfs10520()]
    if self.include_free_text:
      bfs10534.append(bfs10535(self.bfs10465, self.search_text).bfs10520())

    return ' | '.join(bfs10534)


class bfs10535(bfs10530):
  def bfs10532(self):
    return 'text()'

  def bfs10520(self):
    return (super(bfs10535, self).bfs10520() + '/..')


class LinkImpl(bfs10530):
  def bfs10532(self):
    return 'a'

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


class ListItemImpl(bfs10530):
  def bfs10532(self):
    return 'li'


class ButtonImpl(bfs10530):
  def bfs10532(self):
    return 'button'

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

  def bfs10520(self):
    bfs10540 = self.bfs10500.bfs10104('@aria-label', self.search_text)
    bfs10537 = self.bfs10500.bfs10104('.', self.search_text)
    bfs10541 = bfs10111(bfs10540, bfs10537)
    return ' | '.join([super(ButtonImpl, self).bfs10520(), self.bfs10533(), ("//*[@role='button']" + bfs10541), ('//button' + predicate(bfs10540))])

  def bfs10533(self):
    if self.search_text:
      bfs10543 = self.bfs10500.bfs10104('@value', self.search_text)
      bfs10542 = self.bfs10500.bfs10104('@label', self.search_text)
      bfs10540 = self.bfs10500.bfs10104('@aria-label', self.search_text)
      bfs10544 = self.bfs10500.bfs10104('@title', self.search_text)
      bfs10537 = bfs10111(bfs10543, bfs10542, bfs10540, bfs10544)
    else:
      bfs10537 = ''

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


class ImageImpl(bfs10516):
  def __init__(self, driver, alt, **bfs10066):
    super(ImageImpl, self).__init__(driver, **bfs10066)
    self.alt = alt

  def bfs10520(self):
    return ('//img' + predicate(self.bfs10500.bfs10104('@alt', self.alt)))


class bfs10546(bfs10475):
  bfs10545 = 1.5
  def __init__(self, driver, label=None, **bfs10066):
    super(bfs10546, self).__init__(driver, **bfs10066)
    self.label = label

  def bfs10504(self):
    if (not self.label):
      bfs10063 = self.bfs10547()
    else:
      bfs10550 = TextImpl(self.bfs10465, self.label, include_free_text=False).bfs10504()
      if bfs10550:
        bfs10063 = list(self.bfs10551(self.bfs10547(), bfs10550))
      else:
        bfs10063 = self.bfs10552()


    return sorted(bfs10063, key=self.bfs10465.bfs10300)

  def bfs10547(self, bfs10104=None):
    if (bfs10104 is None):
      bfs10104 = self.bfs10520()

    return list(map(bfs10311, self.bfs10465.find_elements_by_xpath(bfs10104)))

  def bfs10552(self):
    bfs10553 = [bfs10104.strip().lstrip('/') for bfs10104 in self.bfs10520().split('|')]
    bfs10550 = ('//text()' + predicate(self.bfs10500.bfs10104('.', self.label)))
    bfs10104 = ' | '.join([(((bfs10550 + '/following::') + bfs10555) + '[1]') for bfs10555 in bfs10553])
    return self.bfs10547(bfs10104)

  def bfs10520(self):
    raise NotImplementedError()

  def bfs10554(self):
    return 'to_right_of'

  def bfs10556(self):
    return 'below'

  def bfs10551(self, bfs10560, bfs10550):
    for (label, bfs10367) in self.bfs10557(bfs10560, bfs10550):
      yield bfs10367
      bfs10550.remove(label)
      bfs10560.remove(bfs10367)

    bfs10561 = self.bfs10562(bfs10560, bfs10550)
    bfs10561 = self.bfs10563(bfs10561)
    self.bfs10565(bfs10561)
    for bfs10564 in list(bfs10561.values()):
      assert (len(bfs10564) <= 1)
      if bfs10564:
        yield next(iter(bfs10564))



  def bfs10557(self, bfs10560, bfs10550):
    for label in bfs10550:
      if (label.tag_name == 'label'):
        bfs10566 = label.get_attribute('for')
        if bfs10566:
          for bfs10367 in bfs10560:
            bfs10567 = bfs10367.get_attribute('id')
            if (bfs10567.lower() == bfs10566.lower()):
              yield (label, bfs10367)






  def bfs10562(self, bfs10560, bfs10550):
    bfs10063 = {}
    for label in bfs10550:
      for bfs10367 in bfs10560:
        if self.bfs10571(bfs10367, label):
          if (label not in bfs10063):
            bfs10063[label] = set()

          bfs10063[label].add(bfs10367)



    return bfs10063

  def bfs10571(self, bfs10367, label):
    if bfs10367.location.bfs10227(label.location):
      return True

    bfs10570 = self.bfs10554()
    bfs10572 = self.bfs10556()
    return ((label.location.bfs10253(bfs10367.location) <= 150) and (bfs10367.location.bfs10243(bfs10570, label.location) or bfs10367.location.bfs10243(bfs10572, label.location)))

  def bfs10563(self, bfs10561):
    bfs10573 = bfs10321(bfs10561)
    self.bfs10565(bfs10573)
    return bfs10321(bfs10573)

  def bfs10565(self, bfs10574):
    for (bfs10576, bfs10575) in list(bfs10574.items()):
      if bfs10575:
        bfs10574[bfs10576] = set([self.bfs10577(bfs10576, bfs10575)])



  def bfs10577(self, bfs10600, bfs10601):
    bfs10602 = iter(bfs10601)
    bfs10063 = next(bfs10602)
    bfs10603 = self.bfs10605(bfs10063, bfs10600)
    for element in bfs10602:
      bfs10604 = self.bfs10605(element, bfs10600)
      if (bfs10604 < bfs10603):
        bfs10063 = element
        bfs10603 = bfs10604


    return bfs10063

  def bfs10605(self, bfs10606, bfs10610):
    bfs10607 = bfs10606.location
    bfs10611 = bfs10610.location
    if bfs10607.bfs10243(self.bfs10556(), bfs10611):
      bfs10612 = self.bfs10545
    else:
      bfs10612 = 1

    return (bfs10612 * bfs10607.bfs10253(bfs10611))


class bfs10613(bfs10475):
  def __init__(self, driver, *args, **bfs10066):
    super(bfs10613, self).__init__(driver, **bfs10066)
    self.args = ([driver] + list(args))
    self.bfs10066 = bfs10066
    self.bfs10615 = None

  @property
  def bfs10614(self):
    if (self.bfs10615 is None):
      self.bfs10472()

    return self.bfs10615

  def find_all(self):
    bfs10616 = []
    for element in self.bfs10617():
      for bfs10411 in element.find_all():
        if (self.bfs10615 is None):
          self.bfs10615 = element

        if (bfs10411 not in bfs10616):
          yield bfs10411
          bfs10616.append(bfs10411)




  def bfs10617(self):
    for bfs10621 in self.bfs10620():
      yield bfs10621(*self.args, **self.bfs10066)


  def bfs10620(self):
    raise NotImplementedError()


class bfs10377(bfs10613):
  def __init__(self, driver, text, **bfs10066):
    super(bfs10377, self).__init__(driver, text, **bfs10066)

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


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

  def bfs10620(self):
    return [bfs10622, bfs10624, bfs10623]

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

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

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


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

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

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

  def bfs10520(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 bfs10623(bfs10546):
  @property
  def value(self):
    return self.first_occurrence.text

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

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

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


class bfs10622(bfs10516):
  def __init__(self, driver, label, **bfs10066):
    super(bfs10622, self).__init__(driver, **bfs10066)
    self.label = label

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

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

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

  def bfs10520(self):
    return ('(%s)%s' % (bfs10624(self.label).bfs10520(), predicate(self.bfs10500.bfs10104('@placeholder', self.label))))


class bfs10431(bfs10546):
  def bfs10520(self):
    return "//input[@type='file']"


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

  def bfs10620(self):
    return [bfs10625, bfs10626]

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

  @property
  def value(self):
    bfs10627 = self.bfs10631.first_selected_option
    if bfs10627:
      return bfs10627.text

    return None

  @property
  def options(self):
    return [bfs10630.text for bfs10630 in self.bfs10631.options]

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


class bfs10625(bfs10546):
  def bfs10520(self):
    return '//select | //input[@list]'


class bfs10626(bfs10530):
  def bfs10532(self):
    return 'option'

  def bfs10520(self):
    bfs10632 = super(bfs10626, self).bfs10520()
    return (bfs10632 + '/ancestor::select[1]')

  def bfs10504(self):
    bfs10633 = super(bfs10626, self).bfs10504()
    bfs10063 = []
    for bfs10635 in bfs10633:
      for bfs10634 in Select(bfs10635.unwrap()).all_selected_options:
        if self.bfs10500.text(bfs10634.text, self.search_text):
          bfs10063.append(bfs10635)
          break



    return bfs10063


class CheckBoxImpl(bfs10546):
  def is_enabled(self):
    return self.bfs10515()

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

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

  def bfs10554(self):
    return 'to_left_of'

  def bfs10556(self):
    return 'to_right_of'


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

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

  def bfs10554(self):
    return 'to_left_of'

  def bfs10556(self):
    return 'to_right_of'


class WindowImpl(bfs10464):
  def __init__(self, driver, title=None):
    super(WindowImpl, self).__init__(driver)
    self.bfs10636 = title

  def bfs10471(self):
    bfs10637 = []
    for handle in self.bfs10465.window_handles:
      window = WindowImpl.bfs10641(self.bfs10465, handle)
      if (self.bfs10636 is None):
        bfs10637.append((0, window))
      else:
        title = window.title
        if title.startswith(self.bfs10636):
          bfs10640 = (len(title) - len(self.bfs10636))
          bfs10637.append((bfs10640, window))



    bfs10640 = (lambda bfs10252: bfs10252[0])
    bfs10637.sort(key=bfs10640)
    for (bfs10640, window) in bfs10637:
      yield window


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

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

  class bfs10641(object):
    def __init__(self, driver, handle):
      self.driver = driver
      self.handle = handle
      self.bfs10642 = None

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


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


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




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

  def bfs10471(self):
    bfs10063 = self.bfs10465.switch_to.alert
    try:
      text = bfs10063.text
      if ((self.search_text is None) or text.startswith(self.search_text)):
        yield bfs10063

    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 bfs10366(self, text):
    self.first_occurrence.send_keys(text)


