getting 'attribute error while using tuple arguments python selenium - python

I am trying to "until(EC.visibility_of_element_located" function in my method.But getting error like this,what is the reason ?
by = (<selenium.webdriver.chrome.webdriver.WebDriver (session="0df329cbca657f67360d8fa26fc0ca1c")>, ('xpath', "//div[#title='Kapat'])"))
def _find_element(driver, by):
"""Looks up an element. Logs and re-raises ``WebDriverException``
if thrown."""
try:
> return driver.find_element(*by)
E AttributeError: 'BasePage' object has no attribute 'find_element'
Here is my code,BasePage.py::
def click(driver,*by_locator):
WebDriverWait(driver, 60) .until(EC.visibility_of_element_located(by_locator)).click()
and I am calling this function:
driver = webdriver.Chrome()
driver.get("https://www.trendyol.com/")
driver.maximize_window()
website_is_up_and_running("https://www.trendyol.com/")
time.sleep(5)
bp.click(driver, (By.XPATH,"//div[#title='Kapat'])"))

Related

Python Selenium find_element_by_id with default if not found

I would like to find an element on the page by id. The issue is that this element is only temporary and will not exist all of the time. Therefore I would like to set the default value so I can check for it in a conditional like so:
covidPopUp = driver.find_element_by_id("sgpb-popup-dialog-main-
div").extract(default='not-found')
if(covidPopUp == 'not-found'):
load_more_btn = driver.find_element_by_id("load_more_button")
load_more_btn.click()
else:
popUpClose = driver.find_element_by_id("sgpb-popup-close-button-6")
popUpClose.click()
However, this produces the following error:
AttributeError: 'WebElement' object has no attribute 'extract'
I think you have a couple of options.
Use find_element_by_id but catch the exception
from selenium.common.exceptions import NoSuchElementException
try:
covidPopUp = driver.find_element_by_id("sgpb-popup-dialog-main-div")
except NoSuchElementException:
covidPopUp = "not-found"
Use find_elements_by_id (note plural) and check if list is not empty.
covidPopUp = driver.find_elements_by_id("sgpb-popup-dialog-main-div")
covidPopUp = covidPopUp[0] if covidPopUp else "not-found"

InvalidArgumentException: Message: invalid argument: 'using' must be a string

im very new to python, trying to create reusable code. when i try to call the class Login and function login_user in test_main.py by passing all the arguments that were used under Login class, im getting an error as InvalidArgumentException: Message: invalid argument: 'using' must be a string.
test_main.py file which runs on pytest.
Locators_test is the class of test_Locators.py file where i have all my xpaths
test_Locators.py
class Locators_test():
loginlink_xpath = "//a[#id='login-link']"
login_email = "xxxxx"
login_password = "xxxxx"
loginemail_id = "dnn_ctr1179_Login_txtEmail"
loginpassword_id = "dnn_ctr1179_Login_txtPassword"
clicklogin_id = "dnn_ctr1179_Login_btnLogin"
test_login.py
from Smoketest.locatorfile.test_Locators import Locators_test
class Login():
def __init__(self,driver):
self.driver = driver
def login_user(self,driver):
try:
loginButton = self.driver.find_element((By.XPATH, Locators_test.loginlink_xpath))
while loginButton.click() is True:
break
time.sleep(3)
self.driver.execute_script("window.scrollBy(0,300);")
EmailField = self.driver.find_element((By.ID, Locators_test.loginemail_id))
EmailField.send_keys(Locators_test.login_email)
PasswordField = self.driver.find_element((By.ID, Locators_test.loginpassword_id))
PasswordField.send_keys(Locators_test.login_password)
ClickLogin = self.driver.find_element((By.ID, Locators_test.clicklogin_id))
while ClickLogin.click() is True:
break
time.sleep(5)
userName = self.driver.find_element((By.XPATH, Locators_test.username_xpath))
print("Logged in as", userName.text)
except StaleElementReferenceException or ElementClickInterceptedException or TimeoutException as ex:
print(ex.message)
test_main.py
def test_setup():
driver = webdriver.Chrome(executable_path= Locators_test.browser_path)
driver.maximize_window()
driver.delete_all_cookies()
driver.get(homePage)
driver.implicitly_wait(5)
yield
print("test complete")
def test_login(test_setup):
from Smoketest.pages.test_login import Login
lo = Login(driver)
lo.login_user(((Locators_test.loginlink_xpath,Locators_test.loginemail_id,Locators_test.login_email,Locators_test.loginpassword_id,Locators_test.login_password,Locators_test.clicklogin_id,Locators_test.username_xpath)))
indentations are all fine
I fixed it myself by removing the extra pair of parenthesis from the line
loginButton = self.driver.find_element((By.XPATH, Locators_test.loginlink_xpath))
Right way is
loginButton = self.driver.find_element(By.XPATH, Locators_test.loginlink_xpath)
ps: this applies to all the lines.
This worked for me,
locator = (By.XPATH, Locators_test.loginlink_xpath)
self.driver.find_element(*locator).click()
Explanation: In *<arguments>, all positional arguments other than the first one will be packed in a tuple, as they won't get Changed, the exact property will be reflected in the second step.

Trouble verifying text is present in a div with Selenium/Python

So I am trying to verify text is an element, basically I'm testing what happens when no search results are found. However I'm getting the following error message every time and I cannot figure out why.
Traceback (most recent call last):
File "test.py", line 40, in test_article_no_result_search
assert article_results_page.is_articles_not_found(), "Articles found surprisingly."
File "/Users/tester/Documents/Automated Tests/foobar/page.py", line 71, in is_articles_not_found
return "No Results Available" in element.get_attribute("value")
TypeError: argument of type 'NoneType' is not iterable
HTML element I'm trying to verify
<div class="simple-div results-num-span" data-node="group_0.SimpleDiv_0">No Results Available</div>
Here is my test case from test.py
class SearchTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.get(TestingURLS.URL)
def test_article_no_result_search(self):
main_page = MainPage(self.driver)
main_page.load_page()
main_page.click_article_search_input_clear()
main_page.enter_no_result_search_term()
main_page.click_article_search_button()
article_results_page = ArticleResultsPage(self.driver)
article_results_page.load_page()
assert article_results_page.is_articles_not_found(), "Articles found surprisingly."
def tearDown(self):
self.driver.quit
Relevant function in page.py
def is_articles_not_found(self):
element = self.driver.find_element(*SearchResultLocators.UPPER_RESULT_DISPLAY)
return "No Results Available" in element.get_attribute("value")
Relevant locator from locators.py
class SearchResultLocators(object):
UPPER_RESULT_DISPLAY = (By.CSS_SELECTOR, "div.simple-div.results-num-span")
RESULT_COUNT = (By.CSS_SELECTOR, "div.num-shown")
FIRST_ARTICLE_RESULT = (By.CSS_SELECTOR, "div.result")
element.get_attribute("value") can be applied to input nodes of type "text". In your case it is div with child text node, so you can perform below assertion:
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.common.exceptions import TimeoutException
def is_articles_not_found(self):
element = self.driver.find_element(*SearchResultLocators.UPPER_RESULT_DISPLAY)
try:
return wait(self.driver, 3).until(lambda driver: element.text == "No Results Available")
except TimeoutException:
return False

using Enum to build locator for selenium test

I come out one question about selenium web test. Since all elements require their own xpath or css selector to be action by selenium webdriver.
I have tried to use python Enum and create something like
file: elementEnum.py
from enum import Enum
class PageA(Enum):
pElementA = '//div[{}]'
pElementB = '//a[.="{}"]'
pElementC = '//div[#class={}]'
class PageB(Enum):
pElementA = '//button[.="{}""]'
pElementB = '//table/tr[{}]/td[{}]'
but it turns out lots of time I require to build the string in python format function and it does not see pythonoic.
from elementEnum import *
driver.find_element_by_xpath('//div[#class="aaaaaa"]/{}'.format((PageA.pElementA.value).format(1)))
driver.find_element_by_xpath('{}/{}'.format(PageA.pElementA.value).format(1), PageA.pElementB.value.format(2)))
driver.find_element_by_xpath('{}/{}'.format(PageB.pElementB.value).format(1, 3), PageA.pElementA.value.format(2)))
What is the best way for me to list out all corresponse element and their locator.
you could use the
EC.visibility_of_element_located to locate the element
http://selenium-python.readthedocs.io/waits.html
sample code :
class SeleniumBaseClass(object):
def __init__(self,driver):
self.driver = driver
def open(self,URL):
self.driver.get(URL)
def driverURLChange(self,URL):
print("change URL" + URL)
self.driver.get(URL)
def currentUrl(self):
print("URL " + self.driver.current_url)
return self.driver.current_url
def switchNewWindow(self):
self.driver.switch_to_window(self.driver.window_handles[1])
return self.driver.title
def locateElement(self, loc):
try:
print(loc)
element = WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc))
return element
except:
print ("cannot find {0} element".format(loc))
return None
and you could
password_loc =(By.NAME,'password')
webdriver = SeleniumBaseClass(driver)
webdriver.locateElement(password_loc )
this could you pass the tuple to locate the element

