How to while loop exception in Python - python

Someone said to me that I need to convert my code below to while or for loops.
driver.switch_to_window(driver.window_handles[1])
def edit_button(max_sec=10):
try:
WebDriverWait(driver, 1).until(EC.element_to_be_clickable(
(By.XPATH, "//button[contains(text(),'Edit')]")))
print("detected")
except:
driver.refresh()
max_sec -= 1
print(max_sec)
if max_sec == 0:
driver.close()
driver.switch_to_window(driver.window_handles[0])
print("not detected")
edit_button(max_sec)
edit_button()
The code above means that if edit button is not detected, then refresh until it appears for maximum of 10 seconds.
I tried to convert it to while loops, but it shows EXCEPTION ERROR. because this is not detected:
WebDriverWait(driver, 1).until(EC.element_to_be_clickable(
(By.XPATH, "//button[contains(text(),'Edit')]")))
Here is my while loop:
max_sec = 10
while not WebDriverWait(driver, 1).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Edit')]"))):
driver.refresh()
max_sec -= 1
print(max_sec)
if max_sec == 0:
driver.close()
driver.switch_to_window(driver.window_handles[0])
sys.exit()
print("success")
How to make something like this:
while element is exception:
Thanks sorry I am new to Python.

You could change loop condition and catch exception normally with try/except inside loop.
Here is the example:
seconds_left = 10
while seconds_left != 0:
try:
WebDriverWait(driver, 1).until(
EC.element_to_be_clickable(
(By.XPATH, "//button[contains(text(),'Edit')]"),
),
)
break
except:
seconds_left -= 1
driver.refresh()
if seconds_left == 0:
driver.close()
driver.switch_to_window(driver.window_handles[0])
sys.exit()
print("success")

Related

Scroll not working in python selenium code

I wrote the code like this.
However, if there is an element of the conditional statement, after clicking, scrolling is operated on the website. It does not work and there is no error code.
The upper code outside the conditional statement works. What's the reason ?
count = 0
while count < 10:
try:
element = driver.find_element_by_css_selector('a.txt.elss[href="' + self.URL_input.text() + '"]')
time.sleep(2)
print(self.URL_input.text())
element.click()
time.sleep(10)
for i in range(0, 10000,10):
driver.execute_script("window.scrollTo(0, {})".format(i))
self.output_box.insertPlainText("1.\n")
QApplication.processEvents()
random_delay = random.uniform(5, 10)
#driver.quit()
break
except selenium.common.exceptions.NoSuchElementException:
element = driver.find_element_by_css_selector('a.btn_next')
time.sleep(2)
element.click()
time.sleep(2)
count += 1
self.output_box.insertPlainText("10.\n")
QApplication.processEvents()
time.sleep(5)
self.output_box.insertPlainText("end.\n")
def scroll_down():
driver.execute_script("window.scrollBy(0, 50);")
scroll_time = random.uniform(2, 5)
start_time = time.time()
while True:
scroll_down()
time.sleep(0.3) # 1
#
elapsed_time = time.time() - start_time
if elapsed_time >= scroll_time:
break
self.output_box.insertPlainText("\n" + formatted_now + " End!!.")
QApplication.processEvents() #
driver.quit()

How to run a piece of code when an element is present in selenium python?

