#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2018 Jorge Javier Araya Navarro
# This file is under the MIT License
# Complete text of the license is at LICENSE
"""Set of Selenium helpers.
"""
import re
from random import choice
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from kense import exceptions, wait
_ISBROWSER = re.compile(
r'\<class \'selenium\.webdriver\.\w+\.webdriver\.WebDriver\'\>')
WAIT = 60
_MESSAGE_NOTFOUND = "Control %s cannot be found after %d seconds"
ANY = None
def _getwtext(element):
"""Return the text of HTML tag.
Parameters
----------
element : selenium.webdriver.remote.webelement.WebElement
The HTML tag to extract the text from.
Returns
-------
str
The text inside of the HTML tag.
"""
return element.get_attribute('text') or element.get_attribute(
"innerText") or element.get_attribute("textContent")
def _findanyoption(browser, id_):
"""Choose an option at random.
The option is other than the selected before this helper was run. Do not
use this function directly but instead use `kense.controls.selectdropdown`
with `kense.controls.ANY` for the value parameter.
Parameters
----------
browser : selenium.webdriver.remote.webdriver.WebDriver
The Selenium web driver, the target URL must be loaded
id_ : str
The name of the ID of the HTML tag, avoid suffixing it with #.
Returns
-------
str
The text inside of the HTML tag.
"""
values = browser.find_elements(By.XPATH, "//ul[@id='%s_listbox']/li" % id_)
values = [_getwtext(x) for x in values]
# Find the current selected option
try:
option = browser.find_element(By.XPATH,
"//ul[@id='%s_listbox']/li[@id]" % id_)
except NoSuchElementException:
raise exceptions.OptionNotFound(
"Control select#%s have no options to choose from, is empty." %
id_)
# Remove the current selected option
values.remove(_getwtext(option))
try:
value = choice(values)
except IndexError:
raise exceptions.OptionNotFound(
"Cannot choose other value than %s: not enough options." %
_getwtext(option))
return _findoption(browser, id_, value)
def _findoption(browser, id_, value):
"""Select an specific option.
Parameters
----------
browser : selenium.webdriver.remote.webdriver.WebDriver
The Selenium web driver, the target URL must be loaded
id_ : str
The name of the ID of the <select> HTML tag, avoid
suffixing it with #.
value : str
The option to select represented by the user-redeable text on it.
Returns
-------
str
The text inside of the HTML tag.
"""
# Find the dropdown element in the current page
parent = WebDriverWait(browser, WAIT).until(
message=_MESSAGE_NOTFOUND % ("#" + id_, WAIT),
method=lambda w: w.find_element(By.XPATH, "//*[@id='%s']/.." % id_))
# Interact with the parent
parent.click()
# wait until the animation of the listbox finishes
wait.waitanimation(browser, "%s_listbox" % id_)
try:
setoption = browser.find_element(
By.XPATH,
"//ul[@id='%s_listbox']/li[contains(text(), '%s')]" % (id_, value))
except NoSuchElementException:
raise exceptions.OptionNotFound(
("Option %s was not found for dropdown #%s."
" Check your data and the casing of the value.") % (value, id_))
# Select the option by clicking on it
setoption.click()
# wait until the animation of the listbox finishes
wait.waitanimation(browser, "%s_listbox" % id_)
# Search the new selected option and returns its text content
option = browser.find_element(By.XPATH,
"//ul[@id='%s_listbox']/li[@id]" % id_)
return _getwtext(option)
[docs]def selectdropdown(browser, id_, value):
"""Select option from kendoDropDownList.
Parameters
----------
browser : selenium.webdriver.remote.webdriver.WebDriver
The Selenium web driver, the target URL must be loaded
id_ : str
The name of the ID of the <select> HTML tag, avoid
suffixing it with #.
value : str or kense.controls.ANY
The option to select represented by the user-redeable text on it,
use `kense.controls.ANY` to choose an option at random.
Returns
-------
str
The text inside of the HTML tag.
"""
# Check if browser is a valid webdriver
browsertype = str(type(browser))
if not _ISBROWSER.match(browsertype):
raise ValueError( # pragma: no cover
"browser parameter of type %s not valid, expected webdriver." %
browsertype)
# Check if selector is a valid string
if not isinstance(id_, str):
raise ValueError( # pragma: no cover
"selector parameter of type %s not valid, expected str." %
type(id_))
if value == ANY:
return _findanyoption(browser, id_)
return _findoption(browser, id_, value)