selenium python stuck on this line

Why does my code:
self.driver.find_element_by_xpath("//*[text()[contains(.,'%s')]]" % ('Sorry'))
Get stuck and won't pass this line? Even if I do something like:
driver.implicitly_wait(30)
self.driver.find_element_by_xpath("//*[text()[contains(.,'%s')]]" % ('Sorry'))
Complete code:
# gets stuck here
if self.is_text_present('Hello'):
print 'Hello'
# rest of code
def is_text_present(self, text):
try:
self.driver.find_element_by_xpath('//*[contains(text(), "%s")]' % (text))
except NoSuchElementException, e:
return False
return True
Your XPath can be simplified to
"//*[contains(text(),'%s')]" % ('Sorry')
Perhaps try something like:
import contextlib
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui
with contextlib.closing(webdriver.Firefox()) as driver:
...
# Set up a WebDriverWait instance that will poll for up to 10 seconds
wait = ui.WebDriverWait(driver, 10)
# wait.until returns the value of the callback
elt = wait.until(
lambda driver: driver.find_element_by_xpath(
"//*[contains(text(),'%s')]" % ('Sorry')
))
From the docs:
This waits up to 10 seconds before throwing a TimeoutException or if
it finds the element will return it in 0 - 10 seconds.
To debug the problem you might try saving the HTML source to a file right before calling find_element_by_xpath so you can see what the driver is seeing. Is the XPath valid for that HTML?.
def is_text_present(self, text):
with open('/tmp/debug.html', 'w') as f:
time.sleep(5) # crude, but perhaps effective enough for debugging here.
f.write(driver.page_source)
try:
self.driver.find_element_by_xpath('//*[contains(text(), "%s")]' % (text))
except NoSuchElementException, e:
return False
return True

Categories

Resources