from bfs.bfs10101.bfs10102 import bfs10104
from copy import copy
from decorator import decorator
from errno import ESRCH as bfs10327, EACCES as bfs10326
from helium.bfs10114.bfs10116 import bfs10117
from helium.bfs10114.bfs10132 import bfs10137
from helium.bfs10101.bfs10102 import bfs10140
from helium.bfs10101.bfs10147 import bfs10174, bfs10175
from helium.bfs10275 import bfs10312, bfs10276, bfs10313
from helium.bfs10060.bfs10323 import bfs10322
from helium.bfs10060.bfs10324 import bfs10325
from helium.bfs10060.system import bfs10122, bfs10123, bfs10124, bfs10130, bfs10125
from helium.bfs10060.bfs10107 import lower, predicate, bfs10115
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
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
@decorator
def bfs10333(bfs10030, self, *args, **bfs10066):
  if (self.driver.bfs10306() and AlertImpl(self.driver).exists()):
    return bfs10030(self, *args, **bfs10066)

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


  return bfs10063

@decorator
def bfs10334(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, bfs10335, bfs10337, bfs10336=None):
    self.bfs10335 = bfs10335
    self.license = bfs10337
    self.bfs10336 = bfs10336
    self.driver = None

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

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


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

    bfs10137()
    bfs10344 = Chrome(**bfs10066)
    atexit.register((lambda : self.bfs10346(bfs10344.service)))
    return self.bfs10340(bfs10344, url)

  def bfs10343(self):
    if bfs10122():
      bfs10351 = 'chromedriver.exe'
    elif bfs10123():
      bfs10351 = ('chromedriver' + ('_x64' if bfs10130() else '')
)
    else:
      assert bfs10124()
      bfs10351 = 'chromedriver'

    return self.bfs10335.bfs10350(bfs10125(), 'webdrivers', bfs10351)

  def bfs10346(self, service):
    if hasattr(service, 'process'):
      try:
        service.process.kill()
      except OSError, e:
        if (e.errno not in (bfs10327, bfs10326)):
          raise 




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

    bfs10354 = Ie(**bfs10066)
    atexit.register((lambda : self.bfs10346(bfs10354.iedriver)))
    return self.bfs10340(bfs10354, url)

  def bfs10340(self, bfs10355, url=None):
    try:
      self.bfs10357(bfs10355)
    except bfs10104:
      bfs10355.quit()
      raise 

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

    return self.bfs10360()

  @bfs10333
  @bfs10334
  def bfs10356(self, url):
    if ('://' not in url):
      url = ('http://' + url)

    self.driver.get(url)

  def bfs10357(self, driver):
    self.bfs10361(driver)
    self.driver = bfs10276(driver)

  def bfs10361(self, driver):
    try:
      self.license.bfs10362(bfs10174(self.bfs10336))
    except bfs10140:
      try:
        self.license.bfs10362(bfs10175(self.bfs10336, driver))
      except bfs10140:
        raise bfs10104('Unfortunately, Helium could not verify your license key. Please activate your internet connection and try again.')



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


  @bfs10333
  @bfs10334
  def bfs10366(self, text, into=None):
    if (into is not None):
      from helium.api import GUIElement
      if isinstance(into, GUIElement):
        into = into.bfs10364


    self.bfs10363(self.bfs10365, self.bfs10367, text, into=into)

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

      def bfs10371(bfs10370):
        if (hasattr(bfs10370, 'clear') and callable(bfs10370.clear)):
          bfs10370.clear()

        bfs10370.send_keys(text)

      self.bfs10372(into, bfs10371)
    else:
      self.driver.switch_to.active_element.send_keys(text)


  def bfs10367(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.bfs10371(text)

  def bfs10363(self, bfs10373, bfs10374, *args, **bfs10066):
    if (self.driver.bfs10304() or (not AlertImpl(self.driver).exists())):
      try:
        return bfs10373(*args, **bfs10066)
      except UnexpectedAlertPresentException:
        if (self.driver.bfs10304() 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 bfs10374(*args, **bfs10066)

  @bfs10333
  @bfs10334
  def bfs10376(self, key):
    self.driver.switch_to.active_element.send_keys(key)

  def bfs10400(self, element):
    element = self.bfs10375(element)
    click = (lambda bfs10370: bfs10370.click())
    self.bfs10377(element, click, click)

  def bfs10375(self, bfs10370):
    from helium.api import HTMLElement
    if isinstance(bfs10370, basestring):
      bfs10370 = bfs10401(self.driver, bfs10370)
    elif isinstance(bfs10370, HTMLElement):
      bfs10370 = bfs10370.bfs10364

    return bfs10370

  @bfs10333
  @bfs10334
  def bfs10377(self, element, bfs10402, bfs10404):
    offset = None
    from helium.api import Point
    if isinstance(element, Point):
      (element, offset) = self.bfs10403(element)

    if (offset is not None):
      bfs10301 = (lambda bfs10370: bfs10404(self.driver.bfs10301().move_to_element_with_offset(bfs10370, *offset)).perform())
    else:
      bfs10301 = (lambda bfs10370: bfs10402(bfs10370))

    self.bfs10372(element, bfs10301)

  def bfs10403(self, bfs10226):
    element = bfs10312(self.driver.execute_script(('return document.elementFromPoint(%r, %r);' % (bfs10226.x, bfs10226.y))))
    offset = (bfs10226 - (element.location.bfs10201, element.location.bfs10202))
    if ((offset == (0, 0)) and self.driver.bfs10304()):
      offset = (1, 1)

    return (element, offset)

  def bfs10405(self, element):
    element = self.bfs10375(element)
    self.bfs10377(element, (lambda bfs10370: self.driver.bfs10301().double_click(bfs10370).perform()), (lambda bfs10301: bfs10301.double_click()))

  def bfs10411(self, element, to):
    self.bfs10406(element)
    self.bfs10407(to)

  def bfs10406(self, element):
    element = self.bfs10375(element)
    self.bfs10377(element, (lambda bfs10370: self.driver.bfs10301().click_and_hold(bfs10370).perform()), (lambda bfs10301: bfs10301.click_and_hold()))

  def bfs10407(self, element):
    element = self.bfs10375(element)
    self.bfs10377(element, (lambda bfs10370: self.driver.bfs10301().move_to_element(bfs10370).release().perform()), (lambda bfs10301: bfs10301.release()))

  @bfs10334
  def bfs10413(self, predicate):
    return [predicate.bfs10410(bfs10412) for bfs10412 in predicate.bfs10364.find_all()]

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

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

  def bfs10420(self, num_pixels):
    self.bfs10415(num_pixels, 0)

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

  @bfs10334
  def bfs10415(self, bfs10421, bfs10423):
    self.driver.execute_script('window.scrollBy(arguments[0], arguments[1]);', bfs10421, bfs10423)

  def bfs10422(self, element):
    element = self.bfs10375(element)
    self.bfs10377(element, (lambda bfs10370: self.driver.bfs10301().move_to_element(bfs10370).perform()), (lambda bfs10301: bfs10301))

  def bfs10424(self, element):
    element = self.bfs10375(element)
    self.bfs10377(element, (lambda bfs10370: self.driver.bfs10301().context_click(bfs10370).perform()), (lambda bfs10301: bfs10301.context_click()))

  @bfs10333
  @bfs10334
  def bfs10427(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.bfs10364

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

    self.bfs10372(combo_box, bfs10425)

  def bfs10372(self, bfs10426, bfs10301):
    if (hasattr(bfs10426, 'perform') and callable(bfs10426.perform)):
      self.driver.bfs10300 = bfs10426.perform(bfs10301)
    else:
      if isinstance(bfs10426, WebElement):
        bfs10426 = bfs10312(bfs10426)

      bfs10301(bfs10426)
      self.driver.bfs10300 = bfs10426


  @bfs10334
  def bfs10433(self, file_path, to):
    to = self.bfs10375(to)
    drag_and_drop = bfs10430(self.driver, file_path)
    drag_and_drop.begin()
    try:
      drag_and_drop.bfs10432()
      self.bfs10372(to, (lambda bfs10370: drag_and_drop.bfs10431(bfs10370)))
    finally:
      drag_and_drop.end()


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

    bfs10434 = (lambda bfs10370: bfs10370.send_keys(file_path))
    self.bfs10377(to, bfs10434, bfs10434)

  def bfs10441(self):
    self.bfs10363(self.bfs10440, self.bfs10437)

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

  def bfs10437(self):
    AlertImpl(self.driver).accept()
    self.bfs10440()

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

      bfs10443 = getargspec(condition_fn).args
      bfs10444 = len(bfs10443)

    bfs10112 = (condition_fn if bfs10444 else (lambda driver: condition_fn()))

    wait = WebDriverWait(self.bfs10360(), timeout_secs, poll_frequency=interval_secs)
    wait.until(bfs10112)

  @bfs10334
  def bfs10447(self, window):
    from helium.api import Window
    if isinstance(window, basestring):
      window = WindowImpl(self.driver, window)
    elif isinstance(window, Window):
      window = window.bfs10364

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

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

  @bfs10334
  def bfs10452(self, element):
    from helium.api import HTMLElement
    if isinstance(element, HTMLElement):
      element = element.bfs10364

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

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

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


class bfs10430(object):
  def __init__(self, driver, file_path):
    self.driver = driver
    self.file_path = file_path
    self.bfs10451 = None
    self.bfs10453 = None

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


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

  def bfs10456(self, bfs10457, to):
    (bfs10461, args) = self.bfs10460(bfs10457, to)
    self.driver.execute_script(bfs10461, *args)

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

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

    return (bfs10461, args)

  def bfs10431(self, target):
    self.bfs10453.stop()
    self.bfs10456('drop', to=target)

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

    self.bfs10451 = None


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

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

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


class bfs10465(object):
  def __init__(self, driver):
    self.bfs10466 = None
    self.bfs10467 = driver

  def find_all(self):
    if self.bfs10471():
      yield self
    else:
      for bfs10470 in self.bfs10472():
        yield self.bfs10473(bfs10470)



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

  def bfs10472(self):
    raise NotImplementedError()

  def bfs10473(self, bfs10470):
    bfs10063 = copy(self)
    bfs10063.bfs10466 = bfs10470
    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.bfs10471()):
      self.bfs10474()

    return self.bfs10466

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

  def perform(self, bfs10301):
    from helium.api import Config
    bfs10476 = (time() + Config.implicit_wait_secs)
    bfs10063 = self.bfs10475(bfs10301)
    while ((bfs10063 is None) and (time() < bfs10476)):
      bfs10063 = self.bfs10475(bfs10301)

    if (bfs10063 is not None):
      return bfs10063

    raise LookupError()

  def bfs10475(self, bfs10301):
    for bfs10412 in self.find_all():
      bfs10470 = bfs10412.first_occurrence
      try:
        bfs10301(bfs10470)
      except Exception, e:
        if self.bfs10477(e):
          continue
        else:
          raise 

      else:
        self.bfs10466 = bfs10470
        return bfs10470



  def bfs10477(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 bfs10500(bfs10465):
  def __init__(self, driver, below=None, to_right_of=None, above=None, to_left_of=None):
    super(bfs10500, self).__init__(driver)
    self.below = self.bfs10501(below)
    self.to_right_of = self.bfs10501(to_right_of)
    self.above = self.bfs10501(above)
    self.to_left_of = self.bfs10501(to_left_of)
    self.bfs10503 = bfs10117()

  def bfs10501(self, element):
    if isinstance(element, basestring):
      return TextImpl(self.bfs10467, element)

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

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

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

  @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 bfs10472(self):
    bfs10502 = self.bfs10504()
    for bfs10070 in bfs10313(self.bfs10467):
      for bfs10470 in self.bfs10506():
        if self.bfs10505(bfs10470, bfs10502):
          yield bfs10470




  def bfs10504(self):
    bfs10063 = []
    if self.below:
      bfs10063.append(map((lambda bfs10370: bfs10370.location.is_above), self.below.bfs10472()))

    if self.to_right_of:
      bfs10063.append(map((lambda bfs10370: bfs10370.location.is_to_left_of), self.to_right_of.bfs10472()))

    if self.above:
      bfs10063.append(map((lambda bfs10370: bfs10370.location.is_below), self.above.bfs10472()))

    if self.to_left_of:
      bfs10063.append(map((lambda bfs10370: bfs10370.location.is_to_right_of), self.to_left_of.bfs10472()))

    return bfs10063

  def bfs10505(self, bfs10470, bfs10502):
    return (bfs10470.is_displayed() and self.bfs10507(bfs10470, bfs10502))

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


      if (not bfs10510):
        return False


    return True

  def bfs10506(self):
    raise NotImplementedError()

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


class SImpl(bfs10500):
  def __init__(self, driver, bfs10515, **bfs10066):
    super(SImpl, self).__init__(driver, **bfs10066)
    self.bfs10515 = bfs10515

  def bfs10506(self):
    wrap = (lambda bfs10514: map(bfs10312, bfs10514))
    if self.bfs10515.startswith('@'):
      return wrap(self.bfs10467.find_elements_by_name(self.bfs10515[1:]))

    if self.bfs10515.startswith('//'):
      return wrap(self.bfs10467.find_elements_by_xpath(self.bfs10515))

    return wrap(self.bfs10467.find_elements_by_css_selector(self.bfs10515))


class bfs10516(bfs10500):
  def bfs10506(self):
    bfs10517 = self.bfs10520()
    getLogger(__name__).debug('Looking for HTML element using xpath: %s.', bfs10517)
    return self.bfs10521(map(bfs10312, self.bfs10467.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 bfs10256: bfs10256[0])
    bfs10522.sort(key=bfs10527)
    bfs10526 = (lambda bfs10256: bfs10256[1])
    return map(bfs10526, bfs10522)

  def bfs10520(self):
    raise NotImplementedError()

  def bfs10525(self, web_element):
    return (self.bfs10467.bfs10302(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.bfs10503.bfs10107('.', 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.bfs10467, self.search_text).bfs10533(), LinkImpl(self.bfs10467, self.search_text).bfs10520()]
    if self.include_free_text:
      bfs10534.append(bfs10535(self.bfs10467, 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.bfs10503.bfs10107('@title', self.search_text))) + ' | ') + "//*[@role='link']") + predicate(self.bfs10503.bfs10107('.', 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.bfs10513() and ((not bfs10536) or (bfs10536.lower() == 'false')))

  def bfs10520(self):
    bfs10540 = self.bfs10503.bfs10107('@aria-label', self.search_text)
    bfs10537 = self.bfs10503.bfs10107('.', self.search_text)
    bfs10541 = bfs10115(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.bfs10503.bfs10107('@value', self.search_text)
      bfs10542 = self.bfs10503.bfs10107('@label', self.search_text)
      bfs10540 = self.bfs10503.bfs10107('@aria-label', self.search_text)
      bfs10544 = self.bfs10503.bfs10107('@title', self.search_text)
      bfs10537 = bfs10115(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.bfs10503.bfs10107('@alt', self.alt)))


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

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


    return sorted(bfs10063, key=self.bfs10467.bfs10302)

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

    return map(bfs10312, self.bfs10467.find_elements_by_xpath(bfs10107))

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

  def bfs10520(self):
    raise NotImplementedError()

  def bfs10554(self):
    return 'to_right_of'

  def bfs10556(self):
    return 'below'

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

    bfs10561 = self.bfs10562(bfs10560, bfs10550)
    bfs10561 = self.bfs10563(bfs10561)
    self.bfs10565(bfs10561)
    for bfs10564 in 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 bfs10370 in bfs10560:
            bfs10567 = bfs10370.get_attribute('id')
            if (bfs10567.lower() == bfs10566.lower()):
              yield (label, bfs10370)






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

          bfs10063[label].add(bfs10370)



    return bfs10063

  def bfs10571(self, bfs10370, label):
    if bfs10370.location.bfs10234(label.location):
      return True

    bfs10570 = self.bfs10554()
    bfs10572 = self.bfs10556()
    return ((label.location.bfs10255(bfs10370.location) <= 150) and (bfs10370.location.bfs10246(bfs10570, label.location) or bfs10370.location.bfs10246(bfs10572, label.location)))

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

  def bfs10565(self, bfs10574):
    for (bfs10576, bfs10575) in 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.bfs10246(self.bfs10556(), bfs10611):
      bfs10612 = self.bfs10545
    else:
      bfs10612 = 1

    return (bfs10612 * bfs10607.bfs10255(bfs10611))


class bfs10613(bfs10500):
  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.bfs10474()

    return self.bfs10615

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

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




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


  def bfs10620(self):
    raise NotImplementedError()


class bfs10401(bfs10613):
  def __init__(self, driver, text, **bfs10066):
    super(bfs10401, 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.bfs10513()

  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.bfs10513()

  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.bfs10513()

  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.bfs10503.bfs10107('@placeholder', self.label))))


class bfs10435(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 bfs10506(self):
    bfs10633 = super(bfs10626, self).bfs10506()
    bfs10063 = []
    for bfs10635 in bfs10633:
      for bfs10634 in Select(bfs10635.unwrap()).all_selected_options:
        if self.bfs10503.text(bfs10634.text, self.search_text):
          bfs10063.append(bfs10635)
          break



    return bfs10063


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

  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(bfs10465):
  def __init__(self, driver, title=None):
    super(WindowImpl, self).__init__(driver)
    self.bfs10636 = title

  def bfs10472(self):
    bfs10637 = []
    for handle in self.bfs10467.window_handles:
      window = WindowImpl.bfs10641(self.bfs10467, 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 bfs10256: bfs10256[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(bfs10465):
  def __init__(self, driver, search_text=None):
    super(AlertImpl, self).__init__(driver)
    self.search_text = search_text

  def bfs10472(self):
    bfs10063 = self.bfs10467.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, 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 bfs10371(self, text):
    self.first_occurrence.send_keys(text)