Here's my code:
for x in range(10):
qtitle = (WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//*[#id='prompt-row']/div/div"))).text)
if qtitle == en1:
driver.find_element_by_xpath("//*[#id='boxes']/div/div[4]/input").send_keys(fr1)
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
elif qtitle == en2:
driver.find_element_by_xpath("//*[#id='boxes']/div/div[4]/input").send_keys(fr2)
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
qtitle = (WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//*[#id='prompt-row']/div/div"))).text)
if qtitle == en1:
driver.find_element_by_name(fr1).click()
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
elif qtitle == en2:
driver.find_element_by_name(fr2).click()
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
I want to run the first block of code only when a specific element is present on the website, and same with the second block. So, for example, when the code detects that [element1] is present it will run the first block of code, whilst when [element2] is present it will run the code below it. Is there a way to do this? I thought about using WebDriverWait, so the code would look like this:
for x in range(10):
WebDriverWait(driver, 20).until(EC.visisbility_of_element_located((By.XPATH, "element1 xpath")))
qtitle = (WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//*[#id='prompt-row']/div/div"))).text)
if qtitle == en1:
driver.find_element_by_xpath("//*[#id='boxes']/div/div[4]/input").send_keys(fr1)
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
elif qtitle == en2:
driver.find_element_by_xpath("//*[#id='boxes']/div/div[4]/input").send_keys(fr2)
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
WebDriverWait(driver, 20).until(EC.visisbility_of_element_located((By.XPATH, "element2 xpath")))
qtitle = (WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//*[#id='prompt-row']/div/div"))).text)
if qtitle == en1:
driver.find_element_by_name(fr1).click()
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
elif qtitle == en2:
driver.find_element_by_name(fr2).click()
driver.find_element_by_xpath("//*[#id='prompt-area']/button").click()
time.sleep(1)
But it just ends up waiting for [element1] to be located because it works top to bottom. Any help solving this problem would be appreciated.
lets say you have page html source like this,
<div class='parent'>
<div class='child1'> </div>
<div class='child2'> </div>
<div class='child3'> </div>
</div>
You can dynamically check what type of child nodes present in the html.
parent = WebDriverWait(driver,5).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='parent']")))
val = "None"
#now find all the child elements in the parent
for child in parent.find_elements(By.XPATH('*')):
val = child.get_attribute("class or id or name")
if val == 'child1':
#Execute your block of code
elif val == "Child2":
#Execute your block of code

How do I optimize my code with try statement?

I have a problem that it takes a long time to execute the code that follows the try. It can be up to 10 seconds. Can you think of any optimization?
try:
error_message = WebDriverWait(self.driver, timeout=0).until(EC.visibility_of_element_located(
(By.XPATH, "/html/body/div[1]/div[2]/div/div/div[1]/span[2]")))
assert error_message.text == "Invalid username or password."
print("3")
print("Invalid username or password.")
self.driver.find_element_by_id("username").clear()
except TimeoutException:
print(time.time(), "3")
I put the part of code for initializing the web drive. Maybe here is something wrong what do it wait in try long time.
def setUp(self):
p_test = Logintest()
self.driver = webdriver.Firefox()
self.driver.get("https://localhost/spcssd")
print("TC_S_F.IA.AD001_tEST")
delay = 20 # seconds
# assert "Log in to spcssd" in self.driver.title
try:
element_present = WebDriverWait(self.driver, delay).until(EC.presence_of_element_located((By.ID, "kc-info")))
print("Page is ready!")
except TimeoutException:
print("Loading took too much time!")

return to first function() at the end of last function()

If you scroll to the bottom of below; I am trying to return to the first function at the end of my last function using process_records()
. My attempt returns Undefined variable 'process_records'pylint(undefined-variable)
def process_records(self, records, map_data, completed=None, errors=None):
"""Code to execute after webdriver initialization."""
series_not_null = False
try:
num_attempt = 0
for record in records.itertuples(): # not working
print(record)
series_not_null = True
self.navigate_to_search(num_attempt)
self.navigate_to_member(mrn)
self.navigate_to_assessment()
self.add_assessment(record, map_data)
self.driver.switch_to.parent_frame() # not working
sleep(.5)
except Exception as exc:
if series_not_null:
errors = self.process_series_error(exc)
return completed, errors
def navigate_to_search(self, num_attempt):
"""Uses webdriver to navigate to Search tab and select Member Status=All"""
if num_attempt == 0:
page_change_until(self.driver, By.XPATH, './/*[text()="Search"]')
wait_ready_state(self.driver)
else:
self.driver.switch_to.parent_frame()
elem = wait_until(self.driver, By.XPATH, './/*[text()="Search"]')
is_disp_n = 0
while True:
if elem.is_displayed():
break
else:
self.driver.switch_to.parent_frame()
is_disp_n += 1
sleep(1)
if is_disp_n == 20:
raise Exception('Could not find Search tab after 20 tries.')
num_attempt += 1
radio_locator = (By.XPATH, './/*[#type="RADIO"][#value="All"]')
while True:
break_while_timer = datetime.now()
if datetime.now() - break_while_timer > timedelta(seconds=20):
break_while = True
break
try:
if wait_until(self.driver, *radio_locator).is_selected():
pass
else:
wait_until(self.driver, *radio_locator).click()
break
except Exception:
sleep(1)
def navigate_to_member(self, mrn):
"""Finds member"""
wait_until(self.driver, By.XPATH, './/*[#name="MemberIdItem_1"]').clear()
wait_until(self.driver, By.XPATH, './/*[#name="MemberIdItem_1"]').send_keys(f'{mrn}'+Keys.ENTER)
page_change_until(self.driver, By.XPATH, f'.//*[text()="{mrn}"]')
wait_ready_state(self.driver)
def navigate_to_assessment(self):
"""Navigates to the appropriate contact log"""
self.driver.find_element_by_css_selector("div[eventproxy^='memberAssessment']").click() #clicks assessment icon
element = self.driver.find_element_by_xpath(f"//div[contains(text(), '{self.assessment_type}')]")
actions = ActionChains(self.driver)
actions.move_to_element(element).perform()
self.driver.find_element_by_xpath(f"//div[contains(text(), '{self.assessment_type}')]").click()
self.driver.find_element_by_css_selector("div[eventproxy^='createSelectedAssessmentsButton']").click()
def add_assessment(self, record, map_data):
"""Create contact log"""
qna_frame = self.driver.find_element_by_css_selector("iframe[id^='iccc']")
self.driver.switch_to.frame(qna_frame)
pages = self.driver.find_element_by_css_selector("ul[class='nav nav-pills nav-stacked qna-tabs']")
pages = pages.find_elements_by_css_selector("a")
for page in pages:
page.click()
# for record in records.itertuples(): #attempt
questions = self.driver.find_elements_by_css_selector("fieldset")
questions = [question for question in questions if question.text not in ("", " ", None)]
for question in questions[1:]:
q_text = question.find_element_by_css_selector("span[class='question-text ng-binding']").text
questionType = map_data.loc[map_data['question_text'] == q_text, 'question_type'].item()
answer = map_data.loc[map_data['question_text'] == q_text, 'map'].item()
answer = getattr(record, answer)
if answer not in ("", " ", "NaT", "NaN", None):
if questionType == 'checks':
self.choose_checks(question, answer)
else:
try:
if questionType == 'text':
self.driver.implicitly_wait(0)
(question.find_element_by_css_selector("textarea").send_keys(str(answer))
if
question.find_elements_by_css_selector("textarea")
else
question.find_element_by_css_selector("input").send_keys(answer))
self.driver.implicitly_wait(15)
elif questionType == 'date':
try:
answer = answer.strftime('%m/%d/%Y')
question.find_element_by_css_selector("input").send_keys(answer)
# page.click()
except Exception as e:
raise Errors.RequiredDataError('Issues with Assessment Date -- {}'.format(e))
elif questionType == 'radio':
question.find_element_by_css_selector("input[value='{}']".format(answer)).click()
except:
continue
else:
pass
self.driver.find_element_by_css_selector("#publishButton").click()
sleep(3)
WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".btn.btn-mini.btn-primary"))).click()
process_records()
I have also tried:
self.process_records()
This whole code-block seems to be inside a class. So you should be using self.process_records() to call the function.
The process_records method expects a few positional arguments (apart from self) - you'll probably need to pass those to the function too.

python selenium log number of times page refreshes

I want to know if there is any way to log the number of times my page has refreshed in command prompt when running.
want it to tell me the number of times it has refreshed. Refresh is located between while true: and continue. thanks
driver = webdriver.Chrome(chrome_path)
driver.get(link)
while True:
size = driver.find_elements_by_xpath(".//*[#id='atg_store_picker']/div/div[2]/div[1]/div[1]/span[2]/a[4]")
if len(size) <= 0:
time.sleep(0.5)
print "PAGE NOT LIVE"
driver.refresh()
continue
else:`enter code here`
print 'LIVE!!!!'
break
the answer to my question was very simple...
driver = webdriver.Chrome(chrome_path)
driver.get(link)
count = 0
while True:
size = driver.find_elements_by_xpath(".//*[#id='atg_store_picker']/div/div[2]/div[1]/div[1]/span[2]/a[4]")
if len(size) <= 0:
count +=1
print 'Refresh Count:', count
time.sleep(2)
driver.refresh()
continue
else:
print 'LIVE!!!!'
break

Categories