from bfs.bfs10131.errors import bfs10135
from copy import copy
from decorator import decorator
from errno import ESRCH as bfs10433, EACCES as bfs10435
from helium.bfs10145.bfs10147 import bfs10150
from helium.bfs10145.bfs10161 import bfs10166
from helium.bfs10131.errors import bfs10171
from helium.bfs10131.bfs10177 import bfs10227, bfs10232
from helium.bfs10372 import bfs10415, bfs10375, bfs10416
from helium.bfs10076.bfs10425 import bfs10430
from helium.bfs10076.bfs10432 import bfs10431
from helium.bfs10076.system import bfs10151, bfs10154, bfs10153, bfs10160, bfs10155
from helium.bfs10076.bfs10137 import lower, predicate, bfs10143
from inspect import getargspec, ismethod, isfunction
from os import access, X_OK
from os.path import exists
from selenium.common.exceptions import UnexpectedAlertPresentException, ElementNotVisibleException, MoveTargetOutOfBoundsException, WebDriverException, StaleElementReferenceException, NoAlertPresentException
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 logging
import re
bfs10106 = logging.getLogger(__name__)
bfs10106.setLevel(logging.INFO)
@decorator
def bfs10442(bfs10405, self, *args, **bfs10434):
  if (self.driver.bfs10403() and AlertImpl(self.driver).exists()):
    return bfs10405(self, *args, **bfs10434)

  bfs10436 = self.driver.window_handles[:]
  bfs10440 = bfs10405(self, *args, **bfs10434)
  if (not (self.driver.bfs10403() and AlertImpl(self.driver).exists())):
    bfs10437 = [bfs10441 for bfs10441 in self.driver.window_handles if (bfs10441 not in bfs10436) ]
    if bfs10437:
      self.driver.switch_to.window(bfs10437[0])


  return bfs10440

@decorator
def bfs10444(bfs10405, *args, **bfs10443):
  try:
    return bfs10405(*args, **bfs10443)
  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, bfs10445, bfs10447, bfs10446=None):
    self.bfs10445 = bfs10445
    self.license = bfs10447
    self.bfs10446 = bfs10446
    self.driver = None

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

  def bfs10457(self, url=None):
    bfs10452 = self.bfs10451()
    bfs10453 = ChromeOptions()
    bfs10453.add_argument('--test-type')
    bfs10454 = {'chrome_options': bfs10453}
    if exists(bfs10452):
      if (not access(bfs10452, X_OK)):
        try:
          bfs10431(bfs10452)
        except:
          raise RuntimeError(('The Chrome driver located at %s is not executable.' % bfs10452))


      bfs10106.info(('Using Chrome driver located at %s.' % bfs10452))
      bfs10454['executable_path'] = bfs10452
    else:
      bfs10106.warn(('Could not find Chrome driver at expected location %s.' % bfs10452))

    bfs10166()
    bfs10456 = Chrome(**bfs10454)
    atexit.register((lambda : self.bfs10455(bfs10456.service)))
    return self._start(bfs10456, url)

  def bfs10451(self):
    if bfs10151():
      bfs10461 = 'chromedriver.exe'
    elif bfs10154():
      bfs10461 = ('chromedriver' + ('_x64' if bfs10160() else '')
)
    else:
      assert bfs10153()
      bfs10461 = 'chromedriver'

    return self.bfs10445.bfs10062(bfs10155(), 'webdrivers', bfs10461)

  def bfs10455(self, service):
    if hasattr(service, 'process'):
      try:
        service.process.kill()
      except OSError, e:
        if (e.errno not in (bfs10433, bfs10435)):
          raise 




  def bfs10464(self, url=None):
    bfs10460 = self.bfs10445.bfs10062('win', 'webdrivers', 'IEDriverServer.exe')
    capabilities = DesiredCapabilities.INTERNETEXPLORER.copy()
    capabilities['ignoreZoomSetting'] = True
    bfs10454 = {'capabilities': capabilities}
    if exists(bfs10460):
      bfs10106.info(('Using IE driver located at %s.' % bfs10460))
      bfs10454['executable_path'] = bfs10460
    else:
      bfs10106.warn(('Could not find IE driver at expected location %s.' % bfs10460))

    bfs10462 = Ie(**bfs10454)
    atexit.register((lambda : self.bfs10455(bfs10462.iedriver)))
    return self._start(bfs10462, url)

  def _start(self, bfs10463, url=None):
    try:
      self.bfs10465(bfs10463)
    except bfs10135:
      bfs10463.quit()
      raise 

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

    return self.bfs10467()

  @bfs10442
  @bfs10444
  def bfs10466(self, url):
    if ('://' not in url):
      url = ('http://' + url)

    self.driver.get(url)

  def bfs10465(self, driver):
    self.bfs10471(driver)
    self.driver = bfs10375(driver)

  def bfs10471(self, driver):
    try:
      self.license.bfs10470(bfs10227(self.bfs10446))
    except bfs10171:
      try:
        self.license.bfs10470(bfs10232(self.bfs10446, driver))
      except bfs10171:
        raise bfs10135('Unfortunately, Helium could not verify your license key. Please activate your internet connection and try again.')



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


  @bfs10442
  @bfs10444
  def bfs10475(self, text, into=None):
    if (into is not None):
      from helium.api import GUIElement
      if isinstance(into, GUIElement):
        into = into.bfs10472


    self.bfs10473(self.bfs10474, self.bfs10476, text, into=into)

  def bfs10474(self, text, into=None):
    if into:
      if isinstance(into, basestring):
        into = TextFieldImpl(self.driver, into)

      def _write(bfs10477):
        if (hasattr(bfs10477, 'clear') and callable(bfs10477.clear)):
          bfs10477.clear()

        bfs10477.send_keys(text)

      self.bfs10500(into, _write)
    else:
      self.driver.switch_to.active_element.send_keys(text)


  def bfs10476(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._write(text)

  def bfs10473(self, bfs10501, bfs10503, *args, **bfs10502):
    if (self.driver.bfs10404() or (not AlertImpl(self.driver).exists())):
      try:
        return bfs10501(*args, **bfs10502)
      except UnexpectedAlertPresentException:
        if (self.driver.bfs10404() 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 bfs10503(*args, **bfs10502)

  @bfs10442
  @bfs10444
  def bfs10504(self, key):
    self.driver.switch_to.active_element.send_keys(key)

  def bfs10511(self, element):
    element = self.bfs10506(element)
    click = (lambda bfs10505: bfs10505.click())
    self.bfs10507(element, click, click)

  def bfs10506(self, bfs10477):
    from helium.api import HTMLElement
    if isinstance(bfs10477, basestring):
      bfs10477 = bfs10510(self.driver, bfs10477)
    elif isinstance(bfs10477, HTMLElement):
      bfs10477 = bfs10477.bfs10472

    return bfs10477

  @bfs10442
  @bfs10444
  def bfs10507(self, element, bfs10512, bfs10513):
    offset = None
    from helium.api import Point
    if isinstance(element, Point):
      (element, offset) = self.bfs10515(element)

    if (offset is not None):
      bfs10400 = (lambda bfs10514: bfs10513(self.driver.bfs10400().move_to_element_with_offset(bfs10514, *offset)).perform())
    else:
      bfs10400 = (lambda bfs10516: bfs10512(bfs10516))

    self.bfs10500(element, bfs10400)

  def bfs10515(self, bfs10517):
    element = bfs10415(self.driver.execute_script(('return document.elementFromPoint(%r, %r);' % (bfs10517.x, bfs10517.y))))
    offset = (bfs10517 - (element.location.bfs10237, element.location.bfs10236))
    if ((offset == (0, 0)) and self.driver.bfs10404()):
      offset = (1, 1)

    return (element, offset)

  def bfs10523(self, element):
    element = self.bfs10506(element)
    self.bfs10507(element, (lambda bfs10520: self.driver.bfs10400().double_click(bfs10520).perform()), (lambda bfs10521: bfs10521.double_click()))

  def bfs10525(self, element, to):
    self.bfs10522(element)
    self.bfs10524(to)

  def bfs10522(self, element):
    element = self.bfs10506(element)
    self.bfs10507(element, (lambda bfs10527: self.driver.bfs10400().click_and_hold(bfs10527).perform()), (lambda bfs10526: bfs10526.click_and_hold()))

  def bfs10524(self, element):
    element = self.bfs10506(element)
    self.bfs10507(element, (lambda bfs10530: self.driver.bfs10400().move_to_element(bfs10530).release().perform()), (lambda bfs10531: bfs10531.release()))

  @bfs10444
  def bfs10533(self, predicate):
    return [predicate.bfs10532(bfs10534) for bfs10534 in predicate.bfs10472.find_all()]

  def bfs10536(self, num_pixels):
    self.bfs10535(0, num_pixels)

  def bfs10540(self, num_pixels):
    self.bfs10535(0, (-num_pixels))

  def bfs10537(self, num_pixels):
    self.bfs10535(num_pixels, 0)

  def bfs10541(self, num_pixels):
    self.bfs10535((-num_pixels), 0)

  @bfs10444
  def bfs10535(self, bfs10543, bfs10542):
    self.driver.execute_script('window.scrollBy(arguments[0], arguments[1]);', bfs10543, bfs10542)

  def bfs10545(self, element):
    element = self.bfs10506(element)
    self.bfs10507(element, (lambda bfs10544: self.driver.bfs10400().move_to_element(bfs10544).perform()), (lambda bfs10546: bfs10546))

  def bfs10551(self, element):
    element = self.bfs10506(element)
    self.bfs10507(element, (lambda bfs10547: self.driver.bfs10400().context_click(bfs10547).perform()), (lambda bfs10550: bfs10550.context_click()))

  @bfs10442
  @bfs10444
  def bfs10553(self, combo_box, value):
    from helium.api import ComboBox
    if isinstance(combo_box, basestring):
      combo_box = ComboBoxImpl(self.driver, combo_box)
    elif isinstance(combo_box, ComboBox):
      combo_box = combo_box.bfs10472

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

    self.bfs10500(combo_box, bfs10552)

  def bfs10500(self, bfs10555, bfs10400):
    if (hasattr(bfs10555, 'perform') and callable(bfs10555.perform)):
      self.driver.bfs10377 = bfs10555.perform(bfs10400)
    else:
      if isinstance(bfs10555, WebElement):
        bfs10555 = bfs10415(bfs10555)

      bfs10400(bfs10555)
      self.driver.bfs10377 = bfs10555


  @bfs10444
  def bfs10561(self, file_path, to):
    to = self.bfs10506(to)
    drag_and_drop = bfs10554(self.driver, file_path)
    drag_and_drop.begin()
    try:
      drag_and_drop.bfs10556()
      self.bfs10500(to, (lambda bfs10560: drag_and_drop.bfs10557(bfs10560)))
    finally:
      drag_and_drop.end()


  def bfs10564(self, file_path, to=None):
    if (to is None):
      to = bfs10562(self.driver)
    elif isinstance(to, basestring):
      to = bfs10562(self.driver, to)

    bfs10563 = (lambda bfs10565: bfs10565.send_keys(file_path))
    self.bfs10507(to, bfs10563, bfs10563)

  def bfs10571(self):
    self.bfs10473(self.bfs10566, self.bfs10567)

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

  def bfs10567(self):
    AlertImpl(self.driver).accept()
    self.bfs10566()

  def bfs10576(self, condition_fn, timeout_secs=10, interval_secs=0.5):
    if ismethod(condition_fn):
      bfs10570 = (condition_fn.im_self is not None)
      bfs10572 = getargspec(condition_fn).args
      bfs10573 = (len(bfs10572) - (1 if bfs10570 else 0)
)
    else:
      if (not isfunction(condition_fn)):
        condition_fn = condition_fn.__call__

      bfs10572 = getargspec(condition_fn).args
      bfs10573 = len(bfs10572)

    bfs10574 = (condition_fn if bfs10573 else (lambda driver: condition_fn()))

    wait = WebDriverWait(self.bfs10467(), timeout_secs, poll_frequency=interval_secs)
    wait.until(bfs10574)

  @bfs10444
  def bfs10575(self, window):
    from helium.api import Window
    if isinstance(window, basestring):
      window = WindowImpl(self.driver, window)
    elif isinstance(window, Window):
      window = window.bfs10472

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

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

  @bfs10444
  def bfs10601(self, element):
    from helium.api import HTMLElement
    if isinstance(element, HTMLElement):
      element = element.bfs10472

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

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

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


class bfs10554(object):
  def __init__(self, driver, file_path):
    self.driver = driver
    self.file_path = file_path
    self.bfs10602 = None
    self.bfs10603 = None

  def begin(self):
    self.bfs10605()
    try:
      self.bfs10602.send_keys(self.file_path)
    except:
      self.end()
      raise 


  def bfs10605(self):
    self.bfs10602 = 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 bfs10556(self):
    self.bfs10604('dragenter', to='document.body')
    self.bfs10603 = self.bfs10606('dragover', 'document', interval_msecs=300)
    self.bfs10603.start()

  def bfs10604(self, bfs10610, to):
    (bfs10607, args) = self.bfs10611(bfs10610, to)
    self.driver.execute_script(bfs10607, *args)

  def bfs10606(self, bfs10612, to, interval_msecs):
    (bfs10613, args) = self.bfs10611(bfs10612, to)
    return bfs10615(self.driver, bfs10613, args, interval_msecs)

  def bfs10611(self, bfs10614, to):
    bfs10616 = "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, basestring):
      bfs10616 = bfs10616.replace('arguments[2]', to)
      args = (self.bfs10602, bfs10614)
    else:
      args = (self.bfs10602, bfs10614, to.unwrap())

    return (bfs10616, args)

  def bfs10557(self, target):
    self.bfs10603.stop()
    self.bfs10604('drop', to=target)

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

    self.bfs10602 = None


class bfs10615(object):
  def __init__(self, driver, bfs10617, args, interval_msecs):
    self.driver = driver
    self.bfs10617 = bfs10617
    self.args = args
    self.interval_msecs = interval_msecs
    self.bfs10621 = None

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

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


class bfs10622(object):
  def __init__(self, driver):
    self.bfs10624 = None
    self.bfs10623 = driver

  def find_all(self):
    if self.bfs10625():
      yield self
    else:
      for bfs10626 in self.bfs10627():
        yield self.bfs10631(bfs10626)



  def bfs10625(self):
    return (self.bfs10624 is not None)

  def bfs10627(self):
    raise NotImplementedError()

  def bfs10631(self, bfs10630):
    bfs10632 = copy(self)
    bfs10632.bfs10624 = bfs10630
    return bfs10632

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


  @property
  def first_occurrence(self):
    if (not self.bfs10625()):
      self.bfs10633()

    return self.bfs10624

  def bfs10633(self):
    self.perform((lambda bfs10635: None))

  def perform(self, bfs10400):
    from helium.api import Config
    bfs10634 = (time() + Config.implicit_wait_secs)
    bfs10636 = self.bfs10637(bfs10400)
    while ((bfs10636 is None) and (time() < bfs10634)):
      bfs10636 = self.bfs10637(bfs10400)

    if (bfs10636 is not None):
      return bfs10636

    raise LookupError()

  def bfs10637(self, bfs10400):
    for bfs10641 in self.find_all():
      bfs10640 = bfs10641.first_occurrence
      try:
        bfs10400(bfs10640)
      except Exception, e:
        if self.bfs10642(e):
          continue
        else:
          raise 

      else:
        self.bfs10624 = bfs10640
        return bfs10640



  def bfs10642(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)):
        bfs10106.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 bfs10643(bfs10622):
  def __init__(self, driver, below=None, to_right_of=None, above=None, to_left_of=None):
    super(bfs10643, self).__init__(driver)
    self.below = self.bfs10645(below)
    self.to_right_of = self.bfs10645(to_right_of)
    self.above = self.bfs10645(above)
    self.to_left_of = self.bfs10645(to_left_of)
    self.bfs10644 = bfs10150()

  def bfs10645(self, element):
    if isinstance(element, basestring):
      return TextImpl(self.bfs10623, element)

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

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

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

  @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 bfs10627(self):
    bfs10646 = self.bfs10647()
    for bfs10650 in bfs10416(self.bfs10623):
      for bfs10651 in self.bfs10653():
        if self.bfs10652(bfs10651, bfs10646):
          yield bfs10651




  def bfs10647(self):
    bfs10636 = []
    if self.below:
      bfs10636.append(map((lambda bfs10654: bfs10654.location.is_above), self.below.bfs10627()))

    if self.to_right_of:
      bfs10636.append(map((lambda bfs10656: bfs10656.location.is_to_left_of), self.to_right_of.bfs10627()))

    if self.above:
      bfs10636.append(map((lambda bfs10655: bfs10655.location.is_below), self.above.bfs10627()))

    if self.to_left_of:
      bfs10636.append(map((lambda bfs10657: bfs10657.location.is_to_right_of), self.to_left_of.bfs10627()))

    return bfs10636

  def bfs10652(self, bfs10660, bfs10661):
    return (bfs10660.is_displayed() and self.bfs10662(bfs10660, bfs10661))

  def bfs10662(self, element, bfs10663):
    for bfs10665 in bfs10663:
      bfs10664 = False
      for bfs10666 in bfs10665:
        if bfs10666(element.location):
          bfs10664 = True
          break


      if (not bfs10664):
        return False


    return True

  def bfs10653(self):
    raise NotImplementedError()

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


class SImpl(bfs10643):
  def __init__(self, driver, bfs10667, **bfs10671):
    super(SImpl, self).__init__(driver, **bfs10671)
    self.bfs10667 = bfs10667

  def bfs10653(self):
    wrap = (lambda bfs10672: map(bfs10415, bfs10672))
    if self.bfs10667.startswith('@'):
      return wrap(self.bfs10623.find_elements_by_name(self.bfs10667[1:]))

    if self.bfs10667.startswith('//'):
      return wrap(self.bfs10623.find_elements_by_xpath(self.bfs10667))

    return wrap(self.bfs10623.find_elements_by_css_selector(self.bfs10667))


class bfs10674(bfs10643):
  def bfs10653(self):
    bfs10673 = self.bfs10675()
    bfs10106.debug(('Looking for HTML element using xpath: %s.' % bfs10673))
    return self.bfs10677(map(bfs10415, self.bfs10623.find_elements_by_xpath(bfs10673)))

  def bfs10677(self, bfs10676):
    bfs10700 = []
    for bfs10702 in bfs10676:
      try:
        key = self.bfs10701(bfs10702)
      except StaleElementReferenceException:
        pass
      else:
        bfs10700.append((key, bfs10702))


    bfs10703 = (lambda bfs10705: bfs10705[0])
    bfs10700.sort(key=bfs10703)
    bfs10704 = (lambda bfs10706: bfs10706[1])
    return map(bfs10704, bfs10700)

  def bfs10675(self):
    raise NotImplementedError()

  def bfs10701(self, web_element):
    return (self.bfs10623.bfs10402(web_element) + 1)


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

  def bfs10675(self):
    bfs10710 = (('//' + self.bfs10712()) + predicate(self.bfs10644.bfs10137('.', self.search_text)))
    return ('%s[not(self::script)][not(.%s)]' % (bfs10710, bfs10710))

  def bfs10712(self):
    return '*'


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

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

  def bfs10675(self):
    bfs10713 = [(super(TextImpl, self).bfs10675() + '[not(self::option)]'), ButtonImpl(self.bfs10623, self.search_text).bfs10715(), LinkImpl(self.bfs10623, self.search_text).bfs10675()]
    if self.include_free_text:
      bfs10713.append(bfs10717(self.bfs10623, self.search_text).bfs10675())

    return ' | '.join(bfs10713)


class bfs10717(bfs10707):
  def bfs10712(self):
    return 'text()'

  def bfs10675(self):
    return (super(bfs10717, self).bfs10675() + '/..')


class LinkImpl(bfs10707):
  def bfs10712(self):
    return 'a'

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


class ListItemImpl(bfs10707):
  def bfs10712(self):
    return 'li'


class ButtonImpl(bfs10707):
  def bfs10712(self):
    return 'button'

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

  def bfs10675(self):
    bfs10720 = self.bfs10644.bfs10137('@aria-label', self.search_text)
    bfs10722 = self.bfs10644.bfs10137('.', self.search_text)
    bfs10721 = bfs10143(bfs10720, bfs10722)
    return ' | '.join([super(ButtonImpl, self).bfs10675(), self.bfs10715(), ("//*[@role='button']" + bfs10721), ('//button' + predicate(bfs10720))])

  def bfs10715(self):
    if self.search_text:
      bfs10723 = self.bfs10644.bfs10137('@value', self.search_text)
      bfs10724 = self.bfs10644.bfs10137('@label', self.search_text)
      bfs10725 = self.bfs10644.bfs10137('@aria-label', self.search_text)
      bfs10727 = self.bfs10644.bfs10137('@title', self.search_text)
      bfs10726 = bfs10143(bfs10723, bfs10724, bfs10725, bfs10727)
    else:
      bfs10726 = ''

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


class ImageImpl(bfs10674):
  def __init__(self, driver, alt, **bfs10730):
    super(ImageImpl, self).__init__(driver, **bfs10730)
    self.alt = alt

  def bfs10675(self):
    return ('//img' + predicate(self.bfs10644.bfs10137('@alt', self.alt)))


class bfs10731(bfs10643):
  bfs10733 = 1.5
  def __init__(self, driver, label=None, **bfs10732):
    super(bfs10731, self).__init__(driver, **bfs10732)
    self.label = label

  def bfs10653(self):
    if (not self.label):
      bfs10734 = self.bfs10735()
    else:
      bfs10736 = TextImpl(self.bfs10623, self.label, include_free_text=False).bfs10653()
      if bfs10736:
        bfs10734 = list(self.bfs10740(self.bfs10735(), bfs10736))
      else:
        bfs10734 = self.bfs10737()


    return sorted(bfs10734, key=self.bfs10623.bfs10402)

  def bfs10735(self, bfs10741=None):
    if (bfs10741 is None):
      bfs10741 = self.bfs10675()

    return map(bfs10415, self.bfs10623.find_elements_by_xpath(bfs10741))

  def bfs10737(self):
    bfs10742 = [bfs10137.strip().lstrip('/') for bfs10137 in self.bfs10675().split('|')]
    bfs10744 = ('//text()' + predicate(self.bfs10644.bfs10137('.', self.label)))
    bfs10137 = ' | '.join([(((bfs10744 + '/following::') + bfs10743) + '[1]') for bfs10743 in bfs10742])
    return self.bfs10735(bfs10137)

  def bfs10675(self):
    raise NotImplementedError()

  def bfs10745(self):
    return 'to_right_of'

  def bfs10746(self):
    return 'below'

  def bfs10740(self, bfs10750, bfs10747):
    for (label, bfs10751) in self.bfs10752(bfs10750, bfs10747):
      yield bfs10751
      bfs10747.remove(label)
      bfs10750.remove(bfs10751)

    bfs10754 = self.bfs10753(bfs10750, bfs10747)
    bfs10754 = self.bfs10755(bfs10754)
    self.bfs10756(bfs10754)
    for bfs10757 in bfs10754.values():
      assert (len(bfs10757) <= 1)
      if bfs10757:
        yield next(iter(bfs10757))



  def bfs10752(self, bfs10760, bfs10762):
    for label in bfs10762:
      if (label.tag_name == 'label'):
        bfs10761 = label.get_attribute('for')
        if bfs10761:
          for bfs10763 in bfs10760:
            bfs10765 = bfs10763.get_attribute('id')
            if (bfs10765.lower() == bfs10761.lower()):
              yield (label, bfs10763)






  def bfs10753(self, bfs10764, bfs10766):
    bfs10770 = {}
    for label in bfs10766:
      for bfs10767 in bfs10764:
        if self.bfs10771(bfs10767, label):
          if (label not in bfs10770):
            bfs10770[label] = set()

          bfs10770[label].add(bfs10767)



    return bfs10770

  def bfs10771(self, bfs10772, label):
    if bfs10772.location.bfs10301(label.location):
      return True

    bfs10773 = self.bfs10745()
    bfs10775 = self.bfs10746()
    return ((label.location.bfs10326(bfs10772.location) <= 150) and (bfs10772.location.bfs10316(bfs10773, label.location) or bfs10772.location.bfs10316(bfs10775, label.location)))

  def bfs10755(self, bfs10774):
    bfs10776 = bfs10430(bfs10774)
    self.bfs10756(bfs10776)
    return bfs10430(bfs10776)

  def bfs10756(self, bfs11000):
    for (bfs10777, bfs11001) in bfs11000.items():
      if bfs11001:
        bfs11000[bfs10777] = set([self.bfs11002(bfs10777, bfs11001)])



  def bfs11002(self, bfs11004, bfs11003):
    bfs11005 = iter(bfs11003)
    bfs11007 = next(bfs11005)
    bfs11006 = self.bfs11010(bfs11007, bfs11004)
    for element in bfs11005:
      bfs11012 = self.bfs11010(element, bfs11004)
      if (bfs11012 < bfs11006):
        bfs11007 = element
        bfs11006 = bfs11012


    return bfs11007

  def bfs11010(self, bfs11011, bfs11013):
    bfs11014 = bfs11011.location
    bfs11015 = bfs11013.location
    if bfs11014.bfs10316(self.bfs10746(), bfs11015):
      bfs11016 = self.bfs10733
    else:
      bfs11016 = 1

    return (bfs11016 * bfs11014.bfs10326(bfs11015))


class bfs11020(bfs10643):
  def __init__(self, driver, *args, **bfs10454):
    super(bfs11020, self).__init__(driver, **bfs10454)
    self.args = ([driver] + list(args))
    self.bfs10454 = bfs10454
    self.bfs11017 = None

  @property
  def bfs11021(self):
    if (self.bfs11017 is None):
      self.bfs10633()

    return self.bfs11017

  def find_all(self):
    bfs11023 = []
    for element in self.bfs11022():
      for bfs11024 in element.find_all():
        if (self.bfs11017 is None):
          self.bfs11017 = element

        if (bfs11024 not in bfs11023):
          yield bfs11024
          bfs11023.append(bfs11024)




  def bfs11022(self):
    for bfs11025 in self.bfs11026():
      yield bfs11025(*self.args, **self.bfs10454)


  def bfs11026(self):
    raise NotImplementedError()


class bfs10510(bfs11020):
  def __init__(self, driver, text, **bfs11027):
    super(bfs10510, self).__init__(driver, text, **bfs11027)

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


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

  def bfs11026(self):
    return [bfs11030, bfs11032, bfs11033]

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

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

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


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

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

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

  def bfs10675(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 bfs11033(bfs10731):
  @property
  def value(self):
    return self.first_occurrence.text

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

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

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


class bfs11030(bfs10674):
  def __init__(self, driver, label, **bfs11034):
    super(bfs11030, self).__init__(driver, **bfs11034)
    self.label = label

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

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

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

  def bfs10675(self):
    return ('(%s)%s' % (bfs11032(self.label).bfs10675(), predicate(self.bfs10644.bfs10137('@placeholder', self.label))))


class bfs10562(bfs10731):
  def bfs10675(self):
    return "//input[@type='file']"


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

  def bfs11026(self):
    return [bfs11035, bfs11037]

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

  @property
  def value(self):
    bfs11040 = self.bfs11042.first_selected_option
    if bfs11040:
      return bfs11040.text

    return None

  @property
  def options(self):
    return [bfs11041.text for bfs11041 in self.bfs11042.options]

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


class bfs11035(bfs10731):
  def bfs10675(self):
    return '//select | //input[@list]'


class bfs11037(bfs10707):
  def bfs10712(self):
    return 'option'

  def bfs10675(self):
    bfs11043 = super(bfs11037, self).bfs10675()
    return (bfs11043 + '/ancestor::select[1]')

  def bfs10653(self):
    bfs11044 = super(bfs11037, self).bfs10653()
    bfs11045 = []
    for bfs11047 in bfs11044:
      for bfs11046 in Select(bfs11047.unwrap()).all_selected_options:
        if self.bfs10644.text(bfs11046.text, self.search_text):
          bfs11045.append(bfs11047)
          break



    return bfs11045


class CheckBoxImpl(bfs10731):
  def is_enabled(self):
    return self.bfs10670()

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

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

  def bfs10745(self):
    return 'to_left_of'

  def bfs10746(self):
    return 'to_right_of'


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

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

  def bfs10745(self):
    return 'to_left_of'

  def bfs10746(self):
    return 'to_right_of'


class WindowImpl(bfs10622):
  def __init__(self, driver, title=None):
    super(WindowImpl, self).__init__(driver)
    self.bfs11050 = title

  def bfs10627(self):
    bfs11051 = []
    for handle in self.bfs10623.window_handles:
      window = WindowImpl.bfs11053(self.bfs10623, handle)
      if (self.bfs11050 is None):
        bfs11051.append((0, window))
      else:
        title = window.title
        if title.startswith(self.bfs11050):
          bfs11052 = (len(title) - len(self.bfs11050))
          bfs11051.append((bfs11052, window))



    bfs11052 = (lambda bfs11054: bfs11054[0])
    bfs11051.sort(key=bfs11052)
    for (bfs11052, window) in bfs11051:
      yield window


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

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

  class bfs11053(object):
    def __init__(self, driver, handle):
      self.driver = driver
      self.handle = handle
      self.bfs11056 = None

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


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


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




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

  def bfs10627(self):
    bfs11057 = self.bfs10623.switch_to.alert
    try:
      text = bfs11057.text
      if ((self.search_text is None) or text.startswith(self.search_text)):
        yield bfs11057

    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, e:
      msg = e.msg
      if (msg and re.match('a\\.document\\.getElementsByTagName\\([^\\)]*\\)\\[0\\] is undefined', msg)):
        bfs10106.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 _write(self, text):
    self.first_occurrence.send_keys(text)